xserver: Branch 'XACE-SELINUX' - 115 commits

Eamon Walsh ewalsh at kemper.freedesktop.org
Wed Oct 17 13:09:54 PDT 2007


 GL/glx/g_disptab.h                          |    2 
 GL/glx/glxcmds.c                            |  751 +++++++-------
 GL/glx/glxcmdsswap.c                        |  134 +-
 GL/glx/glxcontext.h                         |   18 
 GL/glx/glxdrawable.h                        |   35 
 GL/glx/glxdri.c                             |  542 ++++------
 GL/glx/glxext.c                             |  253 +---
 GL/glx/glxext.h                             |   38 
 GL/glx/glxglcore.c                          |    5 
 GL/glx/glxscreens.c                         |  140 --
 GL/glx/glxscreens.h                         |   29 
 GL/glx/glxserver.h                          |    5 
 GL/glx/glxutil.c                            |   11 
 GL/glx/glxutil.h                            |    2 
 GL/glx/glxvisuals.c                         |    8 
 GL/glx/indirect_dispatch.h                  |   22 
 GL/glx/indirect_size_get.c                  |    4 
 GL/glx/indirect_table.c                     |    6 
 Xext/shm.c                                  |   98 +
 configure.ac                                |   22 
 dix/events.c                                |   55 +
 dix/extension.c                             |    2 
 exa/exa.c                                   |  218 ++--
 exa/exa.h                                   |   19 
 exa/exa_accel.c                             |   81 -
 exa/exa_migration.c                         |    3 
 exa/exa_priv.h                              |    4 
 fb/fbarc.c                                  |   37 
 fb/fbcmap_mi.c                              |    8 
 hw/kdrive/ephyr/GL/internal/dri_interface.h |  517 +++++++++
 hw/kdrive/ephyr/Makefile.am                 |   47 
 hw/kdrive/ephyr/XF86dri.c                   |  622 ++++++++++++
 hw/kdrive/ephyr/ephyr.c                     |  229 +++-
 hw/kdrive/ephyr/ephyr.h                     |    6 
 hw/kdrive/ephyr/ephyrdri.c                  |  291 +++++
 hw/kdrive/ephyr/ephyrdri.h                  |   75 +
 hw/kdrive/ephyr/ephyrdriext.c               | 1448 ++++++++++++++++++++++++++++
 hw/kdrive/ephyr/ephyrdriext.h               |   32 
 hw/kdrive/ephyr/ephyrglxext.c               |  722 +++++++++++++
 hw/kdrive/ephyr/ephyrglxext.h               |   35 
 hw/kdrive/ephyr/ephyrhostglx.c              |  687 +++++++++++++
 hw/kdrive/ephyr/ephyrhostglx.h              |   76 +
 hw/kdrive/ephyr/ephyrhostproxy.c            |   94 +
 hw/kdrive/ephyr/ephyrhostproxy.h            |   51 
 hw/kdrive/ephyr/ephyrhostvideo.c            | 1004 +++++++++++++++++++
 hw/kdrive/ephyr/ephyrhostvideo.h            |  238 ++++
 hw/kdrive/ephyr/ephyrinit.c                 |  110 +-
 hw/kdrive/ephyr/ephyrlog.h                  |   67 +
 hw/kdrive/ephyr/ephyrproxyext.c             |  119 ++
 hw/kdrive/ephyr/ephyrproxyext.h             |   34 
 hw/kdrive/ephyr/ephyrvideo.c                | 1278 ++++++++++++++++++++++++
 hw/kdrive/ephyr/hostx.c                     | 1055 +++++++++++++++-----
 hw/kdrive/ephyr/hostx.h                     |  122 ++
 hw/kdrive/ephyr/os.c                        |   10 
 hw/kdrive/fbdev/Makefile.am                 |    2 
 hw/kdrive/src/Makefile.am                   |    2 
 hw/xfree86/common/xf86AutoConfig.c          |  231 ++++
 hw/xfree86/common/xf86Config.c              |   38 
 hw/xfree86/common/xf86Config.h              |    5 
 hw/xfree86/common/xf86Events.c              |    4 
 hw/xfree86/common/xf86Globals.c             |    2 
 hw/xfree86/common/xf86Helper.c              |    2 
 hw/xfree86/common/xf86Init.c                |   10 
 hw/xfree86/common/xf86Privstr.h             |    2 
 hw/xfree86/common/xf86str.h                 |    1 
 hw/xfree86/dri/dri.c                        |    4 
 hw/xfree86/modes/xf86Crtc.c                 |   61 -
 hw/xfree86/modes/xf86Crtc.h                 |    3 
 hw/xfree86/modes/xf86EdidModes.c            |  207 +++-
 hw/xfree86/modes/xf86Modes.c                |   11 
 hw/xfree86/modes/xf86Modes.h                |    3 
 hw/xfree86/os-support/assyntax.h            |    2 
 hw/xfree86/os-support/bus/Pci.h             |    2 
 hw/xfree86/os-support/bus/ix86Pci.c         |   20 
 hw/xfree86/os-support/shared/stdResource.c  |    2 
 hw/xfree86/os-support/solaris/sun_bios.c    |    4 
 hw/xfree86/os-support/solaris/sun_init.c    |   12 
 hw/xfree86/os-support/solaris/sun_vid.c     |   14 
 hw/xfree86/os-support/sysv/sysv_video.c     |    4 
 hw/xfree86/os-support/xf86_OSlib.h          |   12 
 hw/xfree86/parser/Configint.h               |    4 
 hw/xfree86/parser/Device.c                  |   20 
 hw/xfree86/parser/Screen.c                  |   24 
 hw/xfree86/parser/read.c                    |    2 
 hw/xfree86/utils/xorgcfg/Makefile.am        |    2 
 hw/xfree86/utils/xorgconfig/xorgconfig.c    |    2 
 hw/xfree86/xf4bpp/vgaSolid.c                |    6 
 include/dix-config.h.in                     |    8 
 include/dix.h                               |    3 
 include/os.h                                |   18 
 include/servermd.h                          |    9 
 mi/micoord.h                                |    3 
 mi/mipointer.c                              |    1 
 os/access.c                                 |  168 +--
 os/connection.c                             |   65 -
 os/io.c                                     |    2 
 os/utils.c                                  |    1 
 os/xalloc.c                                 |    2 
 xorg-server.pc.in                           |    2 
 99 files changed, 10620 insertions(+), 1903 deletions(-)

New commits:
commit 50b27e1ad2a98d36728dc8157492ef5c59c132cd
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Wed Oct 17 16:09:40 2007 -0400

    devPrivates rework: update new GL/glxext code.
    
    Need to merge so this type of thing stops happening.

diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index 4d6bfd7..55463c7 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -27,6 +27,7 @@
 #include "glxserver.h"
 #include <windowstr.h>
 #include <propertyst.h>
+#include "privates.h"
 #include <os.h>
 #include "g_disptab.h"
 #include "unpack.h"
@@ -53,7 +54,7 @@ RESTYPE __glXSwapBarrierRes;
 */
 xGLXSingleReply __glXReply;
 
-static int glxClientPrivateIndex;
+static DevPrivateKey glxClientPrivateKey = &glxClientPrivateKey;
 
 /*
 ** Client that called into GLX dispatch.
@@ -218,7 +219,7 @@ int __glXError(int error)
 __GLXclientState *
 glxGetClient(ClientPtr pClient)
 {
-    return (__GLXclientState *) pClient->devPrivates[glxClientPrivateIndex].ptr;
+    return dixLookupPrivate(&pClient->devPrivates, glxClientPrivateKey);
 }
 
 static void
@@ -288,9 +289,7 @@ void GlxExtensionInit(void)
     __glXDrawableRes = CreateNewResourceType((DeleteType)DrawableGone);
     __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
 
-    glxClientPrivateIndex = AllocateClientPrivateIndex ();
-    if (!AllocateClientPrivate (glxClientPrivateIndex,
-				sizeof (__GLXclientState)))
+    if (!dixRequestPrivate(glxClientPrivateKey, sizeof (__GLXclientState)))
 	return;
     if (!AddCallback (&ClientStateCallback, glxClientCallback, 0))
 	return;
diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index c6f060b..6e4d497 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -41,11 +41,12 @@
 #include <windowstr.h>
 #include <os.h>
 
+#include "privates.h"
 #include "glxserver.h"
 #include "glxutil.h"
 #include "glxext.h"
 
-static int glxScreenPrivateIndex;
+static DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKey;
 
 const char GLServerVersion[] = "1.4";
 static const char GLServerExtensions[] = 
@@ -278,22 +279,11 @@ glxCloseScreen (int index, ScreenPtr pScreen)
 __GLXscreen *
 glxGetScreen(ScreenPtr pScreen)
 {
-    return (__GLXscreen *) pScreen->devPrivates[glxScreenPrivateIndex].ptr;
+    return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey);
 }
 
 void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
 {
-    static int glxGeneration;
-
-    if (glxGeneration != serverGeneration)
-    {
-	glxScreenPrivateIndex = AllocateScreenPrivateIndex ();
-	if (glxScreenPrivateIndex == -1)
-	    return;
-
-	glxGeneration = serverGeneration;
-    }
-
     glxScreen->pScreen       = pScreen;
     glxScreen->GLextensions  = xstrdup(GLServerExtensions);
     glxScreen->GLXvendor     = xstrdup(GLXServerVendorName);
@@ -308,9 +298,9 @@ void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
 
     __glXScreenInitVisuals(glxScreen);
 
-    pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) glxScreen;
+    dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, glxScreen);
 }
- 
+
 void __glXScreenDestroy(__GLXscreen *screen)
 {
     xfree(screen->GLXvendor);
commit c3f7b862550fa8f46633162f83db8c27e46fc672
Merge: af4dde0... feac075...
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Wed Oct 17 15:00:54 2007 -0400

    Merge branch 'master' into XACE-SELINUX
    
    Conflicts:
    
    	os/access.c

diff --cc exa/exa.c
index 56996c4,7ad226f..3f724e6
--- a/exa/exa.c
+++ b/exa/exa.c
@@@ -829,10 -883,10 +876,9 @@@ exaDriverInit (ScreenPtr		pScreen
      /*
       * Hookup offscreen pixmaps
       */
-     if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
- 	pExaScr->info->offScreenBase < pExaScr->info->memorySize)
+     if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)
      {
 -	if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex,
 -				   sizeof (ExaPixmapPrivRec))) {
 +	if (!dixRequestPrivate(exaPixmapPrivateKey, sizeof(ExaPixmapPrivRec))) {
              LogMessage(X_WARNING,
  		       "EXA(%d): Failed to allocate pixmap private\n",
  		       pScreen->myNum);
@@@ -846,21 -900,33 +892,29 @@@
  
  	pExaScr->SavedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
  	pScreen->ModifyPixmapHeader = exaModifyPixmapHeader;
- 	LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %d bytes\n",
- 		   pScreen->myNum,
- 		   pExaScr->info->memorySize - pExaScr->info->offScreenBase);
+ 	if (!pExaScr->info->CreatePixmap) {
+ 	    LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
+ 		       pScreen->myNum,
+ 		       pExaScr->info->memorySize - pExaScr->info->offScreenBase);
+ 	} else {
+ 	    LogMessage(X_INFO, "EXA(%d): Driver allocated offscreen pixmaps\n",
+ 		       pScreen->myNum);
+ 
+ 	}
      }
      else
 -    {
          LogMessage(X_INFO, "EXA(%d): No offscreen pixmaps\n", pScreen->myNum);
 -	if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex, 0))
 -	    return FALSE;
 -    }
  
-     DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
-                 pExaScr->info->memorySize));
-     if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
- 	if (!exaOffscreenInit (pScreen)) {
-             LogMessage(X_WARNING, "EXA(%d): Offscreen pixmap setup failed\n",
-                        pScreen->myNum);
-             return FALSE;
-         }
+     if (!pExaScr->info->CreatePixmap) {
+ 	DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
+ 		    pExaScr->info->memorySize));
+ 	if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
+ 	    if (!exaOffscreenInit (pScreen)) {
+ 		LogMessage(X_WARNING, "EXA(%d): Offscreen pixmap setup failed\n",
+ 			   pScreen->myNum);
+ 		return FALSE;
+ 	    }
+ 	}
      }
  
      LogMessage(X_INFO, "EXA(%d): Driver registered support for the following"
diff --cc os/access.c
index 33b2eb6,b0f63ed..e91dd37
--- a/os/access.c
+++ b/os/access.c
@@@ -1493,20 -1510,28 +1510,31 @@@ GetLocalClientCreds(ClientPtr client, L
  #endif
  }
  
+ void
+ FreeLocalClientCreds(LocalClientCredRec *lcc)
+ {
+     if (lcc != NULL) {
+ 	if (lcc->nSuppGids > 0) {
+ 	    Xfree(lcc->pSuppGids);
+ 	}
+ 	Xfree(lcc);
+     }
+ }
+ 
 -static Bool
 +static int
  AuthorizedClient(ClientPtr client)
  {
 +    int rc;
 +
      if (!client || defeatAccessControl)
 -	return TRUE;
 +	return Success;
  
      /* untrusted clients can't change host access */
 -    if (!XaceHook(XACE_HOSTLIST_ACCESS, client, DixWriteAccess))
 -	return FALSE;
 +    rc = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess);
 +    if (rc != Success)
 +	return rc;
  
 -    return LocalClient(client);
 +    return LocalClient(client) ? Success : BadAccess;
  }
  
  /* Add a host to the access control list.  This is the external interface
commit feac0759522cbdc3e61ccfa373df735903c5cb27
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Wed Oct 17 11:42:28 2007 +0800

    Make config file preferred mode override monitor preferred mode.
    
    Add a new even-more-preferred bit to each mode which is used to make config
    file preferences selected instead of the monitor preferred mode.

diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 0365ddd..af98b4f 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -142,6 +142,7 @@ typedef enum {
 # define M_T_DEFAULT 0x10	/* (VESA) default modes */
 # define M_T_USERDEF 0x20	/* One of the modes from the config file */
 # define M_T_DRIVER  0x40	/* Supplied by the driver (EDID, etc) */
+# define M_T_USERPREF 0x80	/* mode preferred by the user config */
 
 /* Video mode */
 typedef struct _DisplayModeRec {
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index f589b5a..0a48d5b 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -711,7 +711,8 @@ xf86DefaultMode (xf86OutputPtr output, int width, int height)
     for (mode = output->probed_modes; mode; mode = mode->next)
     {
 	int	    dpi;
-	int	    preferred = (mode->type & M_T_PREFERRED) != 0;
+	int	    preferred = (((mode->type & M_T_PREFERRED) != 0) +
+				 ((mode->type & M_T_USERPREF) != 0));
 	int	    diff;
 
 	if (xf86ModeWidth (mode, output->initial_rotation) > width ||
@@ -1415,7 +1416,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 			mode->prev = NULL;
 			output->probed_modes = mode;
 		    }
-		    mode->type |= M_T_PREFERRED;
+		    mode->type |= (M_T_PREFERRED|M_T_USERPREF);
 		}
 		else
 		    mode->type &= ~M_T_PREFERRED;
@@ -1532,6 +1533,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int			o, c;
     DisplayModePtr	target_mode = NULL;
+    int			target_preferred = 0;
     Rotation		target_rotation = RR_Rotate_0;
     xf86CrtcPtr		*crtcs;
     DisplayModePtr	*modes;
@@ -1572,43 +1574,34 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
     }
     
     /*
-     * Let outputs with preferred modes drive screen size
+     * User preferred > preferred > other modes
      */
     for (o = 0; o < config->num_output; o++)
     {
-	xf86OutputPtr output = config->output[o];
+	xf86OutputPtr	output = config->output[o];
+	DisplayModePtr	default_mode;
+	int		default_preferred;
 
-	if (enabled[o] &&
-	    xf86OutputHasPreferredMode (output, width, height))
+	if (!enabled[o])
+	    continue;
+	default_mode = xf86DefaultMode (output, width, height);
+	if (!default_mode)
+	    continue;
+	default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) +
+			     ((default_mode->type & M_T_USERPREF) != 0));
+	if (default_preferred > target_preferred || !target_mode)
 	{
-	    target_mode = xf86DefaultMode (output, width, height);
+	    target_mode = default_mode;
+	    target_preferred = default_preferred;
 	    target_rotation = output->initial_rotation;
-	    if (target_mode)
-	    {
-		modes[o] = target_mode;
-		config->compat_output = o;
-		break;
-	    }
-	}
-    }
-    if (!target_mode)
-    {
-	for (o = 0; o < config->num_output; o++)
-	{
-	    xf86OutputPtr output = config->output[o];
-	    if (enabled[o])
-	    {
-		target_mode = xf86DefaultMode (output, width, height);
-		target_rotation = output->initial_rotation;
-		if (target_mode)
-		{
-		    modes[o] = target_mode;
-		    config->compat_output = o;
-		    break;
-		}
-	    }
+	    config->compat_output = o;
 	}
     }
+    if (target_mode)
+	modes[config->compat_output] = target_mode;
+    /*
+     * Fill in other output modes
+     */
     for (o = 0; o < config->num_output; o++)
     {
 	xf86OutputPtr output = config->output[o];
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 9693e12..4c843cd 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -39,6 +39,9 @@
 #ifndef M_T_DRIVER
 #define M_T_DRIVER	0x40
 #endif
+#ifndef M_T_USERPREF
+#define M_T_USERPREF	0x80
+#endif
 #ifndef HARDWARE_CURSOR_ARGB
 #define HARDWARE_CURSOR_ARGB				0x00004000
 #endif
commit f2da10f7bc2ddb6ad2f18b793afc10d04b97c51c
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Wed Oct 17 10:50:22 2007 +0800

    KDRIVE_LOCAL_LIBS includes some system libraries, not just internal x server libs

diff --git a/configure.ac b/configure.ac
index 59dcde7..fb88773 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1872,7 +1872,7 @@ if test "$KDRIVE" = yes; then
     
     KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS $XV_CFLAGS"
 
-    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $XV_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB"
+    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB"
     KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a'
     case $host_os in
 	*linux*)
@@ -1884,7 +1884,7 @@ if test "$KDRIVE" = yes; then
     KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB"
     KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
     KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB"
-    KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS"
+    KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS $XV_LIBS"
 
     # check if we can build Xephyr
     PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"])
diff --git a/hw/kdrive/fbdev/Makefile.am b/hw/kdrive/fbdev/Makefile.am
index 1ce4833..420855b 100644
--- a/hw/kdrive/fbdev/Makefile.am
+++ b/hw/kdrive/fbdev/Makefile.am
@@ -20,7 +20,7 @@ Xfbdev_LDADD = 						\
 
 Xfbdev_DEPENDENCIES =	\
 	libfbdev.a					\
-	@KDRIVE_LOCAL_LIBS@
+	$(KDRIVE_PURE_LIBS)
 
 relink:
 	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
commit 9dde53ed179336c7b483c9a94a97182ad1777dfb
Author: Alan Hourihane <alanh at tungstengraphics.com>
Date:   Tue Oct 16 19:55:56 2007 +0100

    Fix walking of GLX providers.

diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index 94ec5cc..4d6bfd7 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -317,11 +317,12 @@ void GlxExtensionInit(void)
 	pScreen = screenInfo.screens[i];
 
 	for (p = __glXProviderStack; p != NULL; p = p->next) {
-	    if (p->screenProbe(pScreen) != NULL)
+	    if (p->screenProbe(pScreen) != NULL) {
 		LogMessage(X_INFO,
 			   "GLX: Initialized %s GL provider for screen %d\n",
 			   p->name, i);
-	    break;
+	    	break;
+	    }
 	}
     }
 }
commit 70a5d33c9e41c077a8cd92abd43376e2956d3aed
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Oct 16 12:46:07 2007 +0200

    Always check the return value of __glXGetDrawable first.
    
    Fixes spurious GLX protocol errors because __glXGetDrawable doesn't set the
    error code in case of success. Maybe it should, though.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 7fd1f4d..f6e0321 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -1617,7 +1617,7 @@ int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 	return error;
 
     pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
-    if (error != Success || pGlxDraw->type != GLX_DRAWABLE_PIXMAP) {
+    if (!pGlxDraw || pGlxDraw->type != GLX_DRAWABLE_PIXMAP) {
 	client->errorValue = drawId;
 	return error;
     }
@@ -1675,7 +1675,7 @@ int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
     }
 
     pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
-    if (error != Success)
+    if (!pGlxDraw)
 	return error;
 
     if (pGlxDraw == NULL ||
commit 8b5078b7d9ec08a588a78eb49096b698c6f4916b
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Mon Oct 15 13:10:10 2007 -0400

    Fix byte swapping for GetFBConfigs.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index a6bd2df..7fd1f4d 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -1019,7 +1019,7 @@ __glXCreateARGBConfig(__GLXscreen *screen)
  */
 
 static int
-DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
+DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
 {
     ClientPtr client = cl->client;
     xGLXGetFBConfigsReply reply;
@@ -1049,7 +1049,7 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
     reply.type = X_Reply;
     reply.sequenceNumber = client->sequence;
 
-    if ( do_swap ) {
+    if (client->swapped) {
 	__GLX_SWAP_SHORT(&reply.sequenceNumber);
 	__GLX_SWAP_INT(&reply.length);
 	__GLX_SWAP_INT(&reply.numFBConfigs);
@@ -1104,7 +1104,7 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
 	WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex );
 	WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod );
 
-	if ( do_swap ) {
+	if (client->swapped) {
 	    __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
 	}
 	WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH,
@@ -1117,13 +1117,13 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
 int __glXDisp_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
-    return DoGetFBConfigs( cl, req->screen, GL_FALSE );
+    return DoGetFBConfigs(cl, req->screen);
 }
 
 int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
-    return DoGetFBConfigs( cl, req->screen, GL_FALSE );
+    return DoGetFBConfigs(cl, req->screen);
 }
 
 static int 
commit c922d2eebe29f08f463ee76293dc9042712fb21c
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Sun Oct 14 20:40:18 2007 +0300

    glx: drop duplicate GetDrawableAttributesSGIX declarations.
    
    They are officially autogenerated in indirect_dispatch.h now.

diff --git a/GL/glx/g_disptab.h b/GL/glx/g_disptab.h
index f9a09cc..946e86b 100644
--- a/GL/glx/g_disptab.h
+++ b/GL/glx/g_disptab.h
@@ -34,7 +34,6 @@
 ** version 1.2.1 Specification.
 */
 
-extern int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc);
 extern int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc);
 extern int __glXDisp_QueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc);
 extern int __glXDisp_QueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc);
@@ -42,7 +41,6 @@ extern int __glXDisp_DestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *p
 extern int __glXDisp_QueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc);
 extern int __glXDisp_HyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc);
 
-extern int __glXDispSwap_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc);
 extern int __glXDispSwap_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc);
 extern int __glXDispSwap_QueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc);
 extern int __glXDispSwap_QueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc);
commit 3d4eb17b38dcb1468493f3686dc5ea3623ef9a73
Author: Ben Byer <bbyer at bbyer.local>
Date:   Sun Oct 14 18:07:03 2007 -0700

    mass change from #ifdef i386 to #ifdef __i386__ to conform to ANSI

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 9c54bf4..96fadc9 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -77,7 +77,7 @@ extern DeviceAssocRec mouse_assoc;
 #include "picture.h"
 #endif
 
-#if (defined(i386) || defined(__i386__)) && \
+#if (defined(__i386__)) && \
     (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
      defined(__NetBSD__) || defined(linux) || \
      (defined(SVR4) && !defined(sun)) || defined(__GNU__))
@@ -877,7 +877,7 @@ static OptionInfoRec FlagOptions[] = {
 	{0}, FALSE },
 };
 
-#if defined(i386) || defined(__i386__)
+#ifdef __i386__
 static Bool
 detectPC98(void)
 {
@@ -1164,7 +1164,7 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
 	xf86Info.pixmap24 = Pix24DontCare;
 	xf86Info.pix24From = X_DEFAULT;
     }
-#if defined(i386) || defined(__i386__)
+#ifdef __i386__
     if (xf86GetOptValBool(FlagOptions, FLAG_PC98, &value)) {
 	xf86Info.pc98 = value;
 	if (value) {
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 91964c9..785815c 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -317,7 +317,7 @@ xf86ProcessActionEvent(ActionEvent action, void *arg)
 	}
 	break;
 #if !defined(__SOL8__) && !defined(sgi) && \
-    (!defined(sun) || defined(i386)) && defined(VT_ACTIVATE)
+    (!defined(sun) || defined(__i386__)) && defined(VT_ACTIVATE)
     case ACTION_SWITCHSCREEN:
 	if (VTSwitchEnabled && !xf86Info.dontVTSwitch && arg) {
 	    int vtno = *((int *) arg);
@@ -340,7 +340,7 @@ xf86ProcessActionEvent(ActionEvent action, void *arg)
 #else
 	    if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno + 1) < 0)
 #endif
-#if defined (__SCO__) || (defined(sun) && defined (i386) && defined (SVR4)) || defined(__UNIXWARE__)
+#if defined (__SCO__) || (defined(sun) && defined (__i386__) && defined (SVR4)) || defined(__UNIXWARE__)
 		if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 0) < 0)
 #else
 		if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 1) < 0)
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index 7dc45b7..b3969b1 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -124,7 +124,7 @@ xf86InfoRec xf86Info = {
 	PCIOsConfig,	/* pciFlags */
 	Pix24DontCare,	/* pixmap24 */
 	X_DEFAULT,	/* pix24From */
-#if defined(i386) || defined(__i386__)
+#ifdef __i386__
 	FALSE,		/* pc98 */
 #endif
 	TRUE,		/* pmFlag */
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index b6fc6b6..1ef7973 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -2341,7 +2341,7 @@ xf86GetAllowMouseOpenFail()
 _X_EXPORT Bool
 xf86IsPc98()
 {
-#if defined(i386) || defined(__i386__)
+#ifdef __i386__
     return xf86Info.pc98;
 #else
     return FALSE;
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index 09ebb07..75d4974 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -109,7 +109,7 @@ typedef struct {
     PciProbeType	pciFlags;
     Pix24Flags		pixmap24;
     MessageType		pix24From;
-#if defined(i386) || defined(__i386__)
+#ifdef __i386__
     Bool		pc98;
 #endif
     Bool		pmFlag;
diff --git a/hw/xfree86/os-support/assyntax.h b/hw/xfree86/os-support/assyntax.h
index 718312c..d3e96e5 100644
--- a/hw/xfree86/os-support/assyntax.h
+++ b/hw/xfree86/os-support/assyntax.h
@@ -91,7 +91,7 @@
 #define GNU_ASSEMBLER
 #endif
 
-#if (defined(__STDC__) && !defined(UNIXCPP)) || (defined (sun) && defined (i386) && defined (SVR4) && defined (__STDC__) && !defined (__GNUC__)) 
+#if (defined(__STDC__) && !defined(UNIXCPP)) || (defined (sun) && defined (__i386__) && defined (SVR4) && defined (__STDC__) && !defined (__GNUC__)) 
 #define	CONCAT(x, y)	x ## y
 #else
 #define	CONCAT(x, y)	x/**/y
diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h
index bb93260..6bd0eb7 100644
--- a/hw/xfree86/os-support/bus/Pci.h
+++ b/hw/xfree86/os-support/bus/Pci.h
@@ -210,7 +210,7 @@
 #  define ARCH_PCI_INIT ia64linuxPciInit
 # endif
 # define XF86SCANPCI_WRAPPER ia64ScanPCIWrapper
-#elif defined(__i386__) || defined(i386)
+#elif defined(__i386__)
 # if defined(linux)
 #  define ARCH_PCI_INIT linuxPciInit
 # else
diff --git a/hw/xfree86/os-support/solaris/sun_bios.c b/hw/xfree86/os-support/solaris/sun_bios.c
index 6a132f5..1223dcd 100644
--- a/hw/xfree86/os-support/solaris/sun_bios.c
+++ b/hw/xfree86/os-support/solaris/sun_bios.c
@@ -26,7 +26,7 @@
 #include <xorg-config.h>
 #endif
 
-#ifdef i386
+#ifdef __i386__
 #define _NEED_SYSI86
 #endif
 #include "xf86.h"
@@ -66,7 +66,7 @@ xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
 	Offset += Base & (psize - 1);
 	Base &= ~(psize - 1);
 	mlen = (Offset + Len + psize - 1) & ~(psize - 1);
-#if defined(i386) && !defined(__SOL8__)
+#if defined(__i386__) && !defined(__SOL8__)
 	if (Base >= 0xA0000 && Base + mlen < 0xFFFFF && xf86Info.vtno >= 0)
 		sprintf(solx86_vtname, "/dev/vt%02d", xf86Info.vtno);
 	else
diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c
index 08d35c5..c7fac52 100644
--- a/hw/xfree86/os-support/solaris/sun_init.c
+++ b/hw/xfree86/os-support/solaris/sun_init.c
@@ -29,7 +29,7 @@
 #include "xf86.h"
 #include "xf86Priv.h"
 #include "xf86_OSlib.h"
-#if defined(__i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
 # include <sys/kd.h>
 #endif
 
@@ -40,7 +40,7 @@ static int VTnum = -1;
 static int xf86StartVT = -1;
 #endif
 
-#if defined(__SOL8__) || !defined(__i386)
+#if defined(__SOL8__) || !defined(__i386__)
 static char fb_dev[PATH_MAX] = "/dev/fb";
 #else
 static char fb_dev[PATH_MAX] = "/dev/console";
@@ -209,11 +209,11 @@ xf86CloseConsole(void)
 #ifdef HAS_USL_VTS
     struct vt_mode VT;
 #endif
-#if defined(__SOL8__) || !defined(i386)
+#if defined(__SOL8__) || !defined(__i386__)
     int tmp;
 #endif
 
-#if !defined(i386) && !defined(__x86)
+#if !defined(__i386__) && !defined(__x86)
 
     if (!xf86DoProbe && !xf86DoConfigure) {
 	int fd;
@@ -332,7 +332,7 @@ xf86ProcessArgument(int argc, char **argv, int i)
 
 #endif /* HAS_USL_VTS */
 
-#if defined(__SOL8__) || !defined(i386)
+#if defined(__SOL8__) || !defined(__i386__)
 
     if ((i + 1) < argc) {
 	if (!strcmp(argv[i], "-dev")) {
@@ -352,7 +352,7 @@ void xf86UseMsg()
 #ifdef HAS_USL_VTS
     ErrorF("vtXX                   Use the specified VT number\n");
 #endif
-#if defined(__SOL8__) || !defined(i386)
+#if defined(__SOL8__) || !defined(__i386__)
     ErrorF("-dev <fb>              Framebuffer device\n");
 #endif
     ErrorF("-keeptty               Don't detach controlling tty\n");
diff --git a/hw/xfree86/os-support/solaris/sun_vid.c b/hw/xfree86/os-support/solaris/sun_vid.c
index 4f2ab87..494b2cf 100644
--- a/hw/xfree86/os-support/solaris/sun_vid.c
+++ b/hw/xfree86/os-support/solaris/sun_vid.c
@@ -28,7 +28,7 @@
 
 #include <sys/types.h> /* get __x86 definition if not set by compiler */
 
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
 #define _NEED_SYSI86
 #endif
 #include "xf86.h"
@@ -108,7 +108,7 @@ xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
 	 * TSI - 2001.09 - SPARC changes
 	 */
 
-#if defined(i386) && !defined(__SOL8__)
+#if defined(__i386__) && !defined(__SOL8__)
 	if(Base < 0xFFFFF)
 		sprintf(vtname, "/dev/vt%02d", xf86Info.vtno);
 	else
@@ -148,14 +148,14 @@ xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
 /* I/O Permissions section						   */
 /***************************************************************************/
 
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
 static Bool ExtendedEnabled = FALSE;
 #endif
 
 _X_EXPORT Bool
 xf86EnableIO(void)
 {
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
 	if (ExtendedEnabled)
 		return TRUE;
 
@@ -171,7 +171,7 @@ xf86EnableIO(void)
 _X_EXPORT void
 xf86DisableIO(void)
 {
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
 	if(!ExtendedEnabled)
 		return;
 
@@ -188,7 +188,7 @@ xf86DisableIO(void)
 
 _X_EXPORT Bool xf86DisableInterrupts(void)
 {
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
 	if (!ExtendedEnabled && (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0))
 		return FALSE;
 
@@ -207,7 +207,7 @@ _X_EXPORT Bool xf86DisableInterrupts(void)
 
 _X_EXPORT void xf86EnableInterrupts(void)
 {
-#if defined(i386) || defined(__x86)
+#if defined(__i386__) || defined(__x86)
 	if (!ExtendedEnabled && (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0))
 		return;
 
diff --git a/hw/xfree86/os-support/sysv/sysv_video.c b/hw/xfree86/os-support/sysv/sysv_video.c
index 5811947..9972bca 100644
--- a/hw/xfree86/os-support/sysv/sysv_video.c
+++ b/hw/xfree86/os-support/sysv/sysv_video.c
@@ -234,7 +234,7 @@ unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
 	return;
 }
 
-#if defined(SVR4) && defined(i386) && !defined(sun)
+#if defined(SVR4) && defined(__i386__) && !defined(sun)
 /*
  * For some SVR4 versions, a 32-bit read is done for the first location
  * in each page when the page is first mapped.  If this is done while
@@ -270,7 +270,7 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
 	pVidMem->linearSupported = linearVidMem();
 	pVidMem->mapMem = mapVidMem;
 	pVidMem->unmapMem = unmapVidMem;
-#if defined(SVR4) && defined(i386) && !defined(sun)
+#if defined(SVR4) && defined(__i386__) && !defined(sun)
 	pVidMem->readSideEffects = readSideEffects;
 #endif
 	pVidMem->initialised = TRUE;
diff --git a/hw/xfree86/os-support/xf86_OSlib.h b/hw/xfree86/os-support/xf86_OSlib.h
index fcc79be..662dbaa 100644
--- a/hw/xfree86/os-support/xf86_OSlib.h
+++ b/hw/xfree86/os-support/xf86_OSlib.h
@@ -100,7 +100,7 @@ typedef signed long xf86ssize_t;
 /**************************************************************************/
 #if (defined(SYSV) || defined(SVR4)) && \
     !defined(DGUX) && !defined(sgi) && \
-    (defined(sun) || defined(i386))
+    (defined(sun) || defined(__i386__))
 # ifdef SCO325
 #  ifndef _SVID3
 #   define _SVID3
@@ -140,7 +140,7 @@ typedef signed long xf86ssize_t;
 #  endif /* SVR4 && !sun */
 /* V86SC_IOPL was moved to <sys/sysi86.h> on Solaris 7 and later */
 #  if defined(sun) && defined (SVR4)		/* Solaris? */
-#   if defined(i386) || defined(__x86)		/* on x86 or x64? */
+#   if defined(__i386__) || defined(__x86)		/* on x86 or x64? */
 #    if !defined(V86SC_IOPL)			/* Solaris 7 or later? */
 #     include <sys/v86.h>			/* Nope */
 #    endif
@@ -148,7 +148,7 @@ typedef signed long xf86ssize_t;
 #  else 
 #   include <sys/v86.h>					/* Not solaris */
 #  endif /* sun && i386 && SVR4 */
-#  if defined(sun) && (defined (i386) || defined(__x86))  && defined (SVR4)
+#  if defined(sun) && (defined (__i386__) || defined(__x86))  && defined (SVR4)
 #    include <sys/psw.h>
 #  endif
 # endif /* _NEED_SYSI86 */
@@ -224,15 +224,11 @@ typedef signed long xf86ssize_t;
 #  define POSIX_TTY
 # endif
 
-# if defined(sun) && defined (i386) && defined (SVR4) && !defined(__SOL8__)
+# if defined(sun) && defined (__i386__) && defined (SVR4) && !defined(__SOL8__)
 #  define USE_VT_SYSREQ
 #  define VT_SYSREQ_DEFAULT TRUE
 # endif
 
-# if defined(ATT) && !defined(i386)
-#  define i386 /* not defined in ANSI C mode */
-# endif /* ATT && !i386 */
-
 # ifdef SYSV
 #  if !defined(ISC) || defined(ISC202) || defined(ISC22)
 #   define NEED_STRERROR
diff --git a/hw/xfree86/utils/xorgconfig/xorgconfig.c b/hw/xfree86/utils/xorgconfig/xorgconfig.c
index 8d9c03f..f50b4e2 100644
--- a/hw/xfree86/utils/xorgconfig/xorgconfig.c
+++ b/hw/xfree86/utils/xorgconfig/xorgconfig.c
@@ -631,7 +631,7 @@ mouse_configuration(void) {
 		config_emulate3buttons = 0;
 	printf("\n");
 
-#if (defined(sun) && (defined(__i386) || defined(__x86)))
+#if (defined(sun) && (defined(__i386__) || defined(__x86)))
 	/* SPARC & USB mice (VUID or AUTO protocols) default to /dev/mouse, 
 	   but PS/2 mice default to /dev/kdmouse */
 	if ((config_mousetype != M_AUTO) && (config_mousetype != M_VUID)) {
diff --git a/hw/xfree86/xf4bpp/vgaSolid.c b/hw/xfree86/xf4bpp/vgaSolid.c
index 501bd3d..0ef18cf 100644
--- a/hw/xfree86/xf4bpp/vgaSolid.c
+++ b/hw/xfree86/xf4bpp/vgaSolid.c
@@ -54,7 +54,7 @@ static void fastFill
 {
 int stop_count = bytewidth ;
 register int row_jump = bytes_per_line - bytewidth ;
-#if !defined(OLDHC) && defined(BSDrt) && !defined(i386)
+#if !defined(OLDHC) && defined(BSDrt) && !defined(__i386__)
 register const unsigned int notZero = ((unsigned char)(~0x0));
 #else
 #define notZero ((unsigned char)(~0))
@@ -112,7 +112,7 @@ static void fastFillRMW
 {
 int stop_count = bytewidth ;
 register int row_jump = bytes_per_line - bytewidth ;
-#if !defined(OLDHC) && defined(BSDrt) && !defined(i386)
+#if !defined(OLDHC) && defined(BSDrt) && !defined(__i386__)
 register const unsigned int notZero = ((unsigned char)(~0x0));
 #endif
 register int tmp ;
@@ -369,7 +369,7 @@ register unsigned int height ;		/* MUST BE > 0 !! */
 {
 int stop_count = wordwidth ;
 register int row_jump = bytes_per_line - wordwidth*2 ;
-#if !defined(OLDHC) && defined(BSDrt) && !defined(i386) && 0
+#if !defined(OLDHC) && defined(BSDrt) && !defined(__i386__) && 0
 register const int notZero = ~0x0 ;
 #else
 #define notZero ( ~0 )
diff --git a/include/servermd.h b/include/servermd.h
index 74b90b3..2616bfe 100644
--- a/include/servermd.h
+++ b/include/servermd.h
@@ -260,7 +260,7 @@ SOFTWARE.
 
 #if defined(ibm032) || defined (ibm)
 
-#ifdef i386
+#ifdef __i386__
 # define IMAGE_BYTE_ORDER	LSBFirst	/* Value for PS/2 only */
 #else
 # define IMAGE_BYTE_ORDER	MSBFirst        /* Values for the RT only*/
@@ -270,7 +270,7 @@ SOFTWARE.
 #define GETLEFTBITS_ALIGNMENT	4
 /* ibm pcc doesn't understand pragmas. */
 
-#ifdef i386
+#ifdef __i386__
 #define BITMAP_SCANLINE_UNIT	8
 #endif
 
@@ -444,10 +444,9 @@ SOFTWARE.
 
 #endif /* luna */
 
-#if	(defined(SVR4) && defined(i386)) || \
+#if	(defined(SVR4) && defined(__i386__)) || \
 	defined(__alpha__) || defined(__alpha) || \
-	defined(__i386__) || defined(__i386) || \
-	defined(__QNX__) || \
+	defined(__i386__) || defined(__QNX__) || \
 	defined(__s390x__) || defined(__s390__)
   
 #ifndef IMAGE_BYTE_ORDER
diff --git a/mi/micoord.h b/mi/micoord.h
index b3d725b..16a244b 100644
--- a/mi/micoord.h
+++ b/mi/micoord.h
@@ -46,8 +46,7 @@
 #if defined(mips) || defined(sgi) || \
     defined(sparc) || defined(__sparc64__) || \
     defined(__alpha) || defined(__alpha__) || \
-    defined(__i386__) || defined(i386) || \
-    defined(__ia64__) || defined(ia64) || \
+    defined(__i386__) || defined(__ia64__) || \
     defined(__s390x__) || defined(__s390__) || \
     defined(__amd64__) || defined(amd64) || defined(__amd64)
 #define GetHighWord(x) (((int) (x)) >> 16)
diff --git a/os/access.c b/os/access.c
index 5b638c7..b0f63ed 100644
--- a/os/access.c
+++ b/os/access.c
@@ -119,10 +119,10 @@ SOFTWARE.
 #  include <net/if.h>
 # endif
 #else
-#if defined(SVR4) ||  (defined(SYSV) && defined(i386)) || defined(__GNU__)
+#if defined(SVR4) ||  (defined(SYSV) && defined(__i386__)) || defined(__GNU__)
 # include <sys/utsname.h>
 #endif
-#if defined(SYSV) &&  defined(i386)
+#if defined(SYSV) &&  defined(__i386__)
 # include <sys/stream.h>
 # ifdef ISC
 #  include <sys/stropts.h>
diff --git a/os/io.c b/os/io.c
index 9de75ee..36abe13 100644
--- a/os/io.c
+++ b/os/io.c
@@ -356,7 +356,7 @@ ReadRequestFromClient(ClientPtr client)
 	{
 	    if ((result < 0) && ETEST(errno))
 	    {
-#if defined(SVR4) && defined(i386) && !defined(sun)
+#if defined(SVR4) && defined(__i386__) && !defined(sun)
 		if (0)
 #endif
 		{
diff --git a/os/xalloc.c b/os/xalloc.c
index 8c019f3..e5f3946 100644
--- a/os/xalloc.c
+++ b/os/xalloc.c
@@ -211,7 +211,7 @@ extern Bool Must_have_memory;
 			fclose(f);			\
 		  }					\
 		}
-#if defined(linux) && defined(i386)
+#if defined(linux) && defined(__i386__)
 #define LOG_ALLOC(_fun, _size, _ret)						\
 	{	unsigned long *from;						\
 		__asm__("movl %%ebp,%0" : /*OUT*/ "=r" (from) : /*IN*/ );	\
commit ec0fc012e91e703bb399a380df2912f71957a220
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Sun Oct 14 14:59:12 2007 -0400

    Fix GLX byteswapping.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 91c80b2..a6bd2df 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -109,9 +109,10 @@ static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen,
  * same as the VisualID.
  */
 
-int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
-		    GLXContextID shareList, VisualID visual,
-		    GLuint screen, GLboolean isDirect)
+static int
+DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
+		GLXContextID shareList, VisualID visual,
+		GLuint screen, GLboolean isDirect)
 {
     ClientPtr client = cl->client;
     VisualPtr pVisual;
@@ -385,36 +386,6 @@ static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
     glxc->isCurrent = GL_TRUE;
 }
 
-/*****************************************************************************/
-/*
-** Make an OpenGL context and drawable current.
-*/
-
-int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
-{
-    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
-
-    return DoMakeCurrent( cl, req->drawable, req->drawable,
-			  req->context, req->oldContextTag );
-}
-
-int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
-{
-    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
-
-    return DoMakeCurrent( cl, req->drawable, req->readdrawable,
-			  req->context, req->oldContextTag );
-}
-
-int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
-{
-    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
-
-    return DoMakeCurrent( cl, req->drawable, req->readable,
-			  req->context, req->oldContextTag );
-}
-
-
 /**
  * Given a drawable ID, get the associated drawable and / or pixmap.
  * 
@@ -501,10 +472,15 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
     return pGlxDraw;
 }
 
+/*****************************************************************************/
+/*
+** Make an OpenGL context and drawable current.
+*/
 
-int DoMakeCurrent( __GLXclientState *cl,
-		   GLXDrawable drawId, GLXDrawable readId,
-		   GLXContextID contextId, GLXContextTag tag )
+static int
+DoMakeCurrent(__GLXclientState *cl,
+	      GLXDrawable drawId, GLXDrawable readId,
+	      GLXContextID contextId, GLXContextTag tag)
 {
     ClientPtr client = cl->client;
     xGLXMakeCurrentReply reply;
@@ -658,6 +634,30 @@ int DoMakeCurrent( __GLXclientState *cl,
     return Success;
 }
 
+int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
+
+    return DoMakeCurrent( cl, req->drawable, req->drawable,
+			  req->context, req->oldContextTag );
+}
+
+int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
+
+    return DoMakeCurrent( cl, req->drawable, req->readdrawable,
+			  req->context, req->oldContextTag );
+}
+
+int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
+{
+    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
+
+    return DoMakeCurrent( cl, req->drawable, req->readable,
+			  req->context, req->oldContextTag );
+}
+
 int __glXDisp_IsDirect(__GLXclientState *cl, GLbyte *pc)
 {
     ClientPtr client = cl->client;
@@ -830,8 +830,8 @@ int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc)
 }
 
 
-int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
-		       GLboolean do_swap)
+static int
+DoGetVisualConfigs(__GLXclientState *cl, unsigned screen)
 {
     ClientPtr client = cl->client;
     xGLXGetVisualConfigsReply reply;
@@ -856,7 +856,7 @@ int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
     reply.type = X_Reply;
     reply.sequenceNumber = client->sequence;
 
-    if ( do_swap ) {
+    if (client->swapped) {
 	__GLX_SWAP_SHORT(&reply.sequenceNumber);
 	__GLX_SWAP_INT(&reply.length);
 	__GLX_SWAP_INT(&reply.numVisuals);
@@ -910,7 +910,7 @@ int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
 	buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
 	buf[p++] = modes->transparentIndex;
 
-	if ( do_swap ) {
+	if (client->swapped) {
 	    __GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_CONFIG);
 	}
 	WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, 
@@ -922,7 +922,7 @@ int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
 int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
-    return DoGetVisualConfigs( cl, req->screen, GL_FALSE );
+    return DoGetVisualConfigs(cl, req->screen);
 }
 
 
@@ -1018,7 +1018,8 @@ __glXCreateARGBConfig(__GLXscreen *screen)
  * is the same, so this routine pulls double duty.
  */
 
-int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
+static int
+DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
 {
     ClientPtr client = cl->client;
     xGLXGetFBConfigsReply reply;
@@ -1119,7 +1120,6 @@ int __glXDisp_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
     return DoGetFBConfigs( cl, req->screen, GL_FALSE );
 }
 
-
 int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
@@ -1501,7 +1501,8 @@ int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
 }
 
 
-int DoQueryContext(__GLXclientState *cl, GLXContextID gcId)
+static int
+DoQueryContext(__GLXclientState *cl, GLXContextID gcId)
 {
     ClientPtr client = cl->client;
     __GLXcontext *ctx;
@@ -1753,7 +1754,10 @@ int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
 ** client library to send batches of GL rendering commands.
 */
 
-int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
+/*
+** Execute all the drawing commands in a request.
+*/
+int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXRenderReq *req;
     ClientPtr client= cl->client;
@@ -1764,9 +1768,8 @@ int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
     __GLXcontext *glxc;
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    
     req = (xGLXRenderReq *) pc;
-    if (do_swap) {
+    if (client->swapped) {
 	__GLX_SWAP_SHORT(&req->length);
 	__GLX_SWAP_INT(&req->contextTag);
     }
@@ -1790,7 +1793,7 @@ int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
 	** Also, each command must be word aligned.
 	*/
 	hdr = (__GLXrenderHeader *) pc;
-	if (do_swap) {
+	if (client->swapped) {
 	    __GLX_SWAP_SHORT(&hdr->length);
 	    __GLX_SWAP_SHORT(&hdr->opcode);
 	}
@@ -1802,7 +1805,8 @@ int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
 	*/
 	err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry);
 	proc = (__GLXdispatchRenderProcPtr)
-	  __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode, do_swap);
+	    __glXGetProtocolDecodeFunction(& Render_dispatch_info,
+					   opcode, client->swapped);
 
 	if ((err < 0) || (proc == NULL)) {
 	    client->errorValue = commandsDone;
@@ -1811,7 +1815,8 @@ int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
 
         if (entry.varsize) {
             /* variable size command */
-            extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE, do_swap);
+            extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE,
+				     client->swapped);
             if (extra < 0) {
                 extra = 0;
             }
@@ -1844,15 +1849,11 @@ int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap)
     return Success;
 }
 
+
 /*
-** Execute all the drawing commands in a request.
+** Execute a large rendering request (one that spans multiple X requests).
 */
-int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc)
-{
-    return DoRender(cl, pc, False);
-}
-
-int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
+int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXRenderLargeReq *req;
     ClientPtr client= cl->client;
@@ -1862,10 +1863,9 @@ int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
     int error;
     CARD16 opcode;
     __GLX_DECLARE_SWAP_VARIABLES;
-
     
     req = (xGLXRenderLargeReq *) pc;
-    if (do_swap) {
+    if (client->swapped) {
 	__GLX_SWAP_SHORT(&req->length);
 	__GLX_SWAP_INT(&req->contextTag);
 	__GLX_SWAP_INT(&req->dataBytes);
@@ -1908,7 +1908,7 @@ int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
 	}
 
 	hdr = (__GLXrenderLargeHeader *) pc;
-	if (do_swap) {
+	if (client->swapped) {
 	    __GLX_SWAP_INT(&hdr->length);
 	    __GLX_SWAP_INT(&hdr->opcode);
 	}
@@ -1930,7 +1930,8 @@ int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
 	    ** be computed from its parameters), all the parameters needed
 	    ** will be in the 1st request, so it's okay to do this.
 	    */
-	    extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE, do_swap);
+	    extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE,
+				     client->swapped);
 	    if (extra < 0) {
 		extra = 0;
 	    }
@@ -2030,7 +2031,8 @@ int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
 	    opcode = hdr->opcode;
 
 	    proc = (__GLXdispatchRenderProcPtr)
-	      __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode, do_swap);
+	      __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode,
+					     client->swapped);
 	    if (proc == NULL) {
 		client->errorValue = opcode;
 		return __glXError(GLXBadLargeRequest);
@@ -2055,14 +2057,6 @@ int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap)
     }
 }
 
-/*
-** Execute a large rendering request (one that spans multiple X requests).
-*/
-int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc)
-{
-    return DoRenderLarge(cl, pc, False);
-}
-
 extern RESTYPE __glXSwapBarrierRes;
 
 int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
diff --git a/GL/glx/glxcmdsswap.c b/GL/glx/glxcmdsswap.c
index 3f600c1..7f17c26 100644
--- a/GL/glx/glxcmdsswap.c
+++ b/GL/glx/glxcmdsswap.c
@@ -77,8 +77,7 @@ int __glXDispSwap_CreateContext(__GLXclientState *cl, GLbyte *pc)
     __GLX_SWAP_INT(&req->screen);
     __GLX_SWAP_INT(&req->shareList);
 
-    return DoCreateContext( cl, req->context, req->shareList, req->visual,
-			    req->screen, req->isDirect );
+    return __glXDisp_CreateContext(cl, pc);
 }
 
 int __glXDispSwap_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
@@ -93,8 +92,7 @@ int __glXDispSwap_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
     __GLX_SWAP_INT(&req->renderType);
     __GLX_SWAP_INT(&req->shareList);
 
-    return DoCreateContext( cl, req->context, req->shareList, req->fbconfig,
-			    req->screen, req->isDirect );
+    return __glXDisp_CreateNewContext(cl, pc);
 }
 
 int __glXDispSwap_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
@@ -110,8 +108,7 @@ int __glXDispSwap_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
     __GLX_SWAP_INT(&req->renderType);
     __GLX_SWAP_INT(&req->shareList);
 
-    return DoCreateContext( cl, req->context, req->shareList, req->fbconfig,
-			    req->screen, req->isDirect );
+    return __glXDisp_CreateContextWithConfigSGIX(cl, pc);
 }
 
 int __glXDispSwap_DestroyContext(__GLXclientState *cl, GLbyte *pc)
@@ -135,8 +132,7 @@ int __glXDispSwap_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
     __GLX_SWAP_INT(&req->context);
     __GLX_SWAP_INT(&req->oldContextTag);
 
-    return DoMakeCurrent( cl, req->drawable, req->drawable,
-			  req->context, req->oldContextTag );
+    return __glXDisp_MakeCurrent(cl, pc);
 }
 
 int __glXDispSwap_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
@@ -150,8 +146,7 @@ int __glXDispSwap_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
     __GLX_SWAP_INT(&req->context);
     __GLX_SWAP_INT(&req->oldContextTag);
 
-    return DoMakeCurrent( cl, req->drawable, req->readdrawable,
-			  req->context, req->oldContextTag );
+    return __glXDisp_MakeContextCurrent(cl, pc);
 }
 
 int __glXDispSwap_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
@@ -165,8 +160,7 @@ int __glXDispSwap_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
     __GLX_SWAP_INT(&req->context);
     __GLX_SWAP_INT(&req->oldContextTag);
 
-    return DoMakeCurrent( cl, req->drawable, req->readable,
-			  req->context, req->oldContextTag );
+    return __glXDisp_MakeCurrentReadSGI(cl, pc);
 }
 
 int __glXDispSwap_IsDirect(__GLXclientState *cl, GLbyte *pc)
@@ -233,7 +227,7 @@ int __glXDispSwap_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
     __GLX_DECLARE_SWAP_VARIABLES;
 
     __GLX_SWAP_INT(&req->screen);
-    return DoGetVisualConfigs( cl, req->screen, GL_TRUE );
+    return __glXDisp_GetVisualConfigs(cl, pc);
 }
 
 int __glXDispSwap_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
@@ -242,7 +236,7 @@ int __glXDispSwap_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
     __GLX_DECLARE_SWAP_VARIABLES;
 
     __GLX_SWAP_INT(&req->screen);
-    return DoGetFBConfigs( cl, req->screen, GL_TRUE );
+    return __glXDisp_GetFBConfigs(cl, pc);
 }
 
 int __glXDispSwap_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
@@ -251,7 +245,7 @@ int __glXDispSwap_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
     __GLX_DECLARE_SWAP_VARIABLES;
 
     __GLX_SWAP_INT(&req->screen);
-    return DoGetFBConfigs( cl, req->screen, GL_TRUE );
+    return __glXDisp_GetFBConfigsSGIX(cl, pc);
 }
 
 int __glXDispSwap_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
@@ -265,14 +259,15 @@ int __glXDispSwap_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
     __GLX_SWAP_INT(&req->pixmap);
     __GLX_SWAP_INT(&req->glxpixmap);
 
-    return DoCreateGLXPixmap( cl, req->visual, req->screen,
-			      req->pixmap, req->glxpixmap, NULL, 0 );
+    return __glXDisp_CreateGLXPixmap(cl, pc);
 }
 
 int __glXDispSwap_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
+    CARD32 *attribs;
     __GLX_DECLARE_SWAP_VARIABLES;
+    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 
     __GLX_SWAP_SHORT(&req->length);
     __GLX_SWAP_INT(&req->screen);
@@ -280,11 +275,10 @@ int __glXDispSwap_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
     __GLX_SWAP_INT(&req->pixmap);
     __GLX_SWAP_INT(&req->glxpixmap);
     __GLX_SWAP_INT(&req->numAttribs);
+    attribs = (CARD32*)(req + 1);
+    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
 
-    return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
-			      req->pixmap, req->glxpixmap,
-			      (CARD32*)(req + 1),
-			      req->numAttribs );
+    return __glXDisp_CreatePixmap(cl, pc);
 }
 
 int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
@@ -299,8 +293,7 @@ int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc
     __GLX_SWAP_INT(&req->pixmap);
     __GLX_SWAP_INT(&req->glxpixmap);
 
-    return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
-			      req->pixmap, req->glxpixmap, NULL, 0 );
+    return __glXDisp_CreateGLXPixmapWithConfigSGIX(cl, pc);
 }
 
 int __glXDispSwap_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
@@ -328,50 +321,78 @@ int __glXDispSwap_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
 int __glXDispSwap_QueryContext(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;    
+    __GLX_DECLARE_SWAP_VARIABLES;
 
-    (void) req;
+    __GLX_SWAP_INT(&req->context);
 
-    return BadRequest;    
+    return __glXDisp_QueryContext(cl, pc);
 }
 
 int __glXDispSwap_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;    
+    __GLX_DECLARE_SWAP_VARIABLES;
+    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+    CARD32 *attribs;
 
-    (void) req;
+    __GLX_SWAP_INT(&req->screen);
+    __GLX_SWAP_INT(&req->fbconfig);
+    __GLX_SWAP_INT(&req->pbuffer);
+    __GLX_SWAP_INT(&req->numAttribs);
+    attribs = (CARD32*)(req + 1);
+    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
 
-    return BadRequest;    
+    return __glXDisp_CreatePbuffer(cl, pc);
 }
 
 int __glXDispSwap_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;    
+    __GLX_DECLARE_SWAP_VARIABLES;
 
-    (void) req;
+    __GLX_SWAP_INT(&req->screen);
+    __GLX_SWAP_INT(&req->fbconfig);
+    __GLX_SWAP_INT(&req->pbuffer);
+    __GLX_SWAP_INT(&req->width);
+    __GLX_SWAP_INT(&req->height);
 
-    return BadRequest;    
+    return __glXDisp_CreateGLXPbufferSGIX(cl, pc);
 }
 
 int __glXDispSwap_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) req;
+    __GLX_DECLARE_SWAP_VARIABLES;
 
-    return BadRequest;
+    __GLX_SWAP_INT(&req->pbuffer);
+
+    return __glXDisp_DestroyPbuffer(cl, pc);
 }
 
 int __glXDispSwap_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) req;
+    __GLX_DECLARE_SWAP_VARIABLES;
 
-    return BadRequest;
+    __GLX_SWAP_INT(&req->pbuffer);
+
+    return __glXDisp_DestroyGLXPbufferSGIX(cl, pc);
 }
 
 int __glXDispSwap_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXChangeDrawableAttributesReq *req =
 	(xGLXChangeDrawableAttributesReq *) req;
+    __GLX_DECLARE_SWAP_VARIABLES;
+    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+    CARD32 *attribs;
+
+    __GLX_SWAP_INT(&req->drawable);
+    __GLX_SWAP_INT(&req->numAttribs);
+    attribs = (CARD32*)(req + 1);
+    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
 
-    return BadRequest;
+    return __glXDisp_ChangeDrawableAttributes(cl, pc);
 }
 
 int __glXDispSwap_ChangeDrawableAttributesSGIX(__GLXclientState *cl,
@@ -379,26 +400,44 @@ int __glXDispSwap_ChangeDrawableAttributesSGIX(__GLXclientState *cl,
 {
     xGLXChangeDrawableAttributesSGIXReq *req =
 	(xGLXChangeDrawableAttributesSGIXReq *) req;
+    __GLX_DECLARE_SWAP_VARIABLES;
+    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+    CARD32 *attribs;
 
-    return BadRequest;
+    __GLX_SWAP_INT(&req->drawable);
+    __GLX_SWAP_INT(&req->numAttribs);
+    attribs = (CARD32*)(req + 1);
+    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
+
+    return __glXDisp_ChangeDrawableAttributesSGIX(cl, pc);
 }
 
 int __glXDispSwap_CreateWindow(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
+    __GLX_DECLARE_SWAP_VARIABLES;
+    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+    CARD32 *attribs;
 
-    (void) req;
+    __GLX_SWAP_INT(&req->screen);
+    __GLX_SWAP_INT(&req->fbconfig);
+    __GLX_SWAP_INT(&req->window);
+    __GLX_SWAP_INT(&req->glxwindow);
+    __GLX_SWAP_INT(&req->numAttribs);
+    attribs = (CARD32*)(req + 1);
+    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs);
 
-    return BadRequest;
+    return __glXDisp_CreateWindow(cl, pc);
 }
 
 int __glXDispSwap_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
+    __GLX_DECLARE_SWAP_VARIABLES;
 
-    (void) req;
+    __GLX_SWAP_INT(&req->glxwindow);
 
-    return BadRequest;
+    return __glXDisp_DestroyWindow(cl, pc);
 }
 
 int __glXDispSwap_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
@@ -668,7 +707,7 @@ void __glXSwapGetDrawableAttributesReply(ClientPtr client,
 
 int __glXDispSwap_Render(__GLXclientState *cl, GLbyte *pc)
 {
-    return DoRender(cl, pc, True);
+    return __glXDisp_Render(cl, pc);
 }
 
 /*
@@ -676,7 +715,7 @@ int __glXDispSwap_Render(__GLXclientState *cl, GLbyte *pc)
 */
 int __glXDispSwap_RenderLarge(__GLXclientState *cl, GLbyte *pc)
 {
-    return DoRenderLarge(cl, pc, True);
+    return __glXDisp_RenderLarge(cl, pc);
 }
 
 /************************************************************************/
diff --git a/GL/glx/glxext.h b/GL/glx/glxext.h
index 601bb22..a81850c 100644
--- a/GL/glx/glxext.h
+++ b/GL/glx/glxext.h
@@ -71,19 +71,6 @@ extern void __glXClearErrorOccured(void);
 extern GLboolean __glXErrorOccured(void);
 extern void __glXResetLargeCommandStatus(__GLXclientState*);
 
-extern int DoMakeCurrent( __GLXclientState *cl, GLXDrawable drawId,
-    GLXDrawable readId, GLXContextID contextId, GLXContextTag tag );
-extern int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
-    GLboolean do_swap);
-extern int DoGetFBConfigs(__GLXclientState *cl, unsigned screen,
-    GLboolean do_swap);
-extern int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
-    GLXContextID shareList, VisualID visual, GLuint screen, GLboolean isDirect);
-extern int DoQueryContext(__GLXclientState *cl, GLXContextID gcId);
-
-extern int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap);
-extern int DoRenderLarge(__GLXclientState *cl, GLbyte *pc, int do_swap);
-
 extern void GlxExtensionInit(void);
 
 extern const char GLServerVersion[];
commit 927757e1028f45f7fd94b9a2ab35567e0f34b2a8
Merge: ccda4b6... 17ffc34...
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Fri Oct 12 19:28:39 2007 -0400

    Merge branch 'master' of git://git.freedesktop.org/git/xorg/xserver

commit ccda4b66bdfc179e661b24adc8ec72bb7db75b2b
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Mon Aug 27 14:43:48 2007 -0400

    Implement ChangeDrawableAttributes so we can support GLX_EVENT_MASK.
    
    We never need to actually send out the clobber event, so this should be
    sufficient for GLX 1.3.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index f838f21..91c80b2 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -1385,14 +1385,35 @@ int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
     return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
 }
 
+static int
+DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable,
+			   int numAttribs, CARD32 *attribs)
+{
+    __GLXdrawable *pGlxDraw;
+    int i;
+
+    pGlxDraw = LookupIDByType(glxdrawable, __glXDrawableRes);
+    for (i = 0; i < numAttribs; i++) {
+	switch(attribs[i * 2]) {
+	case GLX_EVENT_MASK:
+	    /* All we do is to record the event mask so we can send it
+	     * back when queried.  We never actually clobber the
+	     * pbuffers, so we never need to send out the event. */
+	    pGlxDraw->eventMask = attribs[i * 2 + 1];
+	    break;
+	}
+    }
+
+    return Success;
+}
+
 int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXChangeDrawableAttributesReq *req =
 	(xGLXChangeDrawableAttributesReq *) pc;
 
-    (void) req;
-
-    return BadRequest;
+    return DoChangeDrawableAttributes(cl->client, req->drawable,
+				      req->numAttribs, (CARD32 *) (req + 1));
 }
 
 int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
@@ -1400,9 +1421,8 @@ int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
     xGLXChangeDrawableAttributesSGIXReq *req =
 	(xGLXChangeDrawableAttributesSGIXReq *)pc;
 
-    (void) req;
-
-    return BadRequest;
+    return DoChangeDrawableAttributes(cl->client, req->drawable,
+				      req->numAttribs, (CARD32 *) (req + 1));
 }
 
 int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
@@ -1676,7 +1696,7 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
     ClientPtr client = cl->client;
     xGLXGetDrawableAttributesReply reply;
     __GLXdrawable *pGlxDraw;
-    CARD32 attributes[4];
+    CARD32 attributes[6];
     int numAttribs, error;
 
     pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
@@ -1685,7 +1705,7 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
 	return error;
     }
 
-    numAttribs = 2;
+    numAttribs = 3;
     reply.length = numAttribs << 1;
     reply.type = X_Reply;
     reply.sequenceNumber = client->sequence;
@@ -1696,6 +1716,8 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
 	GLX_TEXTURE_RECTANGLE_EXT;
     attributes[2] = GLX_Y_INVERTED_EXT;
     attributes[3] = GL_FALSE;
+    attributes[4] = GLX_EVENT_MASK;
+    attributes[5] = pGlxDraw->eventMask;
 
     if (client->swapped) {
 	__glXSwapGetDrawableAttributesReply(client, &reply, attributes);
diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h
index 247e7a2..858bbb3 100644
--- a/GL/glx/glxdrawable.h
+++ b/GL/glx/glxdrawable.h
@@ -95,6 +95,11 @@ struct __GLXdrawable {
     int refCount;
 
     GLenum target;
+
+    /*
+    ** Event mask
+    */
+    unsigned long eventMask;
 };
 
 #endif /* !__GLX_drawable_h__ */
diff --git a/GL/glx/glxutil.c b/GL/glx/glxutil.c
index 9479a58..f531ed9 100644
--- a/GL/glx/glxutil.c
+++ b/GL/glx/glxutil.c
@@ -147,6 +147,7 @@ __glXDrawableInit(__GLXdrawable *drawable,
     drawable->drawId = drawId;
     drawable->refCount = 1;
     drawable->modes = modes;
+    drawable->eventMask = 0;
 
     return GL_TRUE;
 }
commit 695eb8b2e88abc9fa3a76d8da48c3214c7dd1f08
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Mon Aug 27 14:23:50 2007 -0400

    Implement GLX pbuffers.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 0d576c1..f838f21 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -488,7 +488,8 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
     }
 
     pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
-						pDraw, drawId, modes);
+						pDraw, GLX_DRAWABLE_WINDOW,
+						drawId, modes);
 
     /* since we are creating the drawablePrivate, drawId should be new */
     if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
@@ -1127,24 +1128,17 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
 
 static int 
 DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
-		    XID drawableId, XID glxDrawableId, int type)
+		    DrawablePtr pDraw, XID glxDrawableId, int type)
 {
-    DrawablePtr pDraw;
     ScreenPtr pScreen;
     VisualPtr pVisual;
     __GLXscreen *pGlxScreen;
     __GLXdrawable *pGlxDraw;
     __GLcontextModes *modes;
-    int i, rc;
+    int i;
 
     LEGAL_NEW_RESOURCE(glxDrawableId, client);
 
-    rc = dixLookupDrawable(&pDraw, drawableId, client, 0, DixUnknownAccess);
-    if (rc != Success || pDraw->type != type) {
-	client->errorValue = drawableId;
-	return type == DRAWABLE_WINDOW ? BadWindow : BadPixmap;
-    }
-
     /* Check if screen of the fbconfig matches screen of drawable. */
     pScreen = pDraw->pScreen;
     if (screenNum != pScreen->myNum)
@@ -1169,7 +1163,7 @@ DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
 
     /* FIXME: We need to check that the window visual is compatible
      * with the specified fbconfig. */
-    pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw,
+    pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type,
 					  glxDrawableId, modes);
     if (pGlxDraw == NULL)
 	return BadAlloc;
@@ -1179,10 +1173,29 @@ DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
 	return BadAlloc;
     }
 
-    if (type == DRAWABLE_PIXMAP)
+    return Success;
+}
+
+static int
+DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId,
+		  XID drawableId, XID glxDrawableId)
+{
+    DrawablePtr pDraw;
+    int err;
+
+    err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixUnknownAccess);
+    if (err != Success || pDraw->type != DRAWABLE_PIXMAP) {
+	client->errorValue = drawableId;
+	return BadPixmap;
+    }
+
+    err = DoCreateGLXDrawable(client, screenNum, fbconfigId, pDraw,
+			      glxDrawableId, GLX_DRAWABLE_PIXMAP);
+
+    if (err == Success)
 	((PixmapPtr) pDraw)->refcnt++;
 
-    return Success;
+    return err;
 }
 
 static void
@@ -1223,8 +1236,8 @@ int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
 
-    return DoCreateGLXDrawable(cl->client, req->screen, req->visual,
-			       req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
+    return DoCreateGLXPixmap(cl->client, req->screen, req->visual,
+			     req->pixmap, req->glxpixmap);
 }
 
 int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
@@ -1232,8 +1245,8 @@ int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
     xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
     int err;
 
-    err = DoCreateGLXDrawable(cl->client, req->screen, req->fbconfig,
-			      req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
+    err = DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig,
+			    req->pixmap, req->glxpixmap);
     if (err != Success)
 	return err;
 
@@ -1248,8 +1261,8 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
     xGLXCreateGLXPixmapWithConfigSGIXReq *req = 
 	(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
 
-    return DoCreateGLXDrawable(cl->client, req->screen, req->fbconfig,
-			       req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
+    return DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig,
+			     req->pixmap, req->glxpixmap);
 }
 
 
@@ -1257,7 +1270,6 @@ static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
 {
     ClientPtr client = cl->client;
     __GLXdrawable *pGlxDraw;
-    int error;
 
     /*
     ** Check it's the right type of drawable.
@@ -1265,8 +1277,14 @@ static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
     pGlxDraw = LookupIDByType(glxdrawable, __glXDrawableRes);
     if (pGlxDraw == NULL || pGlxDraw->type != type) {
 	client->errorValue = glxdrawable;
-	error = type == DRAWABLE_WINDOW ? GLXBadWindow : GLXBadDrawable;
-	return __glXError(error);
+	switch (type) {
+	case GLX_DRAWABLE_WINDOW:
+	    return __glXError(GLXBadWindow);
+	case GLX_DRAWABLE_PIXMAP:
+	    return __glXError(GLXBadDrawable);
+	case GLX_DRAWABLE_PBUFFER:
+	    return __glXError(GLXBadPbuffer);
+	}
     }
     FreeResource(glxdrawable, FALSE);
 
@@ -1277,50 +1295,94 @@ int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
 
-    return DoDestroyDrawable(cl, req->glxpixmap, DRAWABLE_PIXMAP);
+    return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
 }
 
 int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
 
-    return DoDestroyDrawable(cl, req->glxpixmap, DRAWABLE_PIXMAP);
+    return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
+}
+
+static int
+DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
+		int width, int height, XID glxDrawableId)
+{
+    ScreenPtr	 pScreen;
+    VisualPtr	 pVisual;
+    PixmapPtr	 pPixmap;
+    int		i;
+
+    pScreen = screenInfo.screens[screenNum];
+
+    pVisual = pScreen->visuals;
+    for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
+	if (pVisual->vid == fbconfigId)
+	    break;
+    }
+    if (i == pScreen->numVisuals)
+	return __glXError(GLXBadFBConfig);
+
+    __glXenterServer(GL_FALSE);
+    pPixmap = (*pScreen->CreatePixmap) (pScreen,
+					width, height, pVisual->nplanes);
+    __glXleaveServer(GL_FALSE);
+
+    return DoCreateGLXDrawable(client, screenNum, fbconfigId,
+			       &pPixmap->drawable, glxDrawableId,
+			       GLX_DRAWABLE_PBUFFER);
 }
 
 int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
 {
-    xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
+    xGLXCreatePbufferReq	*req = (xGLXCreatePbufferReq *) pc;
+    CARD32			*attrs;
+    int				 width, height, i;
 
-    (void) req;
+    attrs = (CARD32 *) (req + 1);
+    width = 0;
+    height = 0;
 
-    return BadRequest;
+    for (i = 0; i < req->numAttribs; i++) {
+	switch (attrs[i * 2]) {
+	case GLX_PBUFFER_WIDTH:
+	    width = attrs[i * 2 + 1];
+	    break;
+	case GLX_PBUFFER_HEIGHT:
+	    height = attrs[i * 2 + 1];
+	    break;
+	case GLX_LARGEST_PBUFFER:
+	case GLX_PRESERVED_CONTENTS:
+	    /* FIXME: huh... */
+	    break;
+	}
+    }
+
+    return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
+			   width, height, req->pbuffer);
 }
 
 int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
 
-    (void) req;
-
-    return BadRequest;
+    return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
+			   req->width, req->height, req->pbuffer);
 }
 
 int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
 
-    (void) req;
-
-    return BadRequest;
+    return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
 }
 
-__glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
 
-    (void) req;
-
-    return BadRequest;
+    return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
 }
 
 int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
@@ -1345,18 +1407,26 @@ int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
 
 int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
 {
-    xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
-    ClientPtr client = cl->client;
+    xGLXCreateWindowReq	*req = (xGLXCreateWindowReq *) pc;
+    ClientPtr		 client = cl->client;
+    DrawablePtr		 pDraw;
+    int			 err;
+
+    err = dixLookupDrawable(&pDraw, req->window, client, 0, DixUnknownAccess);
+    if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
+	client->errorValue = req->window;
+	return BadWindow;
+    }
 
     return DoCreateGLXDrawable(client, req->screen, req->fbconfig,
-			       req->window, req->glxwindow, DRAWABLE_WINDOW);
+			       pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW);
 }
 
 int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
 
-    return DoDestroyDrawable(cl, req->glxwindow, DRAWABLE_WINDOW);
+    return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
 }
 
 
@@ -1493,7 +1563,7 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 	return error;
 
     pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
-    if (!pGlxDraw || pGlxDraw->type != DRAWABLE_PIXMAP) {
+    if (!pGlxDraw || pGlxDraw->type != GLX_DRAWABLE_PIXMAP) {
 	client->errorValue = drawId;
 	return __glXError(GLXBadPixmap);
     }
@@ -1526,7 +1596,7 @@ int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 	return error;
 
     pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
-    if (error != Success || pGlxDraw->type != DRAWABLE_PIXMAP) {
+    if (error != Success || pGlxDraw->type != GLX_DRAWABLE_PIXMAP) {
 	client->errorValue = drawId;
 	return error;
     }
@@ -1588,7 +1658,7 @@ int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
 	return error;
 
     if (pGlxDraw == NULL ||
-	pGlxDraw->type != DRAWABLE_WINDOW ||
+	pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
 	pGlxDraw->copySubBuffer == NULL)
 	return __glXError(GLXBadDrawable);
 
diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h
index 5fdcf95..247e7a2 100644
--- a/GL/glx/glxdrawable.h
+++ b/GL/glx/glxdrawable.h
@@ -46,6 +46,13 @@
 #include <GL/internal/dri_interface.h>
 #endif
 
+/* We just need to avoid clashing with DRAWABLE_{WINDOW,PIXMAP} */
+enum {
+    GLX_DRAWABLE_WINDOW,
+    GLX_DRAWABLE_PIXMAP,
+    GLX_DRAWABLE_PBUFFER
+};
+
 struct __GLXdrawable {
     void (*destroy)(__GLXdrawable *private);
     GLboolean (*resize)(__GLXdrawable *private);
@@ -63,9 +70,8 @@ struct __GLXdrawable {
     XID drawId;
 
     /*
-    ** Either DRAWABLE_PIXMAP or DRAWABLE_WINDOW, copied from pDraw above.
-    ** Needed by the resource freer because pDraw might already have been
-    ** freed.
+    ** Either GLX_DRAWABLE_PIXMAP, GLX_DRAWABLE_WINDOW or
+    ** GLX_DRAWABLE_PBUFFER.
     */
     int type;
 
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index 3394e58..2ded6aa 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -615,6 +615,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
 static __GLXdrawable *
 __glXDRIscreenCreateDrawable(__GLXscreen *screen,
 			     DrawablePtr pDraw,
+			     int type,
 			     XID drawId,
 			     __GLcontextModes *modes)
 {
@@ -629,7 +630,8 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
 
     memset(private, 0, sizeof *private);
 
-    if (!__glXDrawableInit(&private->base, screen, pDraw, drawId, modes)) {
+    if (!__glXDrawableInit(&private->base, screen,
+			   pDraw, type, drawId, modes)) {
         xfree(private);
 	return NULL;
     }
diff --git a/GL/glx/glxext.h b/GL/glx/glxext.h
index 8de6434..601bb22 100644
--- a/GL/glx/glxext.h
+++ b/GL/glx/glxext.h
@@ -79,11 +79,6 @@ extern int DoGetFBConfigs(__GLXclientState *cl, unsigned screen,
     GLboolean do_swap);
 extern int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
     GLXContextID shareList, VisualID visual, GLuint screen, GLboolean isDirect);
-extern int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
-    GLuint screenNum, XID pixmapId, XID glxpixmapId, CARD32 *attribs,
-    CARD32 numAttribs);
-extern int DoDestroyPixmap(__GLXclientState *cl, XID glxpixmapId);
-
 extern int DoQueryContext(__GLXclientState *cl, GLXContextID gcId);
 
 extern int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap);
diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c
index 679d55c..fd4e57d 100644
--- a/GL/glx/glxglcore.c
+++ b/GL/glx/glxglcore.c
@@ -118,7 +118,7 @@ __glXMesaDrawableSwapBuffers(__GLXdrawable *base)
 
 static __GLXdrawable *
 __glXMesaScreenCreateDrawable(__GLXscreen *screen,
-			      DrawablePtr pDraw,
+			      DrawablePtr pDraw, int type,
 			      XID drawId,
 			      __GLcontextModes *modes)
 {
@@ -131,7 +131,8 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen,
 
     memset(glxPriv, 0, sizeof *glxPriv);
 
-    if (!__glXDrawableInit(&glxPriv->base, screen, pDraw, drawId, modes)) {
+    if (!__glXDrawableInit(&glxPriv->base, screen,
+			   pDraw, type, drawId, modes)) {
         xfree(glxPriv);
 	return NULL;
     }
diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h
index d887beb..7b1bbcd 100644
--- a/GL/glx/glxscreens.h
+++ b/GL/glx/glxscreens.h
@@ -72,6 +72,7 @@ struct __GLXscreen {
 
     __GLXdrawable *(*createDrawable)(__GLXscreen *context,
 				     DrawablePtr pDraw,
+				     int type,
 				     XID drawId,
 				     __GLcontextModes *modes);
     int            (*swapInterval)  (__GLXdrawable *drawable,
diff --git a/GL/glx/glxutil.c b/GL/glx/glxutil.c
index df1cb2a..9479a58 100644
--- a/GL/glx/glxutil.c
+++ b/GL/glx/glxutil.c
@@ -139,11 +139,11 @@ __glXUnrefDrawable(__GLXdrawable *glxPriv)
 
 GLboolean
 __glXDrawableInit(__GLXdrawable *drawable,
-		  __GLXscreen *screen, DrawablePtr pDraw, XID drawId,
-		  __GLcontextModes *modes)
+		  __GLXscreen *screen, DrawablePtr pDraw, int type,
+		  XID drawId, __GLcontextModes *modes)
 {
-    drawable->type = pDraw->type;
     drawable->pDraw = pDraw;
+    drawable->type = type;
     drawable->drawId = drawId;
     drawable->refCount = 1;
     drawable->modes = modes;
diff --git a/GL/glx/glxutil.h b/GL/glx/glxutil.h
index 1937ef2..6534c3f 100644
--- a/GL/glx/glxutil.h
+++ b/GL/glx/glxutil.h
@@ -50,7 +50,7 @@ extern void __glXUnrefDrawable(__GLXdrawable *glxPriv);
 
 extern GLboolean __glXDrawableInit(__GLXdrawable *drawable,
 				   __GLXscreen *screen,
-				   DrawablePtr pDraw, XID drawID,
+				   DrawablePtr pDraw, int type, XID drawID,
 				   __GLcontextModes *modes);
 
 /* context helper routines */
diff --git a/configure.ac b/configure.ac
index 444edfd..59dcde7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -776,7 +776,7 @@ fi
 
 if test "x$GLX" = xyes && ! test "x$MESA_SOURCE" = x; then
 	PKG_CHECK_MODULES([XLIB], [x11])
-	PKG_CHECK_MODULES([GL], [glproto >= 1.4.8])
+	PKG_CHECK_MODULES([GL], [glproto >= 1.4.9])
 	AC_SUBST(XLIB_CFLAGS)
 	AC_DEFINE(GLXEXT, 1, [Build GLX extension])
 	GLX_LIBS='$(top_builddir)/GL/glx/libglx.la $(top_builddir)/GL/mesa/libGLcore.la'
commit 516c181f57367847c3f317f8f8f5cc3211026f4c
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Thu Aug 23 21:40:01 2007 -0400

    Add dispatching for GLX_SGIX_pbuffer.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index bf6d6e2..0d576c1 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -1296,6 +1296,15 @@ int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
     return BadRequest;
 }
 
+int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+    xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
+
+    (void) req;
+
+    return BadRequest;
+}
+
 int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
@@ -1305,6 +1314,15 @@ int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
     return BadRequest;
 }
 
+__glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+    xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
+
+    (void) req;
+
+    return BadRequest;
+}
+
 int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXChangeDrawableAttributesReq *req =
@@ -1315,6 +1333,16 @@ int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
     return BadRequest;
 }
 
+int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+    xGLXChangeDrawableAttributesSGIXReq *req =
+	(xGLXChangeDrawableAttributesSGIXReq *)pc;
+
+    (void) req;
+
+    return BadRequest;
+}
+
 int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
@@ -1611,22 +1639,18 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
     return Success;
 }
 
-int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
+int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
 {
-    xGLXVendorPrivateWithReplyReq *req = (xGLXVendorPrivateWithReplyReq *)pc;
-    CARD32 *data;
-    XID drawable;
-    
-    data = (CARD32 *) (req + 1);
-    drawable = data[0];
+    xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
 
-    return DoGetDrawableAttributes(cl, drawable);
+    return DoGetDrawableAttributes(cl, req->drawable);
 }
 
-int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
+int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
 {
-    xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
-
+    xGLXGetDrawableAttributesSGIXReq *req =
+	(xGLXGetDrawableAttributesSGIXReq *)pc;
+    
     return DoGetDrawableAttributes(cl, req->drawable);
 }
 
diff --git a/GL/glx/glxcmdsswap.c b/GL/glx/glxcmdsswap.c
index 12bc030..3f600c1 100644
--- a/GL/glx/glxcmdsswap.c
+++ b/GL/glx/glxcmdsswap.c
@@ -343,6 +343,15 @@ int __glXDispSwap_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
     return BadRequest;    
 }
 
+int __glXDispSwap_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+    xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;    
+
+    (void) req;
+
+    return BadRequest;    
+}
+
 int __glXDispSwap_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) req;
@@ -350,6 +359,13 @@ int __glXDispSwap_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
     return BadRequest;
 }
 
+int __glXDispSwap_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+    xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) req;
+
+    return BadRequest;
+}
+
 int __glXDispSwap_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXChangeDrawableAttributesReq *req =
@@ -358,6 +374,15 @@ int __glXDispSwap_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
     return BadRequest;
 }
 
+int __glXDispSwap_ChangeDrawableAttributesSGIX(__GLXclientState *cl,
+					       GLbyte *pc)
+{
+    xGLXChangeDrawableAttributesSGIXReq *req =
+	(xGLXChangeDrawableAttributesSGIXReq *) req;
+
+    return BadRequest;
+}
+
 int __glXDispSwap_CreateWindow(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
diff --git a/GL/glx/indirect_dispatch.h b/GL/glx/indirect_dispatch.h
index 24f4bed..bb39638 100644
--- a/GL/glx/indirect_dispatch.h
+++ b/GL/glx/indirect_dispatch.h
@@ -207,6 +207,8 @@ extern HIDDEN void __glXDisp_TexCoord2iv(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_TexCoord2iv(GLbyte * pc);
 extern HIDDEN void __glXDisp_CompressedTexImage1DARB(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_CompressedTexImage1DARB(GLbyte * pc);
+extern HIDDEN void __glXDisp_Rotated(GLbyte * pc);
+extern HIDDEN void __glXDispSwap_Rotated(GLbyte * pc);
 extern HIDDEN int __glXDisp_ReadPixels(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN int __glXDispSwap_ReadPixels(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN void __glXDisp_EdgeFlagv(GLbyte * pc);
@@ -293,8 +295,8 @@ extern HIDDEN void __glXDisp_ClearIndex(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_ClearIndex(GLbyte * pc);
 extern HIDDEN void __glXDisp_LoadMatrixd(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_LoadMatrixd(GLbyte * pc);
-extern HIDDEN void __glXDisp_RasterPos2dv(GLbyte * pc);
-extern HIDDEN void __glXDispSwap_RasterPos2dv(GLbyte * pc);
+extern HIDDEN void __glXDisp_PushMatrix(GLbyte * pc);
+extern HIDDEN void __glXDispSwap_PushMatrix(GLbyte * pc);
 extern HIDDEN void __glXDisp_ConvolutionParameterfv(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_ConvolutionParameterfv(GLbyte * pc);
 extern HIDDEN int __glXDisp_GetTexGendv(struct __GLXclientStateRec *, GLbyte *);
@@ -371,14 +373,16 @@ extern HIDDEN void __glXDisp_ProgramNamedParameter4fvNV(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_ProgramNamedParameter4fvNV(GLbyte * pc);
 extern HIDDEN void __glXDisp_VertexAttrib4fvARB(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_VertexAttrib4fvARB(GLbyte * pc);
+extern HIDDEN int __glXDisp_CreateGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDispSwap_CreateGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN void __glXDisp_MultiTexCoord1svARB(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_MultiTexCoord1svARB(GLbyte * pc);
 extern HIDDEN void __glXDisp_EndQueryARB(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_EndQueryARB(GLbyte * pc);
 extern HIDDEN void __glXDisp_DepthMask(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_DepthMask(GLbyte * pc);
-extern HIDDEN void __glXDisp_Rotated(GLbyte * pc);
-extern HIDDEN void __glXDispSwap_Rotated(GLbyte * pc);
+extern HIDDEN void __glXDisp_Color4iv(GLbyte * pc);
+extern HIDDEN void __glXDispSwap_Color4iv(GLbyte * pc);
 extern HIDDEN int __glXDisp_GetMaterialiv(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN int __glXDispSwap_GetMaterialiv(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN void __glXDisp_StencilOp(GLbyte * pc);
@@ -619,8 +623,8 @@ extern HIDDEN int __glXDisp_PixelStorei(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN int __glXDispSwap_PixelStorei(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN void __glXDisp_VertexAttrib4usvARB(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_VertexAttrib4usvARB(GLbyte * pc);
-extern HIDDEN void __glXDisp_Color4iv(GLbyte * pc);
-extern HIDDEN void __glXDispSwap_Color4iv(GLbyte * pc);
+extern HIDDEN int __glXDisp_DestroyGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDispSwap_DestroyGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN void __glXDisp_EvalCoord2dv(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_EvalCoord2dv(GLbyte * pc);
 extern HIDDEN void __glXDisp_VertexAttrib3svARB(GLbyte * pc);
@@ -669,6 +673,8 @@ extern HIDDEN void __glXDisp_Lighti(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_Lighti(GLbyte * pc);
 extern HIDDEN int __glXDisp_GetFramebufferAttachmentParameterivEXT(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN int __glXDispSwap_GetFramebufferAttachmentParameterivEXT(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDisp_ChangeDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *);
+extern HIDDEN int __glXDispSwap_ChangeDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *);
 extern HIDDEN void __glXDisp_MultiTexCoord4dvARB(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_MultiTexCoord4dvARB(GLbyte * pc);
 extern HIDDEN int __glXDisp_CreatePbuffer(struct __GLXclientStateRec *, GLbyte *);
@@ -751,8 +757,8 @@ extern HIDDEN void __glXDisp_PixelTransferf(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_PixelTransferf(GLbyte * pc);
 extern HIDDEN void __glXDisp_CopyTexImage1D(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_CopyTexImage1D(GLbyte * pc);
-extern HIDDEN void __glXDisp_PushMatrix(GLbyte * pc);
-extern HIDDEN void __glXDispSwap_PushMatrix(GLbyte * pc);
+extern HIDDEN void __glXDisp_RasterPos2dv(GLbyte * pc);
+extern HIDDEN void __glXDispSwap_RasterPos2dv(GLbyte * pc);
 extern HIDDEN void __glXDisp_Fogiv(GLbyte * pc);
 extern HIDDEN void __glXDispSwap_Fogiv(GLbyte * pc);
 extern HIDDEN void __glXDisp_TexCoord1dv(GLbyte * pc);
diff --git a/GL/glx/indirect_size_get.c b/GL/glx/indirect_size_get.c
index f29ae47..9285714 100644
--- a/GL/glx/indirect_size_get.c
+++ b/GL/glx/indirect_size_get.c
@@ -697,6 +697,7 @@ __glGetBooleanv_size(GLenum e)
     case GL_MATRIX_INDEX_ARRAY_SIZE_ARB:
     case GL_MATRIX_INDEX_ARRAY_TYPE_ARB:
     case GL_MATRIX_INDEX_ARRAY_STRIDE_ARB:
+    case GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT:
     case GL_POINT_SPRITE_ARB:
 /*      case GL_POINT_SPRITE_NV:*/
     case GL_POINT_SPRITE_R_MODE_NV:
@@ -704,8 +705,11 @@ __glGetBooleanv_size(GLenum e)
     case GL_MAX_TEXTURE_COORDS_ARB:
     case GL_MAX_TEXTURE_IMAGE_UNITS_ARB:
     case GL_DEPTH_BOUNDS_TEST_EXT:
+    case GL_MAX_ARRAY_TEXTURE_LAYERS_EXT:
     case GL_STENCIL_TEST_TWO_SIDE_EXT:
     case GL_ACTIVE_STENCIL_FACE_EXT:
+    case GL_TEXTURE_BINDING_1D_ARRAY_EXT:
+    case GL_TEXTURE_BINDING_2D_ARRAY_EXT:
     case GL_RASTER_POSITION_UNCLIPPED_IBM:
         return 1;
     case GL_SMOOTH_POINT_SIZE_RANGE:
diff --git a/GL/glx/indirect_table.c b/GL/glx/indirect_table.c
index 9d0383c..3da1f43 100644
--- a/GL/glx/indirect_table.c
+++ b/GL/glx/indirect_table.c
@@ -1575,9 +1575,9 @@ static const void *VendorPriv_function_table[104][2] = {
     /* [ 92] = 65540 */ {__glXDisp_GetFBConfigsSGIX, __glXDispSwap_GetFBConfigsSGIX},
     /* [ 93] = 65541 */ {__glXDisp_CreateContextWithConfigSGIX, __glXDispSwap_CreateContextWithConfigSGIX},
     /* [ 94] = 65542 */ {__glXDisp_CreateGLXPixmapWithConfigSGIX, __glXDispSwap_CreateGLXPixmapWithConfigSGIX},
-    /* [ 95] = 65543 */ {NULL, NULL},
-    /* [ 96] = 65544 */ {NULL, NULL},
-    /* [ 97] = 65545 */ {NULL, NULL},
+    /* [ 95] = 65543 */ {__glXDisp_CreateGLXPbufferSGIX, __glXDispSwap_CreateGLXPbufferSGIX},
+    /* [ 96] = 65544 */ {__glXDisp_DestroyGLXPbufferSGIX, __glXDispSwap_DestroyGLXPbufferSGIX},
+    /* [ 97] = 65545 */ {__glXDisp_ChangeDrawableAttributesSGIX, __glXDispSwap_ChangeDrawableAttributesSGIX},
     /* [ 98] = 65546 */ {__glXDisp_GetDrawableAttributesSGIX, __glXDispSwap_GetDrawableAttributesSGIX},
     /* [ 99] = 65547 */ {NULL, NULL},
     /* [ 100] = 65548 */ {NULL, NULL},
commit d7ded953c4d263e3dd3374dc03eea19e80c05bc6
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Thu Aug 23 19:07:52 2007 -0400

    Implment GLXPixmaps.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 732b135..bf6d6e2 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -425,108 +425,79 @@ int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
  *
  * \param glxc      Associated GLX context.
  * \param drawId    ID of the drawable.
- * \param ppDraw    Location to store the pointer to the drawable.
- * \param ppPixmap  Location to store the pointer to the pixmap.
  * \param client    Pointer to the client state.
- * \return  Zero is returned on success.  Otherwise a GLX / X11 protocol error
- *          is returned.
+ * \return  the __GLXdrawable is returned on success.  Otherwise NULL.
  * 
  * \notes This function will need some modification when support pbuffers
  *        is added.
  */
-static int GetDrawableOrPixmap( __GLXcontext *glxc, GLXDrawable drawId,
-				__GLXdrawable **ppGlxDraw,
-				__GLXpixmap **ppPixmap,
-				ClientPtr client )
+static __GLXdrawable *
+__glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
+		 int *error)
 {
     DrawablePtr pDraw;
     __GLcontextModes *modes;
     __GLXdrawable *pGlxDraw;
-    __GLXpixmap *drawPixmap = NULL;
+    VisualID vid;
     int rc;
 
-    /* This is the GLX 1.3 case - the client passes in a GLXWindow and
-     * we just return the __GLXdrawable.  The first time a GLXPixmap
-     * comes in, it doesn't have a corresponding __GLXdrawable, so it
-     * falls through to the else-case below, but after that it'll have
-     * a __GLXdrawable and we'll handle it here. */
+    /* This is the GLX 1.3 case - the client passes in a GLXWindow or
+     * GLXPixmap and we just return the __GLXdrawable.  */
     pGlxDraw = (__GLXdrawable *) LookupIDByType(drawId, __glXDrawableRes);
     if (pGlxDraw != NULL) {
 	if (glxc != NULL && pGlxDraw->modes != glxc->modes) {
 	    client->errorValue = drawId;
-	    return BadMatch;
+	    *error = BadMatch;
+	    return NULL;
 	}
 
-	*ppGlxDraw = pGlxDraw;
-	*ppPixmap = pGlxDraw->pGlxPixmap;
-	return Success;
+	return pGlxDraw;
     }
 
-    /* The drawId wasn't a GLXWindow, so presumably it's a regular X
-     * window.  In that case, we create a shadow GLXWindow for it on
+    /* The drawId wasn't a GLX drawable, so presumably it's a regular
+     * X window.  In that case, we create a shadow GLXWindow for it on
      * demand here for pre GLX 1.3 compatibility and use the X Window
      * XID as its GLXWindow XID.  The client can't explicitly create a
      * GLXWindow with the same XID as an X Window, so we wont get any
      * resource ID clashes.  Effectively, the X Window is now also a
      * GLXWindow. */
-    rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
-    if (rc == Success) {
-	if (pDraw->type == DRAWABLE_WINDOW) {
-	    VisualID vid = wVisual((WindowPtr)pDraw);
 
-	    modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes,
-						  vid);
-	} else {
-	    /*
-	    ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
-	    ** is, but it must first be created with glxCreateGLXPixmap).
-	    */
-	    client->errorValue = drawId;
-	    return __glXError(GLXBadDrawable);
-	}
-    } else {
-	drawPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes);
-	if (drawPixmap) {
-	    pDraw = drawPixmap->pDraw;
-	    modes = drawPixmap->modes;
-	} else {
-	    /*
-	    ** Drawable is neither a Window nor a GLXPixmap.
-	    */
-	    client->errorValue = drawId;
-	    return __glXError(GLXBadDrawable);
-	}
+    rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
+    if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
+	client->errorValue = drawId;
+	*error = __glXError(GLXBadDrawable);
+	return NULL;
     }
 
     /* If we're not given a context, don't create the __GLXdrawable */
     if (glxc == NULL) {
-	*ppPixmap = NULL;
-	*ppGlxDraw = NULL;
-	return Success;
+	*error = __glXError(GLXBadDrawable);
+	return NULL;
     }
 
-    /* We're binding an X Window or a GLX Pixmap for the first time
-     * and need to create a GLX drawable for it.  First check that the
-     * drawable screen and fbconfig matches the context ditto. */
+    vid = wVisual((WindowPtr)pDraw);
+    modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes, vid);
+
+    /* We're binding an X Window for the first time and need to create
+     * a GLX drawable for it.  First check that the drawable screen
+     * and fbconfig matches the context ditto. */
     if (pDraw->pScreen != glxc->pScreen || modes != glxc->modes) {
 	client->errorValue = drawId;
-	return BadMatch;
+	*error = BadMatch;
+	return NULL;
     }
 
-    pGlxDraw =
-	glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
-					 pDraw, drawId, modes);
+    pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
+						pDraw, drawId, modes);
 
     /* since we are creating the drawablePrivate, drawId should be new */
     if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
 	pGlxDraw->destroy (pGlxDraw);
-	return BadAlloc;
+	*error = BadAlloc;
+	return NULL;
     }
 
-    *ppPixmap = drawPixmap;
-    *ppGlxDraw = pGlxDraw;
-
-    return 0;
+    return pGlxDraw;
 }
 
 
@@ -536,8 +507,6 @@ int DoMakeCurrent( __GLXclientState *cl,
 {
     ClientPtr client = cl->client;
     xGLXMakeCurrentReply reply;
-    __GLXpixmap *drawPixmap = NULL;
-    __GLXpixmap *readPixmap = NULL;
     __GLXcontext *glxc, *prevglxc;
     __GLXdrawable *drawPriv = NULL;
     __GLXdrawable *readPriv = NULL;
@@ -595,21 +564,13 @@ int DoMakeCurrent( __GLXclientState *cl,
 	assert( drawId != None );
 	assert( readId != None );
 
-	status = GetDrawableOrPixmap(glxc, drawId, &drawPriv, &drawPixmap,
-				     client);
-	if ( status != 0 ) {
+	drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
+	if (drawPriv == NULL)
 	    return status;
-	}
 
-	if ( readId != drawId ) {
-	    status = GetDrawableOrPixmap(glxc, readId, &readPriv, &readPixmap,
-					 client);
-	    if ( status != 0 ) {
-		return status;
-	    }
-	} else {
-	    readPriv = drawPriv;
-	}
+	readPriv = __glXGetDrawable(glxc, readId, client, &status);
+	if (readPriv == NULL)
+	    return status;
 
     } else {
 	/* Switching to no context.  Ignore new drawable. */
@@ -671,42 +632,6 @@ int DoMakeCurrent( __GLXclientState *cl,
     }
 
     if (prevglxc) {
-	if (prevglxc->drawPixmap) {
-	    if (prevglxc->readPixmap &&
-		prevglxc->drawPixmap != prevglxc->readPixmap) {
-		/*
-		** The previous drawable was a glx pixmap, release it.
-		*/
-		prevglxc->readPixmap->refcnt--;
-		if (!prevglxc->readPixmap->idExists &&
-		    !prevglxc->readPixmap->refcnt) {
-		    PixmapPtr pPixmap = (PixmapPtr) prevglxc->readPixmap->pDraw;
-		    /*
-		    ** The DestroyPixmap routine should decrement the
-		    ** refcount of the X pixmap and free only if it's zero.
-		    */
-		    (*prevglxc->readPixmap->pScreen->DestroyPixmap)(pPixmap);
-		    xfree(prevglxc->readPixmap);
-		}
-	    }
-
-	    /*
-	    ** The previous drawable was a glx pixmap, release it.
-	    */
-	    prevglxc->drawPixmap->refcnt--;
-	    if (!prevglxc->drawPixmap->idExists &&
-		!prevglxc->drawPixmap->refcnt) {
-		PixmapPtr pPixmap = (PixmapPtr) prevglxc->drawPixmap->pDraw;
-		/*
-		** The DestroyPixmap routine should decrement the
-		** refcount of the X pixmap and free only if it's zero.
-		*/
-		(*prevglxc->drawPixmap->pScreen->DestroyPixmap)(pPixmap);
-		xfree(prevglxc->drawPixmap);
-	    }
-
-	    prevglxc->drawPixmap = NULL;
-	}
 	ChangeCurrentContext(cl, glxc, tag);
 	StopUsingContext(prevglxc);
     } else {
@@ -714,16 +639,6 @@ int DoMakeCurrent( __GLXclientState *cl,
     }
 
     if (glxc) {
-	if (drawPixmap) {
-	    drawPixmap->refcnt++;
-	    glxc->drawPixmap = drawPixmap;
-	}
-
-	if (readPixmap && (readPixmap != drawPixmap)) {
-	    readPixmap->refcnt++;
-	    glxc->readPixmap = readPixmap;
-	}
-
 	StartUsingContext(cl, glxc);
 	reply.contextTag = tag;
     } else {
@@ -1210,31 +1125,30 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
     return DoGetFBConfigs( cl, req->screen, GL_FALSE );
 }
 
-static int ValidateCreateDrawable(ClientPtr client,
-				  int screenNum, XID fbconfigId,
-				  XID drawablId, XID glxDrawableId,
-				  int type, __GLcontextModes **modes,
-				  DrawablePtr *ppDraw)
+static int 
+DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
+		    XID drawableId, XID glxDrawableId, int type)
 {
     DrawablePtr pDraw;
     ScreenPtr pScreen;
     VisualPtr pVisual;
     __GLXscreen *pGlxScreen;
+    __GLXdrawable *pGlxDraw;
+    __GLcontextModes *modes;
     int i, rc;
 
     LEGAL_NEW_RESOURCE(glxDrawableId, client);
 
-    rc = dixLookupDrawable(&pDraw, drawablId, client, 0, DixUnknownAccess);
+    rc = dixLookupDrawable(&pDraw, drawableId, client, 0, DixUnknownAccess);
     if (rc != Success || pDraw->type != type) {
-	client->errorValue = drawablId;
+	client->errorValue = drawableId;
 	return type == DRAWABLE_WINDOW ? BadWindow : BadPixmap;
     }
 
     /* Check if screen of the fbconfig matches screen of drawable. */
     pScreen = pDraw->pScreen;
-    if (screenNum != pScreen->myNum) {
+    if (screenNum != pScreen->myNum)
 	return BadMatch;
-    }
 
     /* If this fbconfig has a corresponding VisualRec the number of
      * planes must match the drawable depth. */
@@ -1246,55 +1160,39 @@ static int ValidateCreateDrawable(ClientPtr client,
 
     /* Get configuration of the visual. */
     pGlxScreen = glxGetScreen(pScreen);
-    *modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId);
-    if (*modes == NULL) {
+    modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId);
+    if (modes == NULL) {
 	/* Visual not support on this screen by this OpenGL implementation. */
 	client->errorValue = fbconfigId;
 	return BadValue;
     }
 
-    *ppDraw = pDraw;
+    /* FIXME: We need to check that the window visual is compatible
+     * with the specified fbconfig. */
+    pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw,
+					  glxDrawableId, modes);
+    if (pGlxDraw == NULL)
+	return BadAlloc;
+
+    if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) {
+	pGlxDraw->destroy (pGlxDraw);
+	return BadAlloc;
+    }
+
+    if (type == DRAWABLE_PIXMAP)
+	((PixmapPtr) pDraw)->refcnt++;
 
     return Success;
 }
 
-/*
-** Create a GLX Pixmap from an X Pixmap.
-*/
-int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
-		      GLuint screenNum, XID pixmapId, XID glxPixmapId,
-		      CARD32 *attribs, CARD32 numAttribs)
+static void
+determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs)
 {
-    ClientPtr client = cl->client;
-    DrawablePtr pDraw;
-    __GLXpixmap *pGlxPixmap;
-    __GLcontextModes *modes;
     GLenum target = 0;
-    int retval, i;
-
-    retval = ValidateCreateDrawable (client, screenNum, fbconfigId,
-				     pixmapId, glxPixmapId,
-				     DRAWABLE_PIXMAP, &modes, &pDraw);
-    if (retval != Success)
-	return retval;
-
-    pGlxPixmap = (__GLXpixmap *) xalloc(sizeof(__GLXpixmap));
-    if (!pGlxPixmap) {
-	return BadAlloc;
-    }
-    if (!(AddResource(glxPixmapId, __glXPixmapRes, pGlxPixmap))) {
-	return BadAlloc;
-    }
-    pGlxPixmap->pDraw = pDraw;
-    pGlxPixmap->pGlxScreen = glxGetScreen(pDraw->pScreen);
-    pGlxPixmap->pScreen = pDraw->pScreen;
-    pGlxPixmap->idExists = True;
-#ifdef XF86DRI
-    pGlxPixmap->pDamage = NULL;
-#endif
-    pGlxPixmap->refcnt = 0;
+    int i;
+    __GLXdrawable *pGlxDraw;
 
-    pGlxPixmap->modes = modes;
+    pGlxDraw = LookupIDByType(glxDrawableID, __glXDrawableRes);
 
     for (i = 0; i < numAttribs; i++) {
 	if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
@@ -1308,63 +1206,69 @@ int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
 	    }
 	}
     }
-
+ 
     if (!target) {
-	int w = pDraw->width, h = pDraw->height;
-
+	int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
+	
 	if (h & (h - 1) || w & (w - 1))
 	    target = GL_TEXTURE_RECTANGLE_ARB;
 	else
 	    target = GL_TEXTURE_2D;
     }
 
-    pGlxPixmap->target = target;
-
-    /*
-    ** Bump the ref count on the X pixmap so it won't disappear.
-    */
-    ((PixmapPtr) pDraw)->refcnt++;
-
-    return Success;
+    pGlxDraw->target = target;
 }
 
 int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
-    return DoCreateGLXPixmap( cl, req->visual, req->screen,
-			      req->pixmap, req->glxpixmap, NULL, 0 );
+
+    return DoCreateGLXDrawable(cl->client, req->screen, req->visual,
+			       req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
 }
 
 int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
-    return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
-			      req->pixmap, req->glxpixmap,
-			      (CARD32*)(req + 1),
-			      req->numAttribs );
+    int err;
+
+    err = DoCreateGLXDrawable(cl->client, req->screen, req->fbconfig,
+			      req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
+    if (err != Success)
+	return err;
+
+    determineTextureTarget(req->glxpixmap,
+			   (CARD32*) (req + 1), req->numAttribs);
+
+    return Success;
 }
 
 int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateGLXPixmapWithConfigSGIXReq *req = 
 	(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
-    return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
-			      req->pixmap, req->glxpixmap, NULL, 0 );
+
+    return DoCreateGLXDrawable(cl->client, req->screen, req->fbconfig,
+			       req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
 }
 
 
-int DoDestroyPixmap(__GLXclientState *cl, XID glxpixmap)
+static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
 {
     ClientPtr client = cl->client;
+    __GLXdrawable *pGlxDraw;
+    int error;
 
     /*
-    ** Check if it's a valid GLX pixmap.
+    ** Check it's the right type of drawable.
     */
-    if (!LookupIDByType(glxpixmap, __glXPixmapRes)) {
-	client->errorValue = glxpixmap;
-	return __glXError(GLXBadPixmap);
+    pGlxDraw = LookupIDByType(glxdrawable, __glXDrawableRes);
+    if (pGlxDraw == NULL || pGlxDraw->type != type) {
+	client->errorValue = glxdrawable;
+	error = type == DRAWABLE_WINDOW ? GLXBadWindow : GLXBadDrawable;
+	return __glXError(error);
     }
-    FreeResource(glxpixmap, FALSE);
+    FreeResource(glxdrawable, FALSE);
 
     return Success;
 }
@@ -1373,14 +1277,14 @@ int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
 
-    return DoDestroyPixmap(cl, req->glxpixmap);
+    return DoDestroyDrawable(cl, req->glxpixmap, DRAWABLE_PIXMAP);
 }
 
 int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
 
-    return DoDestroyPixmap(cl, req->glxpixmap);
+    return DoDestroyDrawable(cl, req->glxpixmap, DRAWABLE_PIXMAP);
 }
 
 int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
@@ -1415,49 +1319,16 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
     ClientPtr client = cl->client;
-    DrawablePtr pDraw;
-    __GLXdrawable *glxPriv;
-    __GLXscreen *screen;
-    __GLcontextModes *modes;
-    int retval;
-
-    retval = ValidateCreateDrawable (client, req->screen, req->fbconfig,
-				     req->window, req->glxwindow,
-				     DRAWABLE_WINDOW, &modes, &pDraw);
-    if (retval != Success)
-	return retval;
-
-    /* FIXME: We need to check that the window visual is compatible
-     * with the specified fbconfig. */
-
-    screen = glxGetScreen(screenInfo.screens[req->screen]);
-    glxPriv = screen->createDrawable(screen, pDraw, req->glxwindow, modes);
-    if (glxPriv == NULL)
-	return BadAlloc;
-
-    if (!AddResource(req->glxwindow, __glXDrawableRes, glxPriv)) {
-	glxPriv->destroy (glxPriv);
-	return BadAlloc;
-    }
 
-    return Success;
+    return DoCreateGLXDrawable(client, req->screen, req->fbconfig,
+			       req->window, req->glxwindow, DRAWABLE_WINDOW);
 }
 
 int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
-    ClientPtr client = cl->client;
 
-    /*
-    ** Check if it's a valid GLX window.
-    */
-    if (!LookupIDByType(req->glxwindow, __glXDrawableRes)) {
-	client->errorValue = req->glxwindow;
-	return __glXError(GLXBadWindow);
-    }
-    FreeResource(req->glxwindow, FALSE);
-
-    return Success;
+    return DoDestroyDrawable(cl, req->glxwindow, DRAWABLE_WINDOW);
 }
 
 
@@ -1476,7 +1347,6 @@ int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
     XID drawId = req->drawable;
     __GLXcontext *glxc = NULL;
     __GLXdrawable *pGlxDraw;
-    __GLXpixmap *pPixmap;
     int error;
 
     if (tag) {
@@ -1501,11 +1371,11 @@ int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
 	}
     }
 
-    error = GetDrawableOrPixmap(glxc, drawId, &pGlxDraw, &pPixmap, client);
-    if (error != Success)
+    pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
+    if (pGlxDraw == NULL)
 	return error;
 
-    if (pGlxDraw != NULL && pGlxDraw->type == DRAWABLE_WINDOW &&
+    if (pGlxDraw->type == DRAWABLE_WINDOW &&
 	(*pGlxDraw->swapBuffers)(pGlxDraw) == GL_FALSE)
 	return __glXError(GLXBadDrawable);
 
@@ -1576,8 +1446,8 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
     ClientPtr		 client = cl->client;
-    __GLXpixmap		*pGlxPixmap;
     __GLXcontext	*context;
+    __GLXdrawable	*pGlxDraw;
     GLXDrawable		 drawId;
     int			 buffer;
     int			 error;
@@ -1594,8 +1464,8 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
     if (!context)
 	return error;
 
-    pGlxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes);
-    if (!pGlxPixmap) {
+    pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
+    if (!pGlxDraw || pGlxDraw->type != DRAWABLE_PIXMAP) {
 	client->errorValue = drawId;
 	return __glXError(GLXBadPixmap);
     }
@@ -1605,14 +1475,14 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 
     return context->textureFromPixmap->bindTexImage(context,
 						    buffer,
-						    pGlxPixmap);
+						    pGlxDraw);
 }
 
 int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
     ClientPtr		 client = cl->client;
-    __GLXpixmap		*pGlxPixmap;
+    __GLXdrawable	*pGlxDraw;
     __GLXcontext	*context;
     GLXDrawable		 drawId;
     int			 buffer;
@@ -1627,10 +1497,10 @@ int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
     if (!context)
 	return error;
 
-    pGlxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes);
-    if (!pGlxPixmap) {
+    pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
+    if (error != Success || pGlxDraw->type != DRAWABLE_PIXMAP) {
 	client->errorValue = drawId;
-	return __glXError(GLXBadDrawable);
+	return error;
     }
 
     if (!context->textureFromPixmap)
@@ -1638,7 +1508,7 @@ int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 
     return context->textureFromPixmap->releaseTexImage(context,
 						       buffer,
-						       pGlxPixmap);
+						       pGlxDraw);
 }
 
 int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
@@ -1647,7 +1517,6 @@ int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
     GLXContextTag         tag = req->contextTag;
     __GLXcontext         *glxc = NULL;
     __GLXdrawable        *pGlxDraw;
-    __GLXpixmap          *pPixmap;
     ClientPtr		  client = cl->client;
     GLXDrawable		  drawId;
     int                   error;
@@ -1686,7 +1555,7 @@ int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
 	}
     }
 
-    error = GetDrawableOrPixmap(glxc, drawId, &pGlxDraw, &pPixmap, client);
+    pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
     if (error != Success)
 	return error;
 
@@ -1707,15 +1576,15 @@ static int
 DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
 {
     ClientPtr client = cl->client;
-    __GLXpixmap *glxPixmap;
     xGLXGetDrawableAttributesReply reply;
+    __GLXdrawable *pGlxDraw;
     CARD32 attributes[4];
-    int numAttribs;
+    int numAttribs, error;
 
-    glxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes);
-    if (!glxPixmap) {
+    pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
+    if (!pGlxDraw) {
 	client->errorValue = drawId;
-	return __glXError(GLXBadPixmap);
+	return error;
     }
 
     numAttribs = 2;
@@ -1725,7 +1594,7 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
     reply.numAttribs = numAttribs;
 
     attributes[0] = GLX_TEXTURE_TARGET_EXT;
-    attributes[1] = glxPixmap->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
+    attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
 	GLX_TEXTURE_RECTANGLE_EXT;
     attributes[2] = GLX_Y_INVERTED_EXT;
     attributes[3] = GL_FALSE;
diff --git a/GL/glx/glxcontext.h b/GL/glx/glxcontext.h
index eb10ee2..7122647 100644
--- a/GL/glx/glxcontext.h
+++ b/GL/glx/glxcontext.h
@@ -44,12 +44,12 @@
 
 typedef struct __GLXtextureFromPixmap __GLXtextureFromPixmap;
 struct __GLXtextureFromPixmap {
-    int (*bindTexImage)		(__GLXcontext *baseContext,
-				 int           buffer,
-				 __GLXpixmap  *pixmap);
-    int (*releaseTexImage)	(__GLXcontext *baseContext,
-				 int           buffer,
-				 __GLXpixmap  *pixmap);
+    int (*bindTexImage)		(__GLXcontext  *baseContext,
+				 int            buffer,
+				 __GLXdrawable *pixmap);
+    int (*releaseTexImage)	(__GLXcontext  *baseContext,
+				 int            buffer,
+				 __GLXdrawable *pixmap);
 };
 
 
@@ -152,12 +152,6 @@ struct __GLXcontext {
     GLint selectBufSize;	/* number of elements allocated */
 
     /*
-    ** Set only if current drawable is a glx pixmap.
-    */
-    __GLXpixmap *drawPixmap;
-    __GLXpixmap *readPixmap;
-
-    /*
     ** The drawable private this context is bound to
     */
     __GLXdrawable *drawPriv;
diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h
index b7ecad9..5fdcf95 100644
--- a/GL/glx/glxdrawable.h
+++ b/GL/glx/glxdrawable.h
@@ -46,23 +46,6 @@
 #include <GL/internal/dri_interface.h>
 #endif
 
-typedef struct {
-
-    DrawablePtr pDraw;
-    __GLcontextModes *modes;
-    __GLXscreen *pGlxScreen;
-    ScreenPtr pScreen;
-    Bool idExists;
-    int refcnt;
-    GLenum target;
-#ifdef XF86DRI
-    DamagePtr pDamage;
-    __DRIcontext *pDRICtx;
-    GLint texname;
-    unsigned long offset;
-#endif
-} __GLXpixmap;
-
 struct __GLXdrawable {
     void (*destroy)(__GLXdrawable *private);
     GLboolean (*resize)(__GLXdrawable *private);
@@ -78,7 +61,6 @@ struct __GLXdrawable {
 
     DrawablePtr pDraw;
     XID drawId;
-    __GLXpixmap *pGlxPixmap;
 
     /*
     ** Either DRAWABLE_PIXMAP or DRAWABLE_WINDOW, copied from pDraw above.
@@ -105,6 +87,8 @@ struct __GLXdrawable {
     ** reference count
     */
     int refCount;
+
+    GLenum target;
 };
 
 #endif /* !__GLX_drawable_h__ */
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index ae74311..3394e58 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -59,6 +59,9 @@
 #include "dispatch.h"
 #include "extension_string.h"
 
+#define containerOf(ptr, type, member)			\
+    (type *)( (char *)ptr - offsetof(type,member) )
+
 typedef struct __GLXDRIscreen   __GLXDRIscreen;
 typedef struct __GLXDRIcontext  __GLXDRIcontext;
 typedef struct __GLXDRIdrawable __GLXDRIdrawable;
@@ -73,12 +76,14 @@ struct __GLXDRIscreen {
 
     __DRIcopySubBufferExtension *copySubBuffer;
     __DRIswapControlExtension *swapControl;
-    __DRItexOffsetExtension *texOffset;
 
+#ifdef __DRI_TEX_OFFSET
+    __DRItexOffsetExtension *texOffset;
     DRITexOffsetStartProcPtr texOffsetStart;
     DRITexOffsetFinishProcPtr texOffsetFinish;
-    __GLXpixmap* texOffsetOverride[16];
+    __GLXDRIdrawable *texOffsetOverride[16];
     GLuint lastTexOffsetOverride;
+#endif
 
     unsigned char glx_enable_bits[__GLX_EXT_BYTES];
 };
@@ -92,6 +97,14 @@ struct __GLXDRIcontext {
 struct __GLXDRIdrawable {
     __GLXdrawable base;
     __DRIdrawable driDrawable;
+
+    /* Pulled in from old __GLXpixmap */
+#ifdef __DRI_TEX_OFFSET
+    GLint texname;
+    __GLXDRIcontext *ctx;
+    unsigned long offset;
+    DamagePtr pDamage;
+#endif
 };
 
 static const char CREATE_NEW_SCREEN_FUNC[] = __DRI_CREATE_NEW_SCREEN_STRING;
@@ -107,15 +120,15 @@ __glXDRIleaveServer(GLboolean rendering)
 	GLuint lastOverride = screen->lastTexOffsetOverride;
 
 	if (lastOverride) {
-	    __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+	    __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
 	    int j;
 
 	    for (j = 0; j < lastOverride; j++) {
-		__GLXpixmap *pGlxPix = texOffsetOverride[j];
+		__GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
 
 		if (pGlxPix && pGlxPix->texname) {
 		    pGlxPix->offset =
-			screen->texOffsetStart((PixmapPtr)pGlxPix->pDraw);
+			screen->texOffsetStart((PixmapPtr)pGlxPix->base.pDraw);
 		}
 	    }
 	}
@@ -129,18 +142,18 @@ __glXDRIleaveServer(GLboolean rendering)
 	GLuint lastOverride = screen->lastTexOffsetOverride;
 
 	if (lastOverride) {
-	    __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+	    __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
 	    int j;
 
 	    for (j = 0; j < lastOverride; j++) {
-		__GLXpixmap *pGlxPix = texOffsetOverride[j];
+		__GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
 
 		if (pGlxPix && pGlxPix->texname) {
-		    screen->texOffset->setTexOffset(pGlxPix->pDRICtx,
+		    screen->texOffset->setTexOffset(&pGlxPix->ctx->driContext,
 						    pGlxPix->texname,
 						    pGlxPix->offset,
-						    pGlxPix->pDraw->depth,
-						    ((PixmapPtr)pGlxPix->pDraw)->devKind);
+						    pGlxPix->base.pDraw->depth,
+						    ((PixmapPtr)pGlxPix->base.pDraw)->devKind);
 		}
 	    }
 	}
@@ -321,14 +334,17 @@ glxFillAlphaChannel (PixmapPtr pixmap, int x, int y, int width, int height)
 static int
 __glXDRIbindTexImage(__GLXcontext *baseContext,
 		     int buffer,
-		     __GLXpixmap *glxPixmap)
+		     __GLXdrawable *glxPixmap)
 {
     RegionPtr	pRegion = NULL;
     PixmapPtr	pixmap;
     int		bpp, override = 0, texname;
     GLenum	format, type;
-    ScreenPtr pScreen = glxPixmap->pScreen;
-    __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen);
+    ScreenPtr pScreen = glxPixmap->pDraw->pScreen;
+    __GLXDRIdrawable *driDraw =
+	    containerOf(glxPixmap, __GLXDRIdrawable, base);
+    __GLXDRIscreen * const screen =
+	    (__GLXDRIscreen *) glxGetScreen(pScreen);
 
     CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
 				      GL_TEXTURE_BINDING_2D :
@@ -341,11 +357,11 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
     pixmap = (PixmapPtr) glxPixmap->pDraw;
 
     if (screen->texOffsetStart && screen->texOffset) {
-	__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+	__GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
 	int i, firstEmpty = 16;
 
 	for (i = 0; i < 16; i++) {
-	    if (texOffsetOverride[i] == glxPixmap)
+	    if (texOffsetOverride[i] == driDraw)
 		goto alreadyin; 
 
 	    if (firstEmpty == 16 && !texOffsetOverride[i])
@@ -360,37 +376,37 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
 	if (firstEmpty >= screen->lastTexOffsetOverride)
 	    screen->lastTexOffsetOverride = firstEmpty + 1;
 
-	texOffsetOverride[firstEmpty] = glxPixmap;
+	texOffsetOverride[firstEmpty] = driDraw;
 
 alreadyin:
 	override = 1;
 
-	glxPixmap->pDRICtx = &((__GLXDRIcontext*)baseContext)->driContext;
+	driDraw->ctx = (__GLXDRIcontext*)baseContext;
 
-	if (texname == glxPixmap->texname)
+	if (texname == driDraw->texname)
 	    return Success;
 
-	glxPixmap->texname = texname;
+	driDraw->texname = texname;
 
-	screen->texOffset->setTexOffset(glxPixmap->pDRICtx, texname, 0,
+	screen->texOffset->setTexOffset(&driDraw->ctx->driContext, texname, 0,
 					pixmap->drawable.depth,
 					pixmap->devKind);
     }
 nooverride:
 
-    if (!glxPixmap->pDamage) {
+    if (!driDraw->pDamage) {
 	if (!override) {
-	    glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
-					      TRUE, pScreen, NULL);
-	    if (!glxPixmap->pDamage)
+	    driDraw->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
+					    TRUE, pScreen, NULL);
+	    if (!driDraw->pDamage)
 		return BadAlloc;
 
-	    DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
+	    DamageRegister ((DrawablePtr) pixmap, driDraw->pDamage);
 	}
 
 	pRegion = NULL;
     } else {
-	pRegion = DamageRegion(glxPixmap->pDamage);
+	pRegion = DamageRegion(driDraw->pDamage);
 	if (REGION_NIL(pRegion))
 	    return Success;
     }
@@ -469,7 +485,7 @@ nooverride:
     }
 
     if (!override)
-	DamageEmpty(glxPixmap->pDamage);
+	DamageEmpty(driDraw->pDamage);
 
     return Success;
 }
@@ -477,19 +493,21 @@ nooverride:
 static int
 __glXDRIreleaseTexImage(__GLXcontext *baseContext,
 			int buffer,
-			__GLXpixmap *pixmap)
+			__GLXdrawable *pixmap)
 {
-    ScreenPtr pScreen = pixmap->pScreen;
+    ScreenPtr pScreen = pixmap->pDraw->pScreen;
+    __GLXDRIdrawable *driDraw =
+	    containerOf(pixmap, __GLXDRIdrawable, base);
     __GLXDRIscreen * const screen =
 	(__GLXDRIscreen *) glxGetScreen(pScreen);
     GLuint lastOverride = screen->lastTexOffsetOverride;
 
     if (lastOverride) {
-	__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+	__GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
 	int i;
 
 	for (i = 0; i < lastOverride; i++) {
-	    if (texOffsetOverride[i] == pixmap) {
+	    if (texOffsetOverride[i] == driDraw) {
 		if (screen->texOffsetFinish)
 		    screen->texOffsetFinish((PixmapPtr)pixmap->pDraw);
 
@@ -696,9 +714,6 @@ filter_modes(__GLcontextModes **server_modes,
 }
 
 
-#define containerOf(ptr, type, member)			\
-    (type *)( (char *)ptr - offsetof(type,member) )
-
 static GLboolean
 getDrawableInfo(__DRIdrawable *driDrawable,
 		unsigned int *index, unsigned int *stamp,
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index b5de8c3..94ec5cc 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -45,7 +45,6 @@ __GLXcontext *__glXLastContext;
 ** X resources.
 */
 RESTYPE __glXContextRes;
-RESTYPE __glXPixmapRes;
 RESTYPE __glXDrawableRes;
 RESTYPE __glXSwapBarrierRes;
 
@@ -102,32 +101,6 @@ static int ContextGone(__GLXcontext* cx, XID id)
 }
 
 /*
-** Free a GLX Pixmap.
-*/
-static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
-{
-    PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
-
-    pGlxPixmap->idExists = False;
-    if (!pGlxPixmap->refcnt) {
-#ifdef XF86DRI
-	if (pGlxPixmap->pDamage) {
-	    DamageUnregister (pGlxPixmap->pDraw, pGlxPixmap->pDamage);
-	    DamageDestroy(pGlxPixmap->pDamage);
-	}
-#endif
-	/*
-	** The DestroyPixmap routine should decrement the refcount and free
-	** only if it's zero.
-	*/
-	(*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
-	xfree(pGlxPixmap);
-    }
-
-    return True;
-}
-
-/*
 ** Destroy routine that gets called when a drawable is freed.  A drawable
 ** contains the ancillary buffers needed for rendering.
 */
@@ -136,24 +109,17 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
     __GLXcontext *cx, *cx1;
 
     /*
-    ** Use glxPriv->type to figure out what kind of drawable this is. Don't
-    ** use glxPriv->pDraw->type because by the time this routine is called,
-    ** the pDraw might already have been freed.
+    ** When a drawable is destroyed, notify all context bound to 
+    ** it, that there are no longer bound to anything.
     */
-    if (glxPriv->type == DRAWABLE_WINDOW) {
-	/*
-	** When a window is destroyed, notify all context bound to 
-	** it, that there are no longer bound to anything.
-	*/
-	for (cx = glxPriv->drawGlxc; cx; cx = cx1) {
-	    cx1 = cx->nextDrawPriv;
-	    cx->pendingState |= __GLX_PENDING_DESTROY;
-	}
+    for (cx = glxPriv->drawGlxc; cx; cx = cx1) {
+	cx1 = cx->nextDrawPriv;
+	cx->pendingState |= __GLX_PENDING_DESTROY;
+    }
 
-	for (cx = glxPriv->readGlxc; cx; cx = cx1) {
-	    cx1 = cx->nextReadPriv;
-	    cx->pendingState |= __GLX_PENDING_DESTROY;
-	}
+    for (cx = glxPriv->readGlxc; cx; cx = cx1) {
+	cx1 = cx->nextReadPriv;
+	cx->pendingState |= __GLX_PENDING_DESTROY;
     }
 
     __glXUnrefDrawable(glxPriv);
@@ -319,7 +285,6 @@ void GlxExtensionInit(void)
     __GLXprovider *p;
 
     __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
-    __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
     __glXDrawableRes = CreateNewResourceType((DeleteType)DrawableGone);
     __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
 
diff --git a/GL/glx/glxutil.c b/GL/glx/glxutil.c
index 1f17292..df1cb2a 100644
--- a/GL/glx/glxutil.c
+++ b/GL/glx/glxutil.c
@@ -148,9 +148,5 @@ __glXDrawableInit(__GLXdrawable *drawable,
     drawable->refCount = 1;
     drawable->modes = modes;
 
-    /* if not a pixmap, lookup will fail, so pGlxPixmap will be NULL */
-    drawable->pGlxPixmap = (__GLXpixmap *) 
-	LookupIDByType(drawId, __glXPixmapRes);
-
     return GL_TRUE;
 }
commit 2b0847c7aaf95b6b10f062dfff601032b2430a9b
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Wed Aug 8 10:07:03 2007 -0400

    Implement damage reporting for AIGLX.

diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index 6389ad9..ae74311 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -784,6 +784,22 @@ getUST(int64_t *ust)
     }
 }
 
+static void __glXReportDamage(__DRIdrawable *driDraw,
+			      int x, int y,
+			      drm_clip_rect_t *rects, int num_rects,
+			      GLboolean front_buffer)
+{
+    __GLXDRIdrawable *drawable =
+	    containerOf(driDraw, __GLXDRIdrawable, driDrawable);
+    DrawablePtr pDraw = drawable->base.pDraw;
+    RegionRec region;
+
+    REGION_INIT(pDraw->pScreen, &region, (BoxPtr) rects, num_rects);
+    REGION_TRANSLATE(pScreen, &region, pDraw->x, pDraw->y);
+    DamageDamageRegion(pDraw, &region);
+    REGION_UNINIT(pDraw->pScreen, &region);
+}
+
 /* Table of functions that we export to the driver. */
 static const __DRIinterfaceMethods interface_methods = {
     _gl_context_modes_create,
@@ -793,6 +809,8 @@ static const __DRIinterfaceMethods interface_methods = {
 
     getUST,
     NULL, /* glXGetMscRateOML, */
+
+    __glXReportDamage,
 };
 
 static const char dri_driver_path[] = DRI_DRIVER_PATH;
commit 600028305cc047e824b18369a026f89c9eb7e437
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Thu May 31 22:55:47 2007 -0400

    Move hyperpipe and swapbarrier extension funcs to screen private struct.
    
    This gets rid of a couple more global arrays and gets the two extensions
    more in line with the general extension mechanism.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index e09290e..732b135 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -2088,13 +2088,14 @@ int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
     int barrier = req->barrier;
     DrawablePtr pDraw;
     int screen, rc;
+    __GLXscreen *pGlxScreen;
 
     rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixUnknownAccess);
+    pGlxScreen = glxGetScreen(pDraw->pScreen);
     if (rc == Success && (pDraw->type == DRAWABLE_WINDOW)) {
 	screen = pDraw->pScreen->myNum;
-        if (__glXSwapBarrierFuncs &&
-            __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc) {
-            int ret = __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, barrier);
+        if (pGlxScreen->swapBarrierFuncs) {
+            int ret = pGlxScreen->swapBarrierFuncs->bindSwapBarrierFunc(screen, drawable, barrier);
             if (ret == Success) {
                 if (barrier)
                     /* add source for cleanup when drawable is gone */
@@ -2118,10 +2119,11 @@ int __glXDisp_QueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
                                     (xGLXQueryMaxSwapBarriersSGIXReq *) pc;
     xGLXQueryMaxSwapBarriersSGIXReply reply;
     int screen = req->screen;
+    __GLXscreen *pGlxScreen;
 
-    if (__glXSwapBarrierFuncs &&
-        __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc)
-        reply.max = __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc(screen);
+    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+    if (pGlxScreen->swapBarrierFuncs)
+        reply.max = pGlxScreen->swapBarrierFuncs->queryMaxSwapBarriersFunc(screen);
     else
         reply.max = 0;
 
@@ -2154,11 +2156,12 @@ int __glXDisp_QueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc)
     int npipes=0;
 
     int n= 0;
+    __GLXscreen *pGlxScreen;
 
-    if (__glXHyperpipeFuncs &&
-        __glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc != NULL) {
+    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+    if (pGlxScreen->hyperpipeFuncs) {
         rdata =
-            (__glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc(screen, &npipes, &n));
+            (pGlxScreen->hyperpipeFuncs->queryHyperpipeNetworkFunc(screen, &npipes, &n));
     }
     length = __GLX_PAD(n) >> 2;
     reply.type = X_Reply;
@@ -2191,13 +2194,13 @@ int __glXDisp_DestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *pc)
     int screen = req->screen;
     int  success = GLX_BAD_HYPERPIPE_SGIX;
     int hpId ;
+    __GLXscreen *pGlxScreen;
 
     hpId = req->hpId;
 
-
-    if (__glXHyperpipeFuncs &&
-        __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc != NULL) {
-        success = __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc(screen, hpId);
+    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+    if (pGlxScreen->hyperpipeFuncs) {
+        success = pGlxScreen->hyperpipeFuncs->destroyHyperpipeConfigFunc(screen, hpId);
     }
 
     reply.type = X_Reply;
@@ -2229,12 +2232,13 @@ int __glXDisp_QueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
     int npipes=0;
     int n= 0;
     int hpId;
+    __GLXscreen *pGlxScreen;
 
     hpId = req->hpId;
 
-    if (__glXHyperpipeFuncs &&
-        __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc != NULL) {
-        rdata = __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc(screen, hpId,&npipes, &n);
+    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+    if (pGlxScreen->hyperpipeFuncs) {
+        rdata = pGlxScreen->hyperpipeFuncs->queryHyperpipeConfigFunc(screen, hpId,&npipes, &n);
     }
 
     length = __GLX_PAD(n) >> 2;
@@ -2272,14 +2276,15 @@ int __glXDisp_HyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
 
     int npipes=0, networkId;
     int hpId=-1;
+    __GLXscreen *pGlxScreen;
 
+    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
     networkId = (int)req->networkId;
     npipes = (int)req->npipes;
     rdata = (void *)(req +1);
 
-    if (__glXHyperpipeFuncs &&
-        __glXHyperpipeFuncs[screen].hyperpipeConfigFunc != NULL) {
-        __glXHyperpipeFuncs[screen].hyperpipeConfigFunc(screen,networkId,
+    if (pGlxScreen->hyperpipeFuncs) {
+        pGlxScreen->hyperpipeFuncs->hyperpipeConfigFunc(screen,networkId,
                                                         &hpId, &npipes,
                                                         (void *) rdata);
     }
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index ad02a89..b5de8c3 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -198,9 +198,10 @@ extern RESTYPE __glXSwapBarrierRes;
 
 static int SwapBarrierGone(int screen, XID drawable)
 {
-    if (__glXSwapBarrierFuncs &&
-        __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc != NULL) {
-        __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, 0);
+    __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+
+    if (pGlxScreen->swapBarrierFuncs) {
+        pGlxScreen->swapBarrierFuncs->bindSwapBarrierFunc(screen, drawable, 0);
     }
     FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
     return True;
diff --git a/GL/glx/glxext.h b/GL/glx/glxext.h
index 6774e4d..8de6434 100644
--- a/GL/glx/glxext.h
+++ b/GL/glx/glxext.h
@@ -106,25 +106,5 @@ extern int GlxInitVisuals(
     int               preferredVis
 );
 
-typedef struct {
-    void * (* queryHyperpipeNetworkFunc)(int, int *, int *);
-    void * (* queryHyperpipeConfigFunc)(int, int, int *, int *);
-    int    (* destroyHyperpipeConfigFunc)(int, int);
-    void * (* hyperpipeConfigFunc)(int, int, int *, int *, void *);
-} __GLXHyperpipeExtensionFuncs;
-
-extern void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs);
-
-extern __GLXHyperpipeExtensionFuncs *__glXHyperpipeFuncs;
-
-typedef struct {
-    int    (* bindSwapBarrierFunc)(int, XID, int);
-    int    (* queryMaxSwapBarriersFunc)(int);
-} __GLXSwapBarrierExtensionFuncs;
-
-extern void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs);
-
-extern __GLXSwapBarrierExtensionFuncs *__glXSwapBarrierFuncs;
-
 #endif /* _glxext_h_ */
 
diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index 75cb871..c6f060b 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -181,12 +181,6 @@ static char GLXServerExtensions[] =
 			"GLX_MESA_copy_sub_buffer "
 			;
 
-__GLXSwapBarrierExtensionFuncs *__glXSwapBarrierFuncs = NULL;
-static int __glXNumSwapBarrierFuncs = 0;
-__GLXHyperpipeExtensionFuncs *__glXHyperpipeFuncs = NULL;
-static int __glXNumHyperpipeFuncs = 0;
-
-
 /*
 ** This hook gets called when a window moves or changes size.
 */
@@ -256,34 +250,16 @@ static Bool glxPositionWindow(WindowPtr pWin, int x, int y)
 
 void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs)
 {
-    if (__glXNumHyperpipeFuncs < screen + 1) {
-        __glXHyperpipeFuncs = xrealloc(__glXHyperpipeFuncs,
-                                           (screen+1) * sizeof(__GLXHyperpipeExtensionFuncs));
-        __glXNumHyperpipeFuncs = screen + 1;
-    }
+    __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
 
-    __glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc =
-        *funcs->queryHyperpipeNetworkFunc;
-    __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc =
-        *funcs->queryHyperpipeConfigFunc;
-    __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc =
-        *funcs->destroyHyperpipeConfigFunc;
-    __glXHyperpipeFuncs[screen].hyperpipeConfigFunc =
-        *funcs->hyperpipeConfigFunc;
+    pGlxScreen->hyperpipeFuncs = funcs;
 }
 
 void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs)
 {
-    if (__glXNumSwapBarrierFuncs < screen + 1) {
-        __glXSwapBarrierFuncs = xrealloc(__glXSwapBarrierFuncs,
-                                           (screen+1) * sizeof(__GLXSwapBarrierExtensionFuncs));
-        __glXNumSwapBarrierFuncs = screen + 1;
-    }
+    __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
 
-    __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc =
-        funcs->bindSwapBarrierFunc;
-    __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc =
-        funcs->queryMaxSwapBarriersFunc;
+    pGlxScreen->swapBarrierFuncs = funcs;
 }
 
 static Bool
diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h
index d92a795..d887beb 100644
--- a/GL/glx/glxscreens.h
+++ b/GL/glx/glxscreens.h
@@ -42,6 +42,21 @@
 
 #include "GL/internal/glcore.h"
 
+typedef struct {
+    void * (* queryHyperpipeNetworkFunc)(int, int *, int *);
+    void * (* queryHyperpipeConfigFunc)(int, int, int *, int *);
+    int    (* destroyHyperpipeConfigFunc)(int, int);
+    void * (* hyperpipeConfigFunc)(int, int, int *, int *, void *);
+} __GLXHyperpipeExtensionFuncs;
+
+typedef struct {
+    int    (* bindSwapBarrierFunc)(int, XID, int);
+    int    (* queryMaxSwapBarriersFunc)(int);
+} __GLXSwapBarrierExtensionFuncs;
+
+void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs);
+void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs);
+
 /*
 ** Screen dependent data.  These methods are the interface between the DIX
 ** and DDX layers of the GLX server extension.  The methods provide an
@@ -62,6 +77,9 @@ struct __GLXscreen {
     int            (*swapInterval)  (__GLXdrawable *drawable,
 				     int interval);
 
+    __GLXHyperpipeExtensionFuncs *hyperpipeFuncs;
+    __GLXSwapBarrierExtensionFuncs *swapBarrierFuncs;
+
     ScreenPtr pScreen;
 
     /**
commit 781515bb637de4fd79e3c83817cb6ffa8f2d8a4f
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Wed May 30 23:25:03 2007 -0400

    Convert GLX module to use screen private indexes like everything else.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 597c7bd..e09290e 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -131,8 +131,8 @@ int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
 	return BadValue;
     }
     pScreen = screenInfo.screens[screen];
-    pGlxScreen = __glXActiveScreens[screen];
-    
+    pGlxScreen = glxGetScreen(pScreen);
+
     /*
     ** Check if the visual ID is valid for this screen.
     */
@@ -149,7 +149,7 @@ int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
 
     /*
     ** Get configuration of the visual.  This assumes that the
-    ** glXActiveScreens structure contains visual configurations only for the
+    ** glxScreen structure contains visual configurations only for the
     ** subset of Visuals that are supported by this implementation of the
     ** OpenGL.
     */
@@ -931,7 +931,7 @@ int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
 	client->errorValue = screen;
 	return BadValue;
     }
-    pGlxScreen = __glXActiveScreens[screen];
+    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
 
     reply.numVisuals = pGlxScreen->numUsableVisuals;
     reply.numProps = __GLX_TOTAL_CONFIG;
@@ -1119,7 +1119,7 @@ int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
 	client->errorValue = screen;
 	return BadValue;
     }
-    pGlxScreen = __glXActiveScreens[screen];
+    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
 
     /* Create the "extra" 32bpp ARGB visual, if not already added.
      * XXX This is questionable place to do so!  Re-examine this someday.
@@ -1245,7 +1245,7 @@ static int ValidateCreateDrawable(ClientPtr client,
     }
 
     /* Get configuration of the visual. */
-    pGlxScreen = __glXgetActiveScreen(screenNum);
+    pGlxScreen = glxGetScreen(pScreen);
     *modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId);
     if (*modes == NULL) {
 	/* Visual not support on this screen by this OpenGL implementation. */
@@ -1286,7 +1286,7 @@ int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
 	return BadAlloc;
     }
     pGlxPixmap->pDraw = pDraw;
-    pGlxPixmap->pGlxScreen = __glXgetActiveScreen(screenNum);
+    pGlxPixmap->pGlxScreen = glxGetScreen(pDraw->pScreen);
     pGlxPixmap->pScreen = pDraw->pScreen;
     pGlxPixmap->idExists = True;
 #ifdef XF86DRI
@@ -1430,7 +1430,7 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
     /* FIXME: We need to check that the window visual is compatible
      * with the specified fbconfig. */
 
-    screen = __glXgetActiveScreen(req->screen);
+    screen = glxGetScreen(screenInfo.screens[req->screen]);
     glxPriv = screen->createDrawable(screen, pDraw, req->glxwindow, modes);
     if (glxPriv == NULL)
 	return BadAlloc;
@@ -2368,7 +2368,7 @@ int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
 	return BadValue;
     }
 
-    ptr = __glXActiveScreens[screen]->GLXextensions;
+    ptr = glxGetScreen(screenInfo.screens[screen])->GLXextensions;
 
     n = strlen(ptr) + 1;
     length = __GLX_PAD(n) >> 2;
@@ -2404,6 +2404,7 @@ int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc)
     size_t n, length;
     const char *ptr;
     char *buf;
+    __GLXscreen *pGlxScreen;
 
     name = req->name;
     screen = req->screen;
@@ -2414,15 +2415,17 @@ int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc)
 	client->errorValue = screen;
 	return BadValue;
     }
+    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+
     switch(name) {
 	case GLX_VENDOR:
-	    ptr = __glXActiveScreens[screen]->GLXvendor;
+	    ptr = pGlxScreen->GLXvendor;
 	    break;
 	case GLX_VERSION:
-	    ptr = __glXActiveScreens[screen]->GLXversion;
+	    ptr = pGlxScreen->GLXversion;
 	    break;
 	case GLX_EXTENSIONS:
-	    ptr = __glXActiveScreens[screen]->GLXextensions;
+	    ptr = pGlxScreen->GLXextensions;
 	    break;
 	default:
 	    return BadValue; 
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index 116689f..6389ad9 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -103,7 +103,7 @@ __glXDRIleaveServer(GLboolean rendering)
 
     for (i = 0; rendering && i < screenInfo.numScreens; i++) {
 	__GLXDRIscreen * const screen =
-	    (__GLXDRIscreen *) __glXgetActiveScreen(i);
+	    (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
 	GLuint lastOverride = screen->lastTexOffsetOverride;
 
 	if (lastOverride) {
@@ -125,7 +125,7 @@ __glXDRIleaveServer(GLboolean rendering)
 
     for (i = 0; rendering && i < screenInfo.numScreens; i++) {
 	__GLXDRIscreen * const screen =
-	    (__GLXDRIscreen *) __glXgetActiveScreen(i);
+	    (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
 	GLuint lastOverride = screen->lastTexOffsetOverride;
 
 	if (lastOverride) {
@@ -153,8 +153,8 @@ __glXDRIenterServer(GLboolean rendering)
     int i;
 
     for (i = 0; rendering && i < screenInfo.numScreens; i++) {
-	__GLXDRIscreen * const screen =
-	    (__GLXDRIscreen *) __glXgetActiveScreen(i);
+	__GLXDRIscreen * const screen = (__GLXDRIscreen *)
+	    glxGetScreen(screenInfo.screens[i]);
 
 	if (screen->lastTexOffsetOverride) {
 	    CALL_Flush(GET_DISPATCH(), ());
@@ -205,7 +205,7 @@ __glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval)
 {
     __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable;
     __GLXDRIscreen *screen = (__GLXDRIscreen *)
-	__glXgetActiveScreen(baseDrawable->pDraw->pScreen->myNum);
+	glxGetScreen(baseDrawable->pDraw->pScreen);
 
     if (screen->swapControl)
 	screen->swapControl->setSwapInterval(&draw->driDrawable, interval);
@@ -220,7 +220,7 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
 {
     __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
     __GLXDRIscreen *screen = (__GLXDRIscreen *)
-	__glXgetActiveScreen(basePrivate->pDraw->pScreen->myNum);
+	glxGetScreen(basePrivate->pDraw->pScreen);
 
     if (screen->copySubBuffer)
 	screen->copySubBuffer->copySubBuffer(&private->driDrawable,
@@ -328,8 +328,7 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
     int		bpp, override = 0, texname;
     GLenum	format, type;
     ScreenPtr pScreen = glxPixmap->pScreen;
-    __GLXDRIscreen * const screen =
-	(__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
+    __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen);
 
     CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
 				      GL_TEXTURE_BINDING_2D :
@@ -482,7 +481,7 @@ __glXDRIreleaseTexImage(__GLXcontext *baseContext,
 {
     ScreenPtr pScreen = pixmap->pScreen;
     __GLXDRIscreen * const screen =
-	(__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
+	(__GLXDRIscreen *) glxGetScreen(pScreen);
     GLuint lastOverride = screen->lastTexOffsetOverride;
 
     if (lastOverride) {
@@ -801,7 +800,8 @@ static const char dri_driver_path[] = DRI_DRIVER_PATH;
 static Bool
 glxDRIEnterVT (int index, int flags)
 {
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) __glXgetActiveScreen(index);
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) 
+	glxGetScreen(screenInfo.screens[index]);
 
     LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
 
@@ -816,7 +816,8 @@ glxDRIEnterVT (int index, int flags)
 static void
 glxDRILeaveVT (int index, int flags)
 {
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) __glXgetActiveScreen(index);
+    __GLXDRIscreen *screen = (__GLXDRIscreen *)
+	glxGetScreen(screenInfo.screens[index]);
 
     LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
 
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index 5b621d3..ad02a89 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -45,7 +45,6 @@ __GLXcontext *__glXLastContext;
 ** X resources.
 */
 RESTYPE __glXContextRes;
-RESTYPE __glXClientRes;
 RESTYPE __glXPixmapRes;
 RESTYPE __glXDrawableRes;
 RESTYPE __glXSwapBarrierRes;
@@ -55,11 +54,7 @@ RESTYPE __glXSwapBarrierRes;
 */
 xGLXSingleReply __glXReply;
 
-/*
-** A set of state for each client.  The 0th one is unused because client
-** indices start at 1, not 0.
-*/
-static __GLXclientState *__glXClients[MAXCLIENTS + 1];
+static int glxClientPrivateIndex;
 
 /*
 ** Client that called into GLX dispatch.
@@ -77,29 +72,6 @@ static int __glXDispatch(ClientPtr);
 static void ResetExtension(ExtensionEntry* extEntry)
 {
     __glXFlushContextCache();
-    __glXResetScreens();
-}
-
-/*
-** Initialize the per-client context storage.
-*/
-static void ResetClientState(int clientIndex)
-{
-    __GLXclientState *cl = __glXClients[clientIndex];
-
-    if (cl->returnBuf) xfree(cl->returnBuf);
-    if (cl->largeCmdBuf) xfree(cl->largeCmdBuf);
-    if (cl->currentContexts) xfree(cl->currentContexts);
-    memset(cl, 0, sizeof(__GLXclientState));
-    /*
-    ** By default, assume that the client supports
-    ** GLX major version 1 minor version 0 protocol.
-    */
-    cl->GLClientmajorVersion = 1;
-    cl->GLClientminorVersion = 0;
-    if (cl->GLClientextensions)
-	xfree(cl->GLClientextensions);
-
 }
 
 /*
@@ -130,39 +102,6 @@ static int ContextGone(__GLXcontext* cx, XID id)
 }
 
 /*
-** Free a client's state.
-*/
-static int ClientGone(int clientIndex, XID id)
-{
-    __GLXcontext *cx;
-    __GLXclientState *cl = __glXClients[clientIndex];
-    int i;
-
-    if (cl) {
-	/*
-	** Free all the contexts that are current for this client.
-	*/
-	for (i=0; i < cl->numCurrentContexts; i++) {
-	    cx = cl->currentContexts[i];
-	    if (cx) {
-		cx->isCurrent = GL_FALSE;
-		if (!cx->idExists) {
-		    __glXFreeContext(cx);
-		}
-	    }
-	}
-	/*
-	** Re-initialize the client state structure.  Don't free it because
-	** we'll probably get another client with this index and use the struct
-	** again.  There is a maximum of MAXCLIENTS of these structures.
-	*/
-	ResetClientState(clientIndex);
-    }
-
-    return True;
-}
-
-/*
 ** Free a GLX Pixmap.
 */
 static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
@@ -309,22 +248,87 @@ int __glXError(int error)
     return __glXErrorBase + error;
 }
 
+__GLXclientState *
+glxGetClient(ClientPtr pClient)
+{
+    return (__GLXclientState *) pClient->devPrivates[glxClientPrivateIndex].ptr;
+}
+
+static void
+glxClientCallback (CallbackListPtr	*list,
+		   pointer		closure,
+		   pointer		data)
+{
+    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
+    ClientPtr		pClient = clientinfo->client;
+    __GLXclientState	*cl = glxGetClient(pClient);
+    __GLXcontext	*cx;
+    int i;
+
+    switch (pClient->clientState) {
+    case ClientStateRunning:
+	/*
+	** By default, assume that the client supports
+	** GLX major version 1 minor version 0 protocol.
+	*/
+	cl->GLClientmajorVersion = 1;
+	cl->GLClientminorVersion = 0;
+	cl->client = pClient;
+	break;
+
+    case ClientStateGone:
+	for (i = 0; i < cl->numCurrentContexts; i++) {
+	    cx = cl->currentContexts[i];
+	    if (cx) {
+		cx->isCurrent = GL_FALSE;
+		if (!cx->idExists)
+		    __glXFreeContext(cx);
+	    }
+	}
+
+	if (cl->returnBuf) xfree(cl->returnBuf);
+	if (cl->largeCmdBuf) xfree(cl->largeCmdBuf);
+	if (cl->currentContexts) xfree(cl->currentContexts);
+	if (cl->GLClientextensions) xfree(cl->GLClientextensions);
+	break;
+
+    default:
+	break;
+    }
+}
+
 /************************************************************************/
 
+static __GLXprovider *__glXProviderStack;
+
+void GlxPushProvider(__GLXprovider *provider)
+{
+    provider->next = __glXProviderStack;
+    __glXProviderStack = provider;
+}
+
 /*
 ** Initialize the GLX extension.
 */
 void GlxExtensionInit(void)
 {
     ExtensionEntry *extEntry;
+    ScreenPtr pScreen;
     int i;
+    __GLXprovider *p;
 
     __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
-    __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
     __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
     __glXDrawableRes = CreateNewResourceType((DeleteType)DrawableGone);
     __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
 
+    glxClientPrivateIndex = AllocateClientPrivateIndex ();
+    if (!AllocateClientPrivate (glxClientPrivateIndex,
+				sizeof (__GLXclientState)))
+	return;
+    if (!AddCallback (&ClientStateCallback, glxClientCallback, 0))
+	return;
+
     /*
     ** Add extension to server extensions.
     */
@@ -343,17 +347,17 @@ void GlxExtensionInit(void)
 
     __glXErrorBase = extEntry->errorBase;
 
-    /*
-    ** Initialize table of client state.  There is never a client 0.
-    */
-    for (i = 1; i <= MAXCLIENTS; i++) {
-	__glXClients[i] = 0;
-    }
+    for (i = 0; i < screenInfo.numScreens; i++) {
+	pScreen = screenInfo.screens[i];
 
-    /*
-    ** Initialize screen specific data.
-    */
-    __glXInitScreens();
+	for (p = __glXProviderStack; p != NULL; p = p->next) {
+	    if (p->screenProbe(pScreen) != NULL)
+		LogMessage(X_INFO,
+			   "GLX: Initialized %s GL provider for screen %d\n",
+			   p->name, i);
+	    break;
+	}
+    }
 }
 
 /************************************************************************/
@@ -421,11 +425,9 @@ void glxSuspendClients(void)
 {
     int i;
 
-    for (i = 1; i <= MAXCLIENTS; i++) {
-	if (__glXClients[i] == NULL || !__glXClients[i]->inUse)
-	    continue;
-
-	IgnoreClient(__glXClients[i]->client);
+    for (i = 1; i < currentMaxClients; i++) {
+	if (glxGetClient(clients[i])->inUse)
+	    IgnoreClient(clients[i]);
     }
 
     glxBlockClients = TRUE;
@@ -438,11 +440,9 @@ void glxResumeClients(void)
 
     glxBlockClients = FALSE;
 
-    for (i = 1; i <= MAXCLIENTS; i++) {
-	if (__glXClients[i] == NULL || !__glXClients[i]->inUse)
-	    continue;
-
-	AttendClient(__glXClients[i]->client);
+    for (i = 1; i < currentMaxClients; i++) {
+	if (glxGetClient(clients[i])->inUse)
+	    AttendClient(clients[i]);
     }
 
     __glXleaveServer(GL_FALSE);
@@ -504,29 +504,9 @@ static int __glXDispatch(ClientPtr client)
     int retval;
 
     opcode = stuff->glxCode;
-    cl = __glXClients[client->index];
-    if (!cl) {
-	cl = (__GLXclientState *) xalloc(sizeof(__GLXclientState));
-	 __glXClients[client->index] = cl;
-	if (!cl) {
-	    return BadAlloc;
-	}
-	memset(cl, 0, sizeof(__GLXclientState));
-    }
-    
-    if (!cl->inUse) {
-	/*
-	** This is first request from this client.  Associate a resource
-	** with the client so we will be notified when the client dies.
-	*/
-	XID xid = FakeClientID(client->index);
-	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
-	    return BadAlloc;
-	}
-	ResetClientState(client->index);
-	cl->inUse = GL_TRUE;
-	cl->client = client;
-    }
+    cl = glxGetClient(client);
+    /* Mark it in use so we suspend it on VT switch. */
+    cl->inUse = TRUE;
 
     /*
     ** If we're expecting a glXRenderLarge request, this better be one.
diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index 43447a4..75cb871 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -45,6 +45,8 @@
 #include "glxutil.h"
 #include "glxext.h"
 
+static int glxScreenPrivateIndex;
+
 const char GLServerVersion[] = "1.4";
 static const char GLServerExtensions[] = 
 			"GL_ARB_depth_texture "
@@ -179,36 +181,31 @@ static char GLXServerExtensions[] =
 			"GLX_MESA_copy_sub_buffer "
 			;
 
-__GLXscreen **__glXActiveScreens;
-
 __GLXSwapBarrierExtensionFuncs *__glXSwapBarrierFuncs = NULL;
 static int __glXNumSwapBarrierFuncs = 0;
 __GLXHyperpipeExtensionFuncs *__glXHyperpipeFuncs = NULL;
 static int __glXNumHyperpipeFuncs = 0;
 
-__GLXscreen *__glXgetActiveScreen(int num) {
-	return __glXActiveScreens[num];
-}
-
 
 /*
 ** This hook gets called when a window moves or changes size.
 */
-static Bool PositionWindow(WindowPtr pWin, int x, int y)
+static Bool glxPositionWindow(WindowPtr pWin, int x, int y)
 {
     ScreenPtr pScreen;
     __GLXcontext *glxc;
     __GLXdrawable *glxPriv;
     Bool ret;
+    __GLXscreen *pGlxScreen;
 
     /*
     ** Call wrapped position window routine
     */
     pScreen = pWin->drawable.pScreen;
-    pScreen->PositionWindow =
-	__glXActiveScreens[pScreen->myNum]->WrappedPositionWindow;
+    pGlxScreen = glxGetScreen(pScreen);
+    pScreen->PositionWindow = pGlxScreen->PositionWindow;
     ret = (*pScreen->PositionWindow)(pWin, x, y);
-    pScreen->PositionWindow = PositionWindow;
+    pScreen->PositionWindow = glxPositionWindow;
 
     /*
     ** Tell all contexts rendering into this window that the window size
@@ -289,80 +286,59 @@ void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs)
         funcs->queryMaxSwapBarriersFunc;
 }
 
-static __GLXprovider *__glXProviderStack;
-
-void GlxPushProvider(__GLXprovider *provider)
+static Bool
+glxCloseScreen (int index, ScreenPtr pScreen)
 {
-    provider->next = __glXProviderStack;
-    __glXProviderStack = provider;
-}
+    __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
 
-void __glXScreenInit(__GLXscreen *screen, ScreenPtr pScreen)
-{
-    screen->pScreen       = pScreen;
-    screen->GLextensions  = xstrdup(GLServerExtensions);
-    screen->GLXvendor     = xstrdup(GLXServerVendorName);
-    screen->GLXversion    = xstrdup(GLXServerVersion);
-    screen->GLXextensions = xstrdup(GLXServerExtensions);
+    pScreen->CloseScreen = pGlxScreen->CloseScreen;
+    pScreen->PositionWindow = pGlxScreen->PositionWindow;
 
-    screen->WrappedPositionWindow = pScreen->PositionWindow;
-    pScreen->PositionWindow = PositionWindow;
+    pGlxScreen->destroy(pGlxScreen);
 
-    __glXScreenInitVisuals(screen);
+    return pScreen->CloseScreen(index, pScreen);
 }
 
-void
-__glXScreenDestroy(__GLXscreen *screen)
+__GLXscreen *
+glxGetScreen(ScreenPtr pScreen)
 {
-    xfree(screen->GLXvendor);
-    xfree(screen->GLXversion);
-    xfree(screen->GLXextensions);
-    xfree(screen->GLextensions);
+    return (__GLXscreen *) pScreen->devPrivates[glxScreenPrivateIndex].ptr;
 }
 
-void __glXInitScreens(void)
+void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
 {
-    GLint i;
-    ScreenPtr pScreen;
-    __GLXprovider *p;
-    size_t size;
+    static int glxGeneration;
 
-    /*
-    ** This alloc has to work or else the server might as well core dump.
-    */
-    size = screenInfo.numScreens * sizeof(__GLXscreen *);
-    __glXActiveScreens = xalloc(size);
-    memset(__glXActiveScreens, 0, size);
-    
-    for (i = 0; i < screenInfo.numScreens; i++) {
-	pScreen = screenInfo.screens[i];
-
-	for (p = __glXProviderStack; p != NULL; p = p->next) {
-	    __glXActiveScreens[i] = p->screenProbe(pScreen);
-	    if (__glXActiveScreens[i] != NULL) {
-		LogMessage(X_INFO,
-			   "GLX: Initialized %s GL provider for screen %d\n",
-			   p->name, i);
-	        break;
-	    }
-	}
+    if (glxGeneration != serverGeneration)
+    {
+	glxScreenPrivateIndex = AllocateScreenPrivateIndex ();
+	if (glxScreenPrivateIndex == -1)
+	    return;
+
+	glxGeneration = serverGeneration;
     }
-}
 
-void __glXResetScreens(void)
+    glxScreen->pScreen       = pScreen;
+    glxScreen->GLextensions  = xstrdup(GLServerExtensions);
+    glxScreen->GLXvendor     = xstrdup(GLXServerVendorName);
+    glxScreen->GLXversion    = xstrdup(GLXServerVersion);
+    glxScreen->GLXextensions = xstrdup(GLXServerExtensions);
+
+    glxScreen->PositionWindow = pScreen->PositionWindow;
+    pScreen->PositionWindow = glxPositionWindow;
+ 
+    glxScreen->CloseScreen = pScreen->CloseScreen;
+    pScreen->CloseScreen = glxCloseScreen;
+
+    __glXScreenInitVisuals(glxScreen);
+
+    pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) glxScreen;
+}
+ 
+void __glXScreenDestroy(__GLXscreen *screen)
 {
-  int i;
-
-  for (i = 0; i < screenInfo.numScreens; i++)
-      if (__glXActiveScreens[i])
-	  __glXActiveScreens[i]->destroy(__glXActiveScreens[i]);
-
-    xfree(__glXActiveScreens);
-    xfree(__glXHyperpipeFuncs);
-    xfree(__glXSwapBarrierFuncs);
-    __glXNumHyperpipeFuncs = 0;
-    __glXNumSwapBarrierFuncs = 0;
-    __glXHyperpipeFuncs = NULL;
-    __glXSwapBarrierFuncs = NULL;
-    __glXActiveScreens = NULL;
+    xfree(screen->GLXvendor);
+    xfree(screen->GLXversion);
+    xfree(screen->GLXextensions);
+    xfree(screen->GLextensions);
 }
diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h
index bba4557..d92a795 100644
--- a/GL/glx/glxscreens.h
+++ b/GL/glx/glxscreens.h
@@ -79,18 +79,12 @@ struct __GLXscreen {
     char *GLXversion;
     char *GLXextensions;
 
-    /*
-    ** Things that are not statically set.
-    */
-    Bool (*WrappedPositionWindow)(WindowPtr pWin, int x, int y);
-
+    Bool (*PositionWindow)(WindowPtr pWin, int x, int y);
+    Bool (*CloseScreen)(int index, ScreenPtr pScreen);
 };
 
 
 void __glXScreenInit(__GLXscreen *screen, ScreenPtr pScreen);
 void __glXScreenDestroy(__GLXscreen *screen);
 
-void __glXInitScreens(void);
-extern void __glXResetScreens(void);
-
 #endif /* !__GLX_screens_h__ */
diff --git a/GL/glx/glxserver.h b/GL/glx/glxserver.h
index b6b5592..45de8e7 100644
--- a/GL/glx/glxserver.h
+++ b/GL/glx/glxserver.h
@@ -90,9 +90,8 @@ typedef XID GLXDrawable;
 
 typedef struct __GLXclientStateRec __GLXclientState;
 
-extern __GLXscreen **__glXActiveScreens;
-extern GLint __glXNumActiveScreens;
-extern __GLXscreen *__glXgetActiveScreen(int num);
+extern __GLXscreen *glxGetScreen(ScreenPtr pScreen);
+extern __GLXclientState *glxGetClient(ClientPtr pClient);
 
 /************************************************************************/
 
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index d1bbfcd..1a54f2c 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -972,7 +972,7 @@ static Bool
 DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
 {
     DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-    __GLXscreen *pGLXScreen = __glXgetActiveScreen(pScreen->myNum);
+    __GLXscreen *pGLXScreen = glxGetScreen(pScreen);
     __GLcontextModes *modes = pGLXScreen->modes;
     void **pVisualConfigPriv = pGLXScreen->pVisualPriv;
     DRIContextPrivPtr pDRIContextPriv;
@@ -1036,7 +1036,7 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
                  XID context, drm_context_t * pHWContext)
 {
     DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-    __GLXscreen *pGLXScreen = __glXgetActiveScreen(pScreen->myNum);
+    __GLXscreen *pGLXScreen = glxGetScreen(pScreen);
     __GLcontextModes *modes = pGLXScreen->modes;
     void **pVisualConfigPriv = pGLXScreen->pVisualPriv;
     DRIContextPrivPtr pDRIContextPriv;
commit 72a3d68a2f5abcd09fef1a55e976e1a5731d4b02
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Thu May 10 11:16:50 2007 -0400

    Update the AIGLX DRI loader to use the new DRI interface.
    
    This lets us drop a bunch of workarounds and use the new DRI extension
    mechanism.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 900a347..597c7bd 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -73,6 +73,8 @@ GlxSetRenderTables (struct _glapi_table *table)
 void
 __glXContextDestroy(__GLXcontext *context)
 {
+    if (!context->isDirect)
+	__glXDeassociateContext(context);
     __glXFlushContextCache();
 }
 
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index c1f3eb7..116689f 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -59,22 +59,21 @@
 #include "dispatch.h"
 #include "extension_string.h"
 
-
-#define STRINGIFY(macro_or_string)	STRINGIFY_ARG (macro_or_string)
-#define	STRINGIFY_ARG(contents)	#contents
-
-typedef struct __GLXDRIscreen      __GLXDRIscreen;
-typedef struct __GLXDRIcontext         __GLXDRIcontext;
+typedef struct __GLXDRIscreen   __GLXDRIscreen;
+typedef struct __GLXDRIcontext  __GLXDRIcontext;
 typedef struct __GLXDRIdrawable __GLXDRIdrawable;
 
 struct __GLXDRIscreen {
     __GLXscreen		 base;
+    __DRIscreen		 driScreen;
+    void		*driver;
 
-    __DRIscreen			 driScreen;
-    void			*driver;
+    xf86EnterVTProc	*enterVT;
+    xf86LeaveVTProc	*leaveVT;
 
-    xf86EnterVTProc *enterVT;
-    xf86LeaveVTProc *leaveVT;
+    __DRIcopySubBufferExtension *copySubBuffer;
+    __DRIswapControlExtension *swapControl;
+    __DRItexOffsetExtension *texOffset;
 
     DRITexOffsetStartProcPtr texOffsetStart;
     DRITexOffsetFinishProcPtr texOffsetFinish;
@@ -85,51 +84,17 @@ struct __GLXDRIscreen {
 };
 
 struct __GLXDRIcontext {
-    __GLXcontext		 base;
-
-    __DRIcontext		 driContext;
+    __GLXcontext base;
+    __DRIcontext driContext;
+    XID hwContextID;
 };
 
 struct __GLXDRIdrawable {
-    __GLXdrawable	 base;
-
-    __DRIdrawable		*driDrawable;
+    __GLXdrawable base;
+    __DRIdrawable driDrawable;
 };
 
-/* History:
- * 20021121 - Initial version
- * 20021128 - Added __glXWindowExists() function
- * 20021207 - Added support for dynamic GLX extensions,
- *            GLX_SGI_swap_control, GLX_SGI_video_sync,
- *            GLX_OML_sync_control, and GLX_MESA_swap_control.
- *            Never officially released.  Do NOT test against
- *            this version.  Use 20030317 instead.
- * 20030317 - Added support GLX_SGIX_fbconfig,
- *            GLX_MESA_swap_frame_usage, GLX_OML_swap_method,
- *            GLX_{ARB,SGIS}_multisample, and
- *            GLX_SGIX_visual_select_group.
- * 20030606 - Added support for GLX_SGI_make_current_read.
- * 20030813 - Made support for dynamic extensions multi-head aware.
- * 20030818 - Added support for GLX_MESA_allocate_memory in place of the
- *            deprecated GLX_NV_vertex_array_range & GLX_MESA_agp_offset
- *            interfaces.
- * 20031201 - Added support for the first round of DRI interface changes.
- *            Do NOT test against this version!  It has binary
- *            compatibility bugs, use 20040317 instead.
- * 20040317 - Added the 'mode' field to __DRIcontextRec.
- * 20040415 - Added support for bindContext3 and unbindContext3.
- * 20040602 - Add __glXGetDrawableInfo.  I though that was there
- *            months ago. :(
- * 20050727 - Gut all the old interfaces.  This breaks compatability with
- *            any DRI driver built to any previous version.
- * 20060314 - Added support for GLX_MESA_copy_sub_buffer.
- */
-
-#define INTERNAL_VERSION 20050727
-
-static const char CREATE_NEW_SCREEN_FUNC[] =
-    "__driCreateNewScreen_" STRINGIFY (INTERNAL_VERSION);
-
+static const char CREATE_NEW_SCREEN_FUNC[] = __DRI_CREATE_NEW_SCREEN_STRING;
 
 static void
 __glXDRIleaveServer(GLboolean rendering)
@@ -171,12 +136,11 @@ __glXDRIleaveServer(GLboolean rendering)
 		__GLXpixmap *pGlxPix = texOffsetOverride[j];
 
 		if (pGlxPix && pGlxPix->texname) {
-		    screen->driScreen.setTexOffset(pGlxPix->pDRICtx,
-						   pGlxPix->texname,
-						   pGlxPix->offset,
-						   pGlxPix->pDraw->depth,
-						   ((PixmapPtr)pGlxPix->pDraw)->
-						   devKind);
+		    screen->texOffset->setTexOffset(pGlxPix->pDRICtx,
+						    pGlxPix->texname,
+						    pGlxPix->offset,
+						    pGlxPix->pDraw->depth,
+						    ((PixmapPtr)pGlxPix->pDraw)->devKind);
 		}
 	    }
 	}
@@ -201,29 +165,17 @@ __glXDRIenterServer(GLboolean rendering)
     DRIWakeupHandler(NULL, 0, NULL);
 }
 
-/**
- * \bug
- * We're jumping through hoops here to get the DRIdrawable which the DRI
- * driver tries to keep to it self...  cf. FIXME in \c createDrawable.
- */
 static void
-__glXDRIdrawableFoo(__GLXDRIdrawable *draw)
+__glXDRIdrawableDestroy(__GLXdrawable *drawable)
 {
-    __GLXDRIscreen * const screen =
-      (__GLXDRIscreen *) __glXgetActiveScreen(draw->base.pDraw->pScreen->myNum);
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
 
-    draw->driDrawable = (*screen->driScreen.getDrawable)(NULL,
-							 draw->base.drawId,
-							 screen->driScreen.private);
-}
+    (*private->driDrawable.destroyDrawable)(&private->driDrawable);
 
-static void
-__glXDRIdrawableDestroy(__GLXdrawable *private)
-{
-#if 0
-    (*glxPriv->driDrawable.destroyDrawable)(NULL,
-					    glxPriv->driDrawable.private);
-#endif
+    __glXenterServer(GL_FALSE);
+    DRIDestroyDrawable(drawable->pDraw->pScreen,
+		       serverClient, drawable->pDraw);
+    __glXleaveServer(GL_FALSE);
 
     xfree(private);
 }
@@ -242,10 +194,7 @@ __glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate)
 {
     __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
 
-    __glXDRIdrawableFoo(private);
-
-    (*private->driDrawable->swapBuffers)(NULL,
-					 private->driDrawable->private);
+    (*private->driDrawable.swapBuffers)(&private->driDrawable);
 
     return TRUE;
 }
@@ -255,10 +204,12 @@ static int
 __glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval)
 {
     __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *)
+	__glXgetActiveScreen(baseDrawable->pDraw->pScreen->myNum);
 
-    __glXDRIdrawableFoo(draw);
+    if (screen->swapControl)
+	screen->swapControl->setSwapInterval(&draw->driDrawable, interval);
 
-    draw->driDrawable->swap_interval = interval;
     return 0;
 }
 
@@ -268,22 +219,26 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
 			       int x, int y, int w, int h)
 {
     __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *)
+	__glXgetActiveScreen(basePrivate->pDraw->pScreen->myNum);
 
-    __glXDRIdrawableFoo(private);
-
-    (*private->driDrawable->copySubBuffer)(NULL,
-					   private->driDrawable->private,
-					   x, y, w, h);
+    if (screen->copySubBuffer)
+	screen->copySubBuffer->copySubBuffer(&private->driDrawable,
+					     x, y, w, h);
 }
 
 static void
 __glXDRIcontextDestroy(__GLXcontext *baseContext)
 {
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    Bool retval;
+
+    context->driContext.destroyContext(&context->driContext);
+
+    __glXenterServer(GL_FALSE);
+    retval = DRIDestroyContext(baseContext->pScreen, context->hwContextID);
+    __glXleaveServer(GL_FALSE);
 
-    context->driContext.destroyContext(NULL,
-				       context->base.pScreen->myNum,
-				       context->driContext.private);
     __glXContextDestroy(&context->base);
     xfree(context);
 }
@@ -292,24 +247,20 @@ static int
 __glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
 {
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+    __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
 
-    return (*context->driContext.bindContext)(NULL,
-					      context->base.pScreen->myNum,
-					      baseContext->drawPriv->drawId,
-					      baseContext->readPriv->drawId,
-					      &context->driContext);
-}
+    return (*context->driContext.bindContext)(&context->driContext,
+					      &draw->driDrawable,
+					      &read->driDrawable);
+}					      
 
 static int
 __glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
 {
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
 
-    return (*context->driContext.unbindContext)(NULL,
-						context->base.pScreen->myNum,
-						baseContext->drawPriv->drawId,
-						baseContext->readPriv->drawId,
-						&context->driContext);
+    return (*context->driContext.unbindContext)(&context->driContext);
 }
 
 static int
@@ -331,12 +282,12 @@ static int
 __glXDRIcontextForceCurrent(__GLXcontext *baseContext)
 {
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+    __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
 
-    return (*context->driContext.bindContext)(NULL,
-					      context->base.pScreen->myNum,
-					      baseContext->drawPriv->drawId,
-					      baseContext->readPriv->drawId,
-					      &context->driContext);
+    return (*context->driContext.bindContext)(&context->driContext,
+					      &draw->driDrawable,
+					      &read->driDrawable);
 }
 
 static void
@@ -390,7 +341,7 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
 
     pixmap = (PixmapPtr) glxPixmap->pDraw;
 
-    if (screen->texOffsetStart && screen->driScreen.setTexOffset) {
+    if (screen->texOffsetStart && screen->texOffset) {
 	__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
 	int i, firstEmpty = 16;
 
@@ -422,8 +373,9 @@ alreadyin:
 
 	glxPixmap->texname = texname;
 
-	screen->driScreen.setTexOffset(glxPixmap->pDRICtx, texname, 0,
-				       pixmap->drawable.depth, pixmap->devKind);
+	screen->texOffset->setTexOffset(glxPixmap->pDRICtx, texname, 0,
+					pixmap->drawable.depth,
+					pixmap->devKind);
     }
 nooverride:
 
@@ -575,9 +527,7 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen)
 {
     __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
 
-    screen->driScreen.destroyScreen(NULL,
-				    screen->base.pScreen->myNum,
-				    screen->driScreen.private);
+    screen->driScreen.destroyScreen(&screen->driScreen);
 
     dlclose(screen->driver);
 
@@ -593,13 +543,18 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
 {
     __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
     __GLXDRIcontext *context, *shareContext;
-    void *sharePrivate;
+    VisualPtr visual;
+    int i;
+    GLboolean retval;
+    __DRIcontext *driShare;
+    drm_context_t hwContext;
+    ScreenPtr pScreen = baseScreen->pScreen;
 
     shareContext = (__GLXDRIcontext *) baseShareContext;
     if (shareContext)
-	sharePrivate = shareContext->driContext.private;
+	driShare = &shareContext->driContext;
     else
-	sharePrivate = NULL;
+	driShare = NULL;
 
     context = xalloc(sizeof *context);
     if (context == NULL)
@@ -614,15 +569,29 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
     context->base.pScreen           = screen->base.pScreen;
 
     context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
+    /* Find the requested X visual */
+    visual = pScreen->visuals;
+    for (i = 0; i < pScreen->numVisuals; i++, visual++)
+	if (visual->vid == modes->visualID)
+	    break;
+    if (i == pScreen->numVisuals)
+	return GL_FALSE;
+
+    context->hwContextID = FakeClientID(0);
+
+    __glXenterServer(GL_FALSE);
+    retval = DRICreateContext(baseScreen->pScreen, visual,
+			      context->hwContextID, &hwContext);
+    __glXleaveServer(GL_FALSE);
 
     context->driContext.private =
-	screen->driScreen.createNewContext(NULL, modes,
+	screen->driScreen.createNewContext(&screen->driScreen,
+					   modes,
 					   0, /* render type */
-					   sharePrivate,
+					   driShare,
+					   hwContext,
 					   &context->driContext);
 
-    context->driContext.mode = modes;
-
     return &context->base;
 }
 
@@ -632,7 +601,10 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
 			     XID drawId,
 			     __GLcontextModes *modes)
 {
+    __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
     __GLXDRIdrawable *private;
+    GLboolean retval;
+    drm_drawable_t hwDrawable;
 
     private = xalloc(sizeof *private);
     if (private == NULL)
@@ -650,21 +622,19 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
     private->base.swapBuffers   = __glXDRIdrawableSwapBuffers;
     private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
 
-#if 0
-    /* FIXME: It would only be natural that we called
-     * driScreen->createNewDrawable here but the DRI drivers manage
-     * them a little oddly. FIXME: describe this better.*/
+    __glXenterServer(GL_FALSE);
+    retval = DRICreateDrawable(screen->pScreen, serverClient,
+			       pDraw, &hwDrawable);
+    __glXleaveServer(GL_FALSE);
 
     /* The last argument is 'attrs', which is used with pbuffers which
      * we currently don't support. */
 
-    glxPriv->driDrawable.private =
-	(screen->driScreen.createNewDrawable)(NULL, modes,
-					      drawId,
-					      &glxPriv->driDrawable,
-					      0,
-					      NULL);
-#endif
+    private->driDrawable.private =
+	(driScreen->driScreen.createNewDrawable)(&driScreen->driScreen,
+						 modes,
+						 &private->driDrawable,
+						 hwDrawable, 0, NULL);
 
     return &private->base;
 }
@@ -727,161 +697,31 @@ filter_modes(__GLcontextModes **server_modes,
 }
 
 
-static void
-enable_glx_extension(void *psc, const char *ext_name)
-{
-    __GLXDRIscreen * const screen = (__GLXDRIscreen *) psc;
-
-    __glXEnableExtension(screen->glx_enable_bits, ext_name);
-}
-
-
-static __DRIfuncPtr getProcAddress(const char *proc_name)
-{
-    if (strcmp(proc_name, "glxEnableExtension") == 0) {
-	return (__DRIfuncPtr) enable_glx_extension;
-    }
-
-    return NULL;
-}
-
-static __DRIscreen *findScreen(__DRInativeDisplay *dpy, int scrn)
-{
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) __glXgetActiveScreen(scrn);
-
-    return &screen->driScreen;
-}
-
-static GLboolean windowExists(__DRInativeDisplay *dpy, __DRIid draw)
-{
-    DrawablePtr pDrawable = (DrawablePtr) LookupIDByType(draw, RT_WINDOW);
-    int unused;
-    drm_clip_rect_t *pRects;
-
-    return pDrawable ? DRIGetDrawableInfo(pDrawable->pScreen, pDrawable,
-					  (unsigned*)&unused, (unsigned*)&unused,
-					  &unused, &unused, &unused, &unused,
-					  &unused, &pRects, &unused, &unused,
-					  &unused, &pRects)
-		     : GL_FALSE;
-}
-
-static GLboolean createContext(__DRInativeDisplay *dpy, int screen,
-			       int configID, void *contextID,
-			       drm_context_t *hw_context)
-{
-    XID fakeID;
-    VisualPtr visual;
-    int i;
-    ScreenPtr pScreen;
-    GLboolean retval;
-
-    pScreen = screenInfo.screens[screen];
-
-    /* Find the requested X visual */
-    visual = pScreen->visuals;
-    for (i = 0; i < pScreen->numVisuals; i++, visual++)
-	if (visual->vid == configID)
-	    break;
-    if (i == pScreen->numVisuals)
-	return GL_FALSE;
-
-    fakeID = FakeClientID(0);
-    *(XID *) contextID = fakeID;
-
-    __glXDRIenterServer(GL_FALSE);
-    retval = DRICreateContext(pScreen, visual, fakeID, hw_context);
-    __glXDRIleaveServer(GL_FALSE);
-    return retval;
-}
-
-static GLboolean destroyContext(__DRInativeDisplay *dpy, int screen,
-				__DRIid context)
-{
-    GLboolean retval;
-
-    __glXDRIenterServer(GL_FALSE);
-    retval = DRIDestroyContext(screenInfo.screens[screen], context);
-    __glXDRIleaveServer(GL_FALSE);
-    return retval;
-}
-
-static GLboolean
-createDrawable(__DRInativeDisplay *dpy, int screen,
-	       __DRIid drawable, drm_drawable_t *hHWDrawable)
-{
-    DrawablePtr pDrawable;
-    GLboolean retval;
-
-    pDrawable = (DrawablePtr) LookupIDByClass(drawable, RC_DRAWABLE);
-    if (!pDrawable)
-	return GL_FALSE;
-
-    __glXDRIenterServer(GL_FALSE);
-    retval = DRICreateDrawable(screenInfo.screens[screen], __pGlxClient,
-			       pDrawable, hHWDrawable);
-    __glXDRIleaveServer(GL_FALSE);
-    return retval;
-}
-
-static GLboolean
-destroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable)
-{
-    DrawablePtr pDrawable;
-    GLboolean retval;
-
-    pDrawable = (DrawablePtr) LookupIDByClass(drawable, RC_DRAWABLE);
-    if (!pDrawable)
-	return GL_FALSE;
-
-    __glXDRIenterServer(GL_FALSE);
-    retval = DRIDestroyDrawable(screenInfo.screens[screen], __pGlxClient,
-				pDrawable);
-    __glXDRIleaveServer(GL_FALSE);
-    return retval;
-}
+#define containerOf(ptr, type, member)			\
+    (type *)( (char *)ptr - offsetof(type,member) )
 
 static GLboolean
-getDrawableInfo(__DRInativeDisplay *dpy, int screen,
-		__DRIid drawable, unsigned int *index, unsigned int *stamp,
+getDrawableInfo(__DRIdrawable *driDrawable,
+		unsigned int *index, unsigned int *stamp,
 		int *x, int *y, int *width, int *height,
 		int *numClipRects, drm_clip_rect_t **ppClipRects,
 		int *backX, int *backY,
 		int *numBackClipRects, drm_clip_rect_t **ppBackClipRects)
 {
-    DrawablePtr pDrawable;
+    __GLXDRIdrawable *drawable = containerOf(driDrawable,
+					     __GLXDRIdrawable, driDrawable);
+    ScreenPtr pScreen = drawable->base.pDraw->pScreen;
     drm_clip_rect_t *pClipRects, *pBackClipRects;
     GLboolean retval;
     size_t size;
 
-    pDrawable = (DrawablePtr) LookupIDByClass(drawable, RC_DRAWABLE);
-    if (!pDrawable) {
-	ErrorF("getDrawableInfo failed to look up window\n");
-
-        *index = 0;
-	*stamp = 0;
-        *x = 0;
-        *y = 0;
-	*width = 0;
-	*height = 0;
-	*numClipRects = 0;
-	*ppClipRects = NULL;
-	*backX = 0;
-	*backY = 0;
-	*numBackClipRects = 0;
-	*ppBackClipRects = NULL;
-
-	return GL_FALSE;
-    }
-
-    __glXDRIenterServer(GL_FALSE);
-    retval = DRIGetDrawableInfo(screenInfo.screens[screen],
-				pDrawable, index, stamp,
+    __glXenterServer(GL_FALSE);
+    retval = DRIGetDrawableInfo(pScreen, drawable->base.pDraw, index, stamp,
 				x, y, width, height,
 				numClipRects, &pClipRects,
 				backX, backY,
 				numBackClipRects, &pBackClipRects);
-    __glXDRIleaveServer(GL_FALSE);
+    __glXleaveServer(GL_FALSE);
 
     if (*numClipRects > 0) {
 	size = sizeof (drm_clip_rect_t) * *numClipRects;
@@ -889,7 +729,6 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen,
 
 	/* Clip cliprects to screen dimensions (redirected windows) */
 	if (*ppClipRects != NULL) {
-	    ScreenPtr pScreen = screenInfo.screens[screen];
 	    int i, j;
 
 	    for (i = 0, j = 0; i < *numClipRects; i++) {
@@ -948,19 +787,9 @@ getUST(int64_t *ust)
 
 /* Table of functions that we export to the driver. */
 static const __DRIinterfaceMethods interface_methods = {
-    getProcAddress,
-
     _gl_context_modes_create,
     _gl_context_modes_destroy,
-      
-    findScreen,
-    windowExists,
-      
-    createContext,
-    destroyContext,
 
-    createDrawable,
-    destroyDrawable,
     getDrawableInfo,
 
     getUST,
@@ -996,6 +825,48 @@ glxDRILeaveVT (int index, int flags)
     return (*screen->leaveVT) (index, flags);
 }
 
+static void
+initializeExtensions(__GLXDRIscreen *screen)
+{
+    const __DRIextension **extensions;
+    int i;
+
+    extensions = screen->driScreen.getExtensions(&screen->driScreen);
+    for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_COPY_SUB_BUFFER
+	if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+	    screen->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_MESA_copy_sub_buffer");
+	    
+	    LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
+	}
+#endif
+
+#ifdef __DRI_SWAP_CONTROL
+	if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
+	    screen->swapControl = (__DRIswapControlExtension *) extensions[i];
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_SGI_swap_control");
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_MESA_swap_control");
+	    
+	    LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+	}
+#endif
+
+#ifdef __DRI_TEX_OFFSET
+	if (strcmp(extensions[i]->name, __DRI_TEX_OFFSET) == 0) {
+	    screen->texOffset = (__DRItexOffsetExtension *) extensions[i];
+	    LogMessage(X_INFO, "AIGLX: enabled GLX_texture_from_pixmap with driver support\n");
+	}
+#endif
+	/* Ignore unknown extensions */
+    }
+}
+    
+#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314
+
 static __GLXscreen *
 __glXDRIscreenProbe(ScreenPtr pScreen)
 {
@@ -1044,8 +915,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     screen->base.pScreen       = pScreen;
 
     __glXInitExtensionEnableBits(screen->glx_enable_bits);
-    screen->driScreen.screenConfigs = screen;
-
 
     /* DRI protocol version. */
     dri_version.major = XF86DRI_MAJOR_VERSION;
@@ -1170,9 +1039,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     
     driver_modes = NULL;
     screen->driScreen.private =
-	(*createNewScreen)(NULL, pScreen->myNum,
+	(*createNewScreen)(pScreen->myNum,
 			   &screen->driScreen,
-			   screen->base.modes,
 			   &ddx_version,
 			   &dri_version,
 			   &drm_version,
@@ -1191,6 +1059,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart,
 			 &screen->texOffsetFinish);
 
+    initializeExtensions(screen);
+
     __glXScreenInit(&screen->base, pScreen);
 
     buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index b35175e..5b621d3 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -145,7 +145,6 @@ static int ClientGone(int clientIndex, XID id)
 	for (i=0; i < cl->numCurrentContexts; i++) {
 	    cx = cl->currentContexts[i];
 	    if (cx) {
-		__glXDeassociateContext(cx);
 		cx->isCurrent = GL_FALSE;
 		if (!cx->idExists) {
 		    __glXFreeContext(cx);
commit 17ffc34ad5e9a8e2269afef05f209701f1895c01
Author: Matthias Hopf <mhopf at suse.de>
Date:   Fri Oct 12 15:33:31 2007 +0200

    Drivers include miscstruct.h which requires pixman.h.

diff --git a/xorg-server.pc.in b/xorg-server.pc.in
index d3ffaa2..c1cdb7d 100644
--- a/xorg-server.pc.in
+++ b/xorg-server.pc.in
@@ -8,6 +8,6 @@ sdkdir=@sdkdir@
 Name: xorg-server
 Description: Modular X.Org X Server
 Version: @PACKAGE_VERSION@
-Requires.private: pixman-1
+Requires: pixman-1
 Cflags: -I${sdkdir}
 Libs: -L${libdir}
commit eaf0e2a21c2cb14e19852e61a4521b3c240253af
Author: David Nusinow <dnusinow at debian.org>
Date:   Thu Oct 11 22:31:24 2007 -0400

    Fix another compiler warning

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 2b44e6d..a6bfc01 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -384,8 +384,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip
                                     chip = (int)strtol(chip_str, NULL, 16);
                                 }
                         }
-                        if (vendor == match_vendor && 
-                               (chip == match_chip || chip == -1)) {
+                        if (vendor == match_vendor && chip == match_chip ) {
                             i = 0;
                             while (matches[i]) {
                                 i++;
commit a5089af726b6a4f833b95a31274743c994277e20
Author: David Nusinow <dnusinow at debian.org>
Date:   Thu Oct 11 22:24:31 2007 -0400

    Fix a warning about the control logic in xchomp()

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 3630041..2b44e6d 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -284,8 +284,8 @@ xchomp(char *line)
     len = strlen(line);
     if (line[len - 1] == '\n' && len > 0) {
         line[len - 1] = '\0';
-        return 0;
     }
+    return 0;
 }
 
 GDevPtr
commit cdf29ff45a3cb45573c9d0cb8f82e6ee97953fb5
Author: David Nusinow <dnusinow at debian.org>
Date:   Thu Oct 11 22:23:34 2007 -0400

    Remove some unused variables

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 1f48b17..3630041 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -215,8 +215,6 @@ xf86AutoConfig(void)
 {
     const char **p;
     char buf[1024];
-    struct pci_device_iterator *iter;
-    struct pci_device * info = NULL;
     const char *driver = NULL;
     ConfigStatus ret;
 
@@ -294,7 +292,6 @@ GDevPtr
 autoConfigDevice(GDevPtr preconf_device)
 {
     GDevPtr ptr = NULL;
-    confScreenPtr scrn = NULL;
 
     if (!xf86configptr) {
         return NULL;
commit 3367091f7fa14497aab40e668cad179e244eef81
Author: David Nusinow <dnusinow at debian.org>
Date:   Thu Oct 11 22:21:38 2007 -0400

    Separate choosing driver from the file-based implementation
    
    This clears the implementation out of the way to prepare for development
    of a symbol-based resolution scheme

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 797334e..1f48b17 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -332,41 +332,20 @@ autoConfigDevice(GDevPtr preconf_device)
     return ptr;
 }
 
-char*
-chooseVideoDriver(void)
+static void
+matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip)
 {
-    struct pci_device * info = NULL;
-    struct pci_device_iterator *iter;
     DIR *idsdir;
     FILE *fp;
     struct dirent *direntry;
     char *line = NULL;
-    char *chosen_driver = NULL;
     size_t len;
     ssize_t read;
     char path_name[256], vendor_str[5], chip_str[5];
     uint16_t vendor, chip;
     int i, j;
-    char *matches[20]; /* If we have more than 20 drivers we're in trouble */
-    
-    for (i=0 ; i<20 ; i++)
-        matches[i] = NULL;
-
-    /* Find the primary device, and get some information about it. */
-    iter = pci_slot_match_iterator_create(NULL);
-    while ((info = pci_device_next(iter)) != NULL) {
-	if (xf86IsPrimaryPci(info)) {
-	    break;
-	}
-    }
-
-    pci_iterator_destroy(iter);
-
-    if (!info) {
-	ErrorF("Primary device is not PCI\n");
-    }
-
     idsdir = opendir("/usr/share/xserver-xorg/pci");
+
     if (idsdir) {
         direntry = readdir(idsdir);
         /* Read the directory */
@@ -408,8 +387,8 @@ chooseVideoDriver(void)
                                     chip = (int)strtol(chip_str, NULL, 16);
                                 }
                         }
-                        if (vendor == info->vendor_id && 
-                               (chip == info->device_id || chip == -1)) {
+                        if (vendor == match_vendor && 
+                               (chip == match_chip || chip == -1)) {
                             i = 0;
                             while (matches[i]) {
                                 i++;
@@ -442,6 +421,38 @@ chooseVideoDriver(void)
             direntry = readdir(idsdir);
         }
     }
+    end:
+    xfree(line);
+    closedir(idsdir);
+}
+
+char*
+chooseVideoDriver(void)
+{
+    struct pci_device * info = NULL;
+    struct pci_device_iterator *iter;
+    char *chosen_driver = NULL;
+    int i;
+    char *matches[20]; /* If we have more than 20 drivers we're in trouble */
+    
+    for (i=0 ; i<20 ; i++)
+        matches[i] = NULL;
+
+    /* Find the primary device, and get some information about it. */
+    iter = pci_slot_match_iterator_create(NULL);
+    while ((info = pci_device_next(iter)) != NULL) {
+	if (xf86IsPrimaryPci(info)) {
+	    break;
+	}
+    }
+
+    pci_iterator_destroy(iter);
+
+    if (!info) {
+	ErrorF("Primary device is not PCI\n");
+    }
+
+    matchDriverFromFiles(matches, info->vendor_id, info->device_id);
 
     /* TODO Handle multiple drivers claiming to support the same PCI ID */
     if (matches[0]) {
@@ -463,7 +474,6 @@ chooseVideoDriver(void)
 
     xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver);
 
-    end:
     i = 0;
     while (matches[i]) {
         if (matches[i] != chosen_driver) {
@@ -471,8 +481,6 @@ chooseVideoDriver(void)
         }
         i++;
     }
-    xfree(line);
-    closedir(idsdir);
 
     return chosen_driver;
 }
commit 3aa41bcb8215c037512ddbd68a3f7bcad3b80a1f
Author: David Nusinow <dnusinow at debian.org>
Date:   Thu Oct 11 21:29:13 2007 -0400

    Remove obsolete error message define from parser

diff --git a/hw/xfree86/parser/Configint.h b/hw/xfree86/parser/Configint.h
index 1440cbb..4d5fbcf 100644
--- a/hw/xfree86/parser/Configint.h
+++ b/hw/xfree86/parser/Configint.h
@@ -186,8 +186,6 @@ else\
 "The Inactive keyword must be followed by a Device name in quotes."
 #define UNDEFINED_SCREEN_MSG \
 "Undefined Screen \"%s\" referenced by ServerLayout \"%s\"."
-#define UNDEFINED_MONITOR_MSG \
-"Undefined Monitor \"%s\" referenced by Screen \"%s\"."
 #define UNDEFINED_MODES_MSG \
 "Undefined Modes Section \"%s\" referenced by Monitor \"%s\"."
 #define UNDEFINED_DEVICE_MSG \
commit e3e12221111886c4063d2da5d70d3830c56d39e2
Author: David Nusinow <dnusinow at debian.org>
Date:   Thu Oct 11 21:27:07 2007 -0400

    Don't bother validating the Device section of the conf file
    
    All the previous tests can now be recovered from if not specified.

diff --git a/hw/xfree86/parser/Configint.h b/hw/xfree86/parser/Configint.h
index c20c195..1440cbb 100644
--- a/hw/xfree86/parser/Configint.h
+++ b/hw/xfree86/parser/Configint.h
@@ -204,8 +204,6 @@ else\
 "This section must have an Identifier line."
 #define ONLY_ONE_MSG \
 "This section must have only one of either %s line."
-#define UNDEFINED_DRIVER_MSG \
-"Device section \"%s\" must have a Driver line."
 #define UNDEFINED_INPUTDRIVER_MSG \
 "InputDevice section \"%s\" must have a Driver line."
 #define INVALID_GAMMA_MSG \
diff --git a/hw/xfree86/parser/Device.c b/hw/xfree86/parser/Device.c
index 6ad5601..216789f 100644
--- a/hw/xfree86/parser/Device.c
+++ b/hw/xfree86/parser/Device.c
@@ -357,26 +357,6 @@ xf86freeDeviceList (XF86ConfDevicePtr ptr)
 	}
 }
 
-int
-xf86validateDevice (XF86ConfigPtr p)
-{
-	XF86ConfDevicePtr device = p->conf_device_lst;
-
-	if (!device) {
-		xf86validationError ("At least one Device section is required.");
-		return (FALSE);
-	}
-
-	while (device) {
-		if (!device->dev_driver) {
-			xf86validationError (UNDEFINED_DRIVER_MSG, device->dev_identifier);
-			return (FALSE);
-		}
-	device = device->list.next;
-	}
-	return (TRUE);
-}
-
 XF86ConfDevicePtr
 xf86findDevice (const char *ident, XF86ConfDevicePtr p)
 {
diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c
index 308ee03..430da0a 100644
--- a/hw/xfree86/parser/read.c
+++ b/hw/xfree86/parser/read.c
@@ -80,8 +80,6 @@ static xf86ConfigSymTabRec TopLevelTab[] =
 static int
 xf86validateConfig (XF86ConfigPtr p)
 {
-	/*if (!xf86validateDevice (p))
-		return FALSE;*/
 	if (!xf86validateScreen (p))
 		return FALSE;
 	if (!xf86validateInput (p))
commit 28ef7f59416677be380561709197b04df0479bef
Author: David Nusinow <dnusinow at debian.org>
Date:   Thu Oct 11 20:56:46 2007 -0400

    Re-enable validation of the screen section of xorg.conf
    
    This also fixes a problem where the server can't find the device section
    when it is specified in the screen section.

diff --git a/hw/xfree86/parser/Screen.c b/hw/xfree86/parser/Screen.c
index 4df2b05..4524f17 100644
--- a/hw/xfree86/parser/Screen.c
+++ b/hw/xfree86/parser/Screen.c
@@ -498,12 +498,6 @@ xf86validateScreen (XF86ConfigPtr p)
 	XF86ConfDevicePtr device;
 	XF86ConfAdaptorLinkPtr adaptor;
 
-	if (!screen)
-	{
-		xf86validationError ("At least one Screen section is required.");
-		return (FALSE);
-	}
-
 	while (screen)
 	{
 		if (screen->scrn_obso_driver && !screen->scrn_identifier)
@@ -512,13 +506,7 @@ xf86validateScreen (XF86ConfigPtr p)
 		monitor = xf86findMonitor (screen->scrn_monitor_str, p->conf_monitor_lst);
 		if (screen->scrn_monitor_str)
 		{
-			if (!monitor)
-			{
-				xf86validationError (UNDEFINED_MONITOR_MSG,
-						 	screen->scrn_monitor_str, screen->scrn_identifier);
-				return (FALSE);
-			}
-			else
+			if (monitor)
 			{
 				screen->scrn_monitor = monitor;
 				if (!xf86validateMonitor(p, screen))
diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c
index a272f5c..308ee03 100644
--- a/hw/xfree86/parser/read.c
+++ b/hw/xfree86/parser/read.c
@@ -82,8 +82,8 @@ xf86validateConfig (XF86ConfigPtr p)
 {
 	/*if (!xf86validateDevice (p))
 		return FALSE;*/
-	/*if (!xf86validateScreen (p))
-		return FALSE;*/
+	if (!xf86validateScreen (p))
+		return FALSE;
 	if (!xf86validateInput (p))
 		return FALSE;
 	if (!xf86validateLayout (p))
commit ea2d4dc468dcebe6d38e676469ec51ed1d43490b
Author: David Nusinow <dnusinow at debian.org>
Date:   Thu Oct 11 20:26:02 2007 -0400

    When there's no xorg.conf, use the video driver autoloading function

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index bf41c4d..797334e 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -220,22 +220,7 @@ xf86AutoConfig(void)
     const char *driver = NULL;
     ConfigStatus ret;
 
-    /* Find the primary device, and get some information about it. */
-    iter = pci_slot_match_iterator_create(NULL);
-    while ((info = pci_device_next(iter)) != NULL) {
-	if (xf86IsPrimaryPci(info)) {
-	    break;
-	}
-    }
-
-    pci_iterator_destroy(iter);
-
-    if (!info) {
-	ErrorF("Primary device is not PCI\n");
-    }
-
-    if (info)
-	driver = videoPtrToDriverName(info);
+    driver = chooseVideoDriver();
 
     AppendToConfig(BUILTIN_MODULE_SECTION);
     AppendToConfig(BUILTIN_MONITOR_SECTION);
commit fc092334ac0a323b80a9602cb8bf60ca9dee3bfa
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Oct 11 16:48:56 2007 -0700

    Bug #10304,12784,11603: Add quirks for several physical size issues.
    
    A lot of EDID writers apparently end up stuffing centimeters (like the
    maximum image size field) into the detailed timings, instead of millimeters.
    Some of them only get it wrong in one direction.  Also, add a quirk to let
    us mark the largest 75hz mode as preferred, which will often be used for
    EDID 1.0 CRTs.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 064ff16..f589b5a 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2134,8 +2134,12 @@ _X_EXPORT xf86MonPtr
 xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
 {
     ScrnInfoPtr	scrn = output->scrn;
+    xf86MonPtr mon;
 
-    return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
+    mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
+    xf86DDCApplyQuirks (scrn->scrnIndex, pDDCBus);
+
+    return mon;
 }
 
 static char *_xf86ConnectorNames[] = { "None", "VGA", "DVI-I", "DVI-D",
diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 8b5e69d..9fa5fef 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -54,6 +54,16 @@ typedef enum {
     DDC_QUIRK_PREFER_LARGE_60 = 1 << 0,
     /* 135MHz clock is too high, drop a bit */
     DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 1,
+    /* Prefer the largest mode at 75 Hz */
+    DDC_QUIRK_PREFER_LARGE_75 = 1 << 2,
+    /* Convert detailed timing's horizontal from units of cm to mm */
+    DDC_QUIRK_DETAILED_H_IN_CM = 1 << 3,
+    /* Convert detailed timing's vertical from units of cm to mm */
+    DDC_QUIRK_DETAILED_V_IN_CM = 1 << 4,
+    /* Detailed timing descriptors have bogus size values, so just take the
+     * maximum size and use that.
+     */
+    DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5,
 } ddc_quirk_t;
 
 static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
@@ -81,6 +91,52 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
     return FALSE;
 }
 
+static Bool quirk_prefer_large_75 (int scrnIndex, xf86MonPtr DDC)
+{
+    /* Bug #11603: Funai Electronics PM36B */
+    if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
+	DDC->vendor.prod_id == 13600)
+	return TRUE;
+
+    return FALSE;
+}
+
+static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC)
+{
+    /* Bug #10304: "LGPhilipsLCD LP154W01-A5" */
+    /* Bug #12784: "LGPhilipsLCD LP154W01-TLA2" */
+    if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
+	DDC->vendor.prod_id == 0)
+	return TRUE;
+
+    /* Bug #11603: Funai Electronics PM36B */
+    if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
+	DDC->vendor.prod_id == 13600)
+	return TRUE;
+
+    return FALSE;
+}
+
+static Bool quirk_detailed_v_in_cm (int scrnIndex, xf86MonPtr DDC)
+{
+    /* Bug #11603: Funai Electronics PM36B */
+    if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
+	DDC->vendor.prod_id == 13600)
+	return TRUE;
+
+    return FALSE;
+}
+
+static Bool quirk_detailed_use_maximum_size (int scrnIndex, xf86MonPtr DDC)
+{
+    /* Bug #10304: LGPhilipsLCD LP154W01-A5 */
+    if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
+	DDC->vendor.prod_id == 0)
+	return TRUE;
+
+    return FALSE;
+}
+
 static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
 {
     /* Envision Peripherals, Inc. EN-7100e.  See bug #9550. */
@@ -106,6 +162,22 @@ static const ddc_quirk_map_t ddc_quirks[] = {
 	quirk_135_clock_too_high,   DDC_QUIRK_135_CLOCK_TOO_HIGH,
 	"Recommended 135MHz pixel clock is too high"
     },
+    {
+	quirk_prefer_large_75,   DDC_QUIRK_PREFER_LARGE_75,
+	"Detailed timing is not preferred, use largest mode at 75Hz"
+    },
+    {
+	quirk_detailed_h_in_cm,   DDC_QUIRK_DETAILED_H_IN_CM,
+	"Detailed timings give horizontal size in cm."
+    },
+    {
+	quirk_detailed_v_in_cm,   DDC_QUIRK_DETAILED_V_IN_CM,
+	"Detailed timings give vertical size in cm."
+    },
+    {
+	quirk_detailed_use_maximum_size,   DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE,
+	"Detailed timings give sizes in cm."
+    },
     { 
 	NULL,		DDC_QUIRK_NONE,
 	"No known quirks"
@@ -303,6 +375,98 @@ DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
     }
 }
 
+static ddc_quirk_t
+xf86DDCDetectQuirks(int scrnIndex, xf86MonPtr DDC, Bool verbose)
+{
+    ddc_quirk_t	quirks;
+    int i;
+
+    quirks = DDC_QUIRK_NONE;
+    for (i = 0; ddc_quirks[i].detect; i++) {
+	if (ddc_quirks[i].detect (scrnIndex, DDC)) {
+	    if (verbose) {
+		xf86DrvMsg (scrnIndex, X_INFO, "    EDID quirk: %s\n",
+			    ddc_quirks[i].description);
+	    }
+	    quirks |= ddc_quirks[i].quirk;
+	}
+    }
+
+    return quirks;
+}
+
+/**
+ * Applies monitor-specific quirks to the decoded EDID information.
+ *
+ * Note that some quirks applying to the mode list are still implemented in
+ * xf86DDCGetModes.
+ */
+void
+xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC)
+{
+    ddc_quirk_t quirks = xf86DDCDetectQuirks (scrnIndex, DDC, FALSE);
+    int i;
+
+    for (i = 0; i < DET_TIMINGS; i++) {
+	struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
+
+	if (det_mon->type != DT)
+	    continue;
+
+	if (quirks & DDC_QUIRK_DETAILED_H_IN_CM)
+	    det_mon->section.d_timings.h_size *= 10;
+
+	if (quirks & DDC_QUIRK_DETAILED_V_IN_CM)
+	    det_mon->section.d_timings.v_size *= 10;
+
+	if (quirks & DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
+	    det_mon->section.d_timings.h_size = 10 * DDC->features.hsize;
+	    det_mon->section.d_timings.v_size = 10 * DDC->features.vsize;
+	}
+    }
+}
+
+/**
+ * Walks the modes list, finding the mode with the largest area which is
+ * closest to the target refresh rate, and marks it as the only preferred mode.
+*/
+static void
+xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes,
+			   float target_refresh)
+{
+	DisplayModePtr	mode, best = modes;
+
+	for (mode = modes; mode; mode = mode->next)
+	{
+	    mode->type &= ~M_T_PREFERRED;
+
+	    if (mode == best) continue;
+
+	    if (mode->HDisplay * mode->VDisplay >
+		best->HDisplay * best->VDisplay)
+	    {
+		best = mode;
+		continue;
+	    }
+	    if (mode->HDisplay * mode->VDisplay ==
+		best->HDisplay * best->VDisplay)
+	    {
+		double	mode_refresh = xf86ModeVRefresh (mode);
+		double	best_refresh = xf86ModeVRefresh (best);
+		double	mode_dist = fabs(mode_refresh - target_refresh);
+		double	best_dist = fabs(best_refresh - target_refresh);
+
+		if (mode_dist < best_dist)
+		{
+		    best = mode;
+		    continue;
+		}
+	    }
+	}
+	if (best)
+	    best->type |= M_T_PREFERRED;
+}
+
 _X_EXPORT DisplayModePtr
 xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
 {
@@ -312,15 +476,9 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
 
     xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
 		DDC->vendor.name, DDC->vendor.prod_id);
-    quirks = DDC_QUIRK_NONE;
-    for (i = 0; ddc_quirks[i].detect; i++)
-	if (ddc_quirks[i].detect (scrnIndex, DDC))
-	{
-	    xf86DrvMsg (scrnIndex, X_INFO, "    EDID quirk: %s\n",
-			ddc_quirks[i].description);
-	    quirks |= ddc_quirks[i].quirk;
-	}
-    
+
+    quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE);
+
     preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
     if (quirks & DDC_QUIRK_PREFER_LARGE_60)
 	preferred = 0;
@@ -357,32 +515,11 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
     Modes = xf86ModesAdd(Modes, Mode);
 
     if (quirks & DDC_QUIRK_PREFER_LARGE_60)
-    {
-	DisplayModePtr	best = Modes;
-	for (Mode = Modes; Mode; Mode = Mode->next)
-	{
-	    if (Mode == best) continue;
-	    if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay)
-	    {
-		best = Mode;
-		continue;
-	    }
-	    if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay)
-	    {
-		double	mode_refresh = xf86ModeVRefresh (Mode);
-		double	best_refresh = xf86ModeVRefresh (best);
-		double	mode_dist = fabs(mode_refresh - 60.0);
-		double	best_dist = fabs(best_refresh - 60.0);
-		if (mode_dist < best_dist)
-		{
-		    best = Mode;
-		    continue;
-		}
-	    }
-	}
-	if (best)
-	    best->type |= M_T_PREFERRED;
-    }
+	xf86DDCSetPreferredRefresh(scrnIndex, Modes, 60);
+
+    if (quirks & DDC_QUIRK_PREFER_LARGE_75)
+	xf86DDCSetPreferredRefresh(scrnIndex, Modes, 75);
+
     return Modes;
 }
 
diff --git a/hw/xfree86/modes/xf86Modes.h b/hw/xfree86/modes/xf86Modes.h
index 2bd4ede..3722d25 100644
--- a/hw/xfree86/modes/xf86Modes.h
+++ b/hw/xfree86/modes/xf86Modes.h
@@ -95,4 +95,7 @@ xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
 DisplayModePtr
 xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
 
+void
+xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC);
+
 #endif /* _XF86MODES_H_ */
commit 45cc03726b49f6ad4afe6c3fb4ad65d1051928b4
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu Oct 11 18:23:25 2007 +0200

    Make mode checking more tolerant like in pre-RandR times.

diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c
index f49c292..9981789 100644
--- a/hw/xfree86/modes/xf86Modes.c
+++ b/hw/xfree86/modes/xf86Modes.c
@@ -389,8 +389,8 @@ xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
 
 	bad = TRUE;
 	for (i = 0; i < mon->nHsync; i++) {
-	    if (xf86ModeHSync(mode) >= mon->hsync[i].lo &&
-		xf86ModeHSync(mode) <= mon->hsync[i].hi)
+	    if (xf86ModeHSync(mode) >= mon->hsync[i].lo * (1-SYNC_TOLERANCE) &&
+		xf86ModeHSync(mode) <= mon->hsync[i].hi * (1+SYNC_TOLERANCE))
 	    {
 		bad = FALSE;
 	    }
@@ -400,8 +400,8 @@ xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
 
 	bad = TRUE;
 	for (i = 0; i < mon->nVrefresh; i++) {
-	    if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo &&
-		xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi)
+	    if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo * (1-SYNC_TOLERANCE) &&
+		xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi * (1+SYNC_TOLERANCE))
 	    {
 		bad = FALSE;
 	    }
@@ -434,7 +434,8 @@ xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
     for (mode = modeList; mode != NULL; mode = mode->next) {
 	Bool good = FALSE;
 	for (i = 0; i < n_ranges; i++) {
-	    if (mode->Clock >= min[i] && mode->Clock <= max[i]) {
+	    if (mode->Clock >= min[i] * (1-SYNC_TOLERANCE) &&
+		mode->Clock <= max[i] * (1+SYNC_TOLERANCE)) {
 		good = TRUE;
 		break;
 	    }
commit 8825d36a38c76ff8faf409c853061be2bd33430d
Author: David Nusinow <dnusinow at debian.org>
Date:   Tue Oct 9 22:49:07 2007 -0400

    Allow the user to not have a screen section
    
    If none is present, a default one will be created. This will be attached
    to either the first device section in the xorg.conf (allowing you to
    specify something like using EXA without having a screen section) or a
    default screen section if none is present in the file.

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 9629df5..9c54bf4 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1813,11 +1813,6 @@ configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen)
     if (!servlayoutp)
 	return FALSE;
 
-    if (conf_screen == NULL) {
-	xf86ConfigError("No Screen sections present\n");
-	return FALSE;
-    }
-
     /*
      * which screen section is the active one?
      *
@@ -1905,6 +1900,12 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
     XF86ConfAdaptorLinkPtr conf_adaptor;
     Bool defaultMonitor = FALSE;
 
+    if (!conf_screen) {
+        conf_screen = xnfcalloc(1, sizeof(XF86ConfScreenRec));
+        conf_screen->scrn_identifier = "Default Screen Section";
+        xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
+    }
+
     xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
 	    scrnum);
     /*
diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c
index 308ee03..a272f5c 100644
--- a/hw/xfree86/parser/read.c
+++ b/hw/xfree86/parser/read.c
@@ -82,8 +82,8 @@ xf86validateConfig (XF86ConfigPtr p)
 {
 	/*if (!xf86validateDevice (p))
 		return FALSE;*/
-	if (!xf86validateScreen (p))
-		return FALSE;
+	/*if (!xf86validateScreen (p))
+		return FALSE;*/
 	if (!xf86validateInput (p))
 		return FALSE;
 	if (!xf86validateLayout (p))
commit 8665cf3327b713f334b0483593a924c197f892f2
Author: David Nusinow <dnusinow at debian.org>
Date:   Tue Oct 9 22:45:15 2007 -0400

    Don't require that the screen explicitly attach the device section
    
    This will allow the screen to not explicitly have a device section. If
    this is the case and there is a device section in the xorg.conf, the first
    one will be used. If there is no device section at all, a default one will
    be created that loads the automatically determined module.

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 1b99e95..9629df5 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1939,11 +1939,20 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
 	if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
 	    return FALSE;
     }
+    /* Configure the device. If there isn't one configured, attach to the
+     * first inactive one that we can configure. If there's none that work,
+     * set it to NULL so that the section can be autoconfigured later */
     screenp->device     = xnfcalloc(1, sizeof(GDevRec));
-    if (configDevice(screenp->device,conf_screen->scrn_device, TRUE))
+    if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
+        conf_screen->scrn_device = xf86configptr->conf_device_lst;
+	xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
+		"\tUsing the first device section listed.\n", screenp->id);
+    }
+    if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
         screenp->device->myScreenSection = screenp;
-    else
+    } else {
         screenp->device = NULL;
+    }
     screenp->options = conf_screen->scrn_option_lst;
     
     /*
commit 37898b824fdc94735495e3494aa2b9a681d477b9
Author: David Nusinow <dnusinow at debian.org>
Date:   Tue Oct 9 22:11:58 2007 -0400

    Use the best guess heuristic as a fallback for autoloading
    
    This prevents breaking the current behavior

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 9624d92..bf41c4d 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -462,6 +462,8 @@ chooseVideoDriver(void)
     if (matches[0]) {
         chosen_driver = matches[0];
     } else {
+	chosen_driver = videoPtrToDriverName(info);
+    #if 0 /* Save for later */
         #if defined  __i386__ || defined __amd64__ || defined __hurd__
         chosen_driver = "vesa";
         #elif defined __alpha__
@@ -471,6 +473,7 @@ chooseVideoDriver(void)
         #else 
         chosen_driver = "fbdev";
         #endif
+    #endif
     }
 
     xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver);
commit 847fbbf4d25132e6c1f99fcf82fe757dbca94a34
Author: David Nusinow <dnusinow at debian.org>
Date:   Tue Oct 9 22:07:49 2007 -0400

    Fix autoloading of drivers for pci-rework

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 85fbc05..9624d92 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -350,7 +350,8 @@ autoConfigDevice(GDevPtr preconf_device)
 char*
 chooseVideoDriver(void)
 {
-    pciVideoPtr *pciptr, info = NULL;
+    struct pci_device * info = NULL;
+    struct pci_device_iterator *iter;
     DIR *idsdir;
     FILE *fp;
     struct dirent *direntry;
@@ -359,7 +360,7 @@ chooseVideoDriver(void)
     size_t len;
     ssize_t read;
     char path_name[256], vendor_str[5], chip_str[5];
-    int vendor, chip;
+    uint16_t vendor, chip;
     int i, j;
     char *matches[20]; /* If we have more than 20 drivers we're in trouble */
     
@@ -367,22 +368,17 @@ chooseVideoDriver(void)
         matches[i] = NULL;
 
     /* Find the primary device, and get some information about it. */
-    if (xf86PciVideoInfo) {
-	    for (pciptr = xf86PciVideoInfo; (info = *pciptr); pciptr++) {
-	        if (xf86IsPrimaryPci(info)) {
-	    	break;
-	        }
-	    }
-	    if (!info) {
-	        ErrorF("Primary device is not PCI\n");
-	    }
-    } else {
-        ErrorF("xf86PciVideoInfo is not set\n");
+    iter = pci_slot_match_iterator_create(NULL);
+    while ((info = pci_device_next(iter)) != NULL) {
+	if (xf86IsPrimaryPci(info)) {
+	    break;
+	}
     }
 
+    pci_iterator_destroy(iter);
+
     if (!info) {
-        ErrorF("Could not get primary PCI info\n");
-        goto end;
+	ErrorF("Primary device is not PCI\n");
     }
 
     idsdir = opendir("/usr/share/xserver-xorg/pci");
@@ -427,8 +423,8 @@ chooseVideoDriver(void)
                                     chip = (int)strtol(chip_str, NULL, 16);
                                 }
                         }
-                        if (vendor == info->vendor && 
-                               (chip == info->chipType || chip == -1)) {
+                        if (vendor == info->vendor_id && 
+                               (chip == info->device_id || chip == -1)) {
                             i = 0;
                             while (matches[i]) {
                                 i++;
commit 6033d8150be3a115b90226eaa42f237bb0cf3369
Author: David Nusinow <dnusinow at debian.org>
Date:   Tue Oct 9 21:17:27 2007 -0400

    First pass at improved video driver autoloading
    
    This is what we're currently shipping in Debian. Enables the ability for
    drivers to ship a text file listing PCI ID's they support, and have the
    server read them on startup when no driver is specified. This works, but
    isn't the final solution.

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 89afafc..85fbc05 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -39,6 +39,7 @@
 #include "xf86Config.h"
 #include "xf86Priv.h"
 #include "xf86_OSlib.h"
+#include "dirent.h"
 
 /* Sections for the default built-in configuration. */
 
@@ -287,3 +288,207 @@ xf86AutoConfig(void)
 
     return (ret == CONFIG_OK);
 }
+
+int 
+xchomp(char *line)
+{
+    size_t len = 0;
+
+    if (!line) {
+        return 1;
+    }
+
+    len = strlen(line);
+    if (line[len - 1] == '\n' && len > 0) {
+        line[len - 1] = '\0';
+        return 0;
+    }
+}
+
+GDevPtr
+autoConfigDevice(GDevPtr preconf_device)
+{
+    GDevPtr ptr = NULL;
+    confScreenPtr scrn = NULL;
+
+    if (!xf86configptr) {
+        return NULL;
+    }
+
+    /* If there's a configured section with no driver chosen, use it */
+    if (preconf_device) {
+        ptr = preconf_device;
+    } else {
+        ptr = (GDevPtr)xalloc(sizeof(GDevRec));
+        if (!ptr) {
+            return NULL;
+        }
+        memset((GDevPtr)ptr, 0, sizeof(GDevRec));
+        ptr->chipID = -1;
+        ptr->chipRev = -1;
+        ptr->irq = -1;
+
+        ptr->active = TRUE;
+        ptr->claimed = FALSE;
+        ptr->identifier = "Autoconfigured Video Device";
+        ptr->driver = NULL;
+    }
+    if (!ptr->driver) {
+        ptr->driver = chooseVideoDriver();
+    }
+
+    /* TODO Handle multiple screen sections */
+    if (xf86ConfigLayout.screens && !xf86ConfigLayout.screens->screen->device) {   
+        xf86ConfigLayout.screens->screen->device = ptr;
+        ptr->myScreenSection = xf86ConfigLayout.screens->screen;
+    }
+    xf86Msg(X_DEFAULT, "Assigned the driver to the xf86ConfigLayout\n");
+
+    return ptr;
+}
+
+char*
+chooseVideoDriver(void)
+{
+    pciVideoPtr *pciptr, info = NULL;
+    DIR *idsdir;
+    FILE *fp;
+    struct dirent *direntry;
+    char *line = NULL;
+    char *chosen_driver = NULL;
+    size_t len;
+    ssize_t read;
+    char path_name[256], vendor_str[5], chip_str[5];
+    int vendor, chip;
+    int i, j;
+    char *matches[20]; /* If we have more than 20 drivers we're in trouble */
+    
+    for (i=0 ; i<20 ; i++)
+        matches[i] = NULL;
+
+    /* Find the primary device, and get some information about it. */
+    if (xf86PciVideoInfo) {
+	    for (pciptr = xf86PciVideoInfo; (info = *pciptr); pciptr++) {
+	        if (xf86IsPrimaryPci(info)) {
+	    	break;
+	        }
+	    }
+	    if (!info) {
+	        ErrorF("Primary device is not PCI\n");
+	    }
+    } else {
+        ErrorF("xf86PciVideoInfo is not set\n");
+    }
+
+    if (!info) {
+        ErrorF("Could not get primary PCI info\n");
+        goto end;
+    }
+
+    idsdir = opendir("/usr/share/xserver-xorg/pci");
+    if (idsdir) {
+        direntry = readdir(idsdir);
+        /* Read the directory */
+        while (direntry) {
+            if (direntry->d_name[0] == '.') {
+                direntry = readdir(idsdir);
+                continue;
+            }
+            len = strlen(direntry->d_name);
+            /* A tiny bit of sanity checking. We should probably do better */
+            if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) {
+                /* We need the full path name to open the file */
+                strncpy(path_name, "/usr/share/xserver-xorg/pci/", 256);
+                strncat(path_name, direntry->d_name, (256 - strlen(path_name)));
+                fp = fopen(path_name, "r");
+                if (fp == NULL) {
+                    xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name);
+                    goto end;
+                }
+                /* Read the file */
+                while ((read = getline(&line, &len, fp)) != -1) {
+                    xchomp(line);
+                    if (isdigit(line[0])) {
+                        strncpy(vendor_str, line, 4);
+                        vendor_str[4] = '\0';
+                        vendor = (int)strtol(vendor_str, NULL, 16);
+                        if ((strlen(&line[4])) == 0) {
+                                chip_str[0] = '\0';
+                                chip = -1;
+                        } else {
+                                /* Handle trailing whitespace */
+                                if (isspace(line[4])) {
+                                    chip_str[0] = '\0';
+                                    chip = -1;
+                                } else {
+                                /* Ok, it's a real ID */
+                                    strncpy(chip_str, &line[4], 4);
+                                    chip_str[4] = '\0';
+                                    chip = (int)strtol(chip_str, NULL, 16);
+                                }
+                        }
+                        if (vendor == info->vendor && 
+                               (chip == info->chipType || chip == -1)) {
+                            i = 0;
+                            while (matches[i]) {
+                                i++;
+                            }
+                            matches[i] = (char*)xalloc(sizeof(char) * strlen(direntry->d_name) -  3);
+                            if (!matches[i]) {
+                                xf86Msg(X_ERROR, "Could not allocate space for the module name. Exiting.\n");
+                                goto end;
+                            }
+                            /* hack off the .ids suffix. This should guard
+                             * against other problems, but it will end up
+                             * taking off anything after the first '.' */
+                            for (j = 0; j < (strlen(direntry->d_name) - 3) ; j++) {
+                                if (direntry->d_name[j] == '.') {
+                                    matches[i][j] = '\0';
+                                    break;
+                                } else {
+                                    matches[i][j] = direntry->d_name[j];
+                                }
+                            }
+                            xf86Msg(X_INFO, "Matched %s from file name %s in autoconfig\n", matches[i], direntry->d_name);
+
+                        }
+                    } else {
+                        /* TODO Handle driver overrides here */
+                    }
+                }
+                fclose(fp);
+            }
+            direntry = readdir(idsdir);
+        }
+    }
+
+    /* TODO Handle multiple drivers claiming to support the same PCI ID */
+    if (matches[0]) {
+        chosen_driver = matches[0];
+    } else {
+        #if defined  __i386__ || defined __amd64__ || defined __hurd__
+        chosen_driver = "vesa";
+        #elif defined __alpha__
+        chosen_driver = "vga";
+        #elif defined __sparc__
+        chosen_driver = "sunffb";
+        #else 
+        chosen_driver = "fbdev";
+        #endif
+    }
+
+    xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver);
+
+    end:
+    i = 0;
+    while (matches[i]) {
+        if (matches[i] != chosen_driver) {
+            xfree(matches[i]);
+        }
+        i++;
+    }
+    xfree(line);
+    closedir(idsdir);
+
+    return chosen_driver;
+}
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 71e0080..1b99e95 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1940,8 +1940,10 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
 	    return FALSE;
     }
     screenp->device     = xnfcalloc(1, sizeof(GDevRec));
-    configDevice(screenp->device,conf_screen->scrn_device, TRUE);
-    screenp->device->myScreenSection = screenp;
+    if (configDevice(screenp->device,conf_screen->scrn_device, TRUE))
+        screenp->device->myScreenSection = screenp;
+    else
+        screenp->device = NULL;
     screenp->options = conf_screen->scrn_option_lst;
     
     /*
@@ -2230,13 +2232,17 @@ configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
 {
     int i;
 
+    if (!conf_device) {
+        return FALSE;
+    }
+
     if (active)
 	xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
 		conf_device->dev_identifier);
     else
 	xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
 		conf_device->dev_identifier);
-	
+
     devicep->identifier = conf_device->dev_identifier;
     devicep->vendor = conf_device->dev_vendor;
     devicep->board = conf_device->dev_board;
diff --git a/hw/xfree86/common/xf86Config.h b/hw/xfree86/common/xf86Config.h
index b8b5fd4..a174e46 100644
--- a/hw/xfree86/common/xf86Config.h
+++ b/hw/xfree86/common/xf86Config.h
@@ -34,6 +34,8 @@
 #define _xf86_config_h
 
 #include "xf86Optrec.h"
+#include "xf86Parser.h"
+#include "xf86str.h"
 
 #ifdef HAVE_PARSER_DECLS
 /*
@@ -65,5 +67,8 @@ Bool xf86BuiltinInputDriver(const char *);
 ConfigStatus xf86HandleConfigFile(Bool);
 
 Bool xf86AutoConfig(void);
+GDevPtr autoConfigDevice(GDevPtr preconf_device);
+char* chooseVideoDriver(void);
+int xchomp(char *line);
 
 #endif /* _xf86_config_h */
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 2f1651c..bf577e6 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -572,6 +572,16 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
     }
 
     /* Load all driver modules specified in the config file */
+    /* If there aren't any specified in the config file, autoconfig them */
+    /* FIXME: Does not handle multiple active screen sections, but I'm not
+     * sure if we really want to handle that case*/
+    GDevPtr configured_device = xf86ConfigLayout.screens->screen->device;
+    if ((!configured_device) || (!configured_device->driver)) {
+        if (!autoConfigDevice(configured_device)) {
+            xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
+            return ;
+        }
+    }
     if ((modulelist = xf86DriverlistFromConfig())) {
       xf86LoadModules(modulelist, NULL);
       xfree(modulelist);
diff --git a/hw/xfree86/parser/Screen.c b/hw/xfree86/parser/Screen.c
index 79e1d24..4df2b05 100644
--- a/hw/xfree86/parser/Screen.c
+++ b/hw/xfree86/parser/Screen.c
@@ -526,15 +526,7 @@ xf86validateScreen (XF86ConfigPtr p)
 			}
 		}
 
-		device = xf86findDevice (screen->scrn_device_str, p->conf_device_lst);
-		if (!device)
-		{
-			xf86validationError (UNDEFINED_DEVICE_MSG,
-						  screen->scrn_device_str, screen->scrn_identifier);
-			return (FALSE);
-		}
-		else
-			screen->scrn_device = device;
+		screen->scrn_device= xf86findDevice (screen->scrn_device_str, p->conf_device_lst);
 
 		adaptor = screen->scrn_adaptor_lst;
 		while (adaptor)
diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c
index 9f79696..308ee03 100644
--- a/hw/xfree86/parser/read.c
+++ b/hw/xfree86/parser/read.c
@@ -80,8 +80,8 @@ static xf86ConfigSymTabRec TopLevelTab[] =
 static int
 xf86validateConfig (XF86ConfigPtr p)
 {
-	if (!xf86validateDevice (p))
-		return FALSE;
+	/*if (!xf86validateDevice (p))
+		return FALSE;*/
 	if (!xf86validateScreen (p))
 		return FALSE;
 	if (!xf86validateInput (p))
commit 81d7b81146224f2b83278f5e21b3f9a36f30bd56
Author: David Nusinow <dnusinow at debian.org>
Date:   Sat Aug 25 15:00:30 2007 -0400

    Load intel instead of i810 when autoconfiguring

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 4bdf1ce..89afafc 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -174,7 +174,7 @@ videoPtrToDriverName(struct pci_device *dev)
 	case 0x8086:
 	    if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800))
 		return "i740";
-	    else return "i810";
+	    else return "intel";
 	case 0x102b:		    return "mga";
 	case 0x10c8:		    return "neomagic";
 	case 0x105d:		    return "i128";
commit fdef7be5c8d5989e0aa453d0a5b86d0a6952e960
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Tue Oct 9 18:44:04 2007 -0700

    Sun bug 6589829: include zoneid of shm segment in access policy for MIT-SHM
    
    <http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6589829>
    <http://www.opensolaris.org/os/community/arc/caselog/2007/500/>

diff --git a/Xext/shm.c b/Xext/shm.c
index 7fa8349..a688aa8 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -62,6 +62,33 @@ in this Software without prior written authorization from The Open Group.
 #include <X11/extensions/shmstr.h>
 #include <X11/Xfuncproto.h>
 
+/* Needed for Solaris cross-zone shared memory extension */
+#ifdef HAVE_SHMCTL64
+#include <sys/ipc_impl.h>
+#define SHMSTAT(id, buf)	shmctl64(id, IPC_STAT64, buf)
+#define SHMSTAT_TYPE 		struct shmid_ds64
+#define SHMPERM_TYPE 		struct ipc_perm64
+#define SHM_PERM(buf) 		buf.shmx_perm
+#define SHM_SEGSZ(buf)		buf.shmx_segsz
+#define SHMPERM_UID(p)		p->ipcx_uid
+#define SHMPERM_CUID(p)		p->ipcx_cuid
+#define SHMPERM_GID(p)		p->ipcx_gid
+#define SHMPERM_CGID(p)		p->ipcx_cgid
+#define SHMPERM_MODE(p)		p->ipcx_mode
+#define SHMPERM_ZONEID(p)	p->ipcx_zoneid
+#else
+#define SHMSTAT(id, buf) 	shmctl(id, IPC_STAT, buf)
+#define SHMSTAT_TYPE 		struct shmid_ds
+#define SHMPERM_TYPE 		struct ipc_perm
+#define SHM_PERM(buf) 		buf.shm_perm
+#define SHM_SEGSZ(buf)		buf.shm_segsz
+#define SHMPERM_UID(p)		p->uid
+#define SHMPERM_CUID(p)		p->cuid
+#define SHMPERM_GID(p)		p->gid
+#define SHMPERM_CGID(p)		p->cgid
+#define SHMPERM_MODE(p)		p->mode
+#endif
+
 #ifdef PANORAMIX
 #include "panoramiX.h"
 #include "panoramiXsrv.h"
@@ -348,32 +375,57 @@ ProcShmQueryVersion(client)
  * using the credentials from the client if available
  */
 static int
-shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly)
 {
     int uid, gid;
     mode_t mask;
+    int uidset = 0, gidset = 0;
+    LocalClientCredRec *lcc;
+    
+    if (GetLocalClientCreds(client, &lcc) != -1) {
 
-    if (LocalClientCred(client, &uid, &gid) != -1) {
-	
-	/* User id 0 always gets access */
-	if (uid == 0) {
-	    return 0;
+	if (lcc->fieldsSet & LCC_UID_SET) {
+	    uid = lcc->euid;
+	    uidset = 1;
+	}
+	if (lcc->fieldsSet & LCC_GID_SET) {
+	    gid = lcc->egid;
+	    gidset = 1;
 	}
-	/* Check the owner */
-	if (perm->uid == uid || perm->cuid == uid) {
-	    mask = S_IRUSR;
-	    if (!readonly) {
-		mask |= S_IWUSR;
+
+#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID)
+	if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1)
+	     || (lcc->zoneid != SHMPERM_ZONEID(perm))) {
+		uidset = 0;
+		gidset = 0;
+	}
+#endif
+	FreeLocalClientCreds(lcc);
+	
+	if (uidset) {
+	    /* User id 0 always gets access */
+	    if (uid == 0) {
+		return 0;
+	    }
+	    /* Check the owner */
+	    if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) {
+		mask = S_IRUSR;
+		if (!readonly) {
+		    mask |= S_IWUSR;
+		}
+		return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
 	    }
-	    return (perm->mode & mask) == mask ? 0 : -1;
 	}
-	/* Check the group */
-	if (perm->gid == gid || perm->cgid == gid) {
-	    mask = S_IRGRP;
-	    if (!readonly) {
-		mask |= S_IWGRP;
+
+	if (gidset) {
+	    /* Check the group */
+	    if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) {
+		mask = S_IRGRP;
+		if (!readonly) {
+		    mask |= S_IWGRP;
+		}
+		return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
 	    }
-	    return (perm->mode & mask) == mask ? 0 : -1;
 	}
     }
     /* Otherwise, check everyone else */
@@ -381,14 +433,14 @@ shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
     if (!readonly) {
 	mask |= S_IWOTH;
     }
-    return (perm->mode & mask) == mask ? 0 : -1;
+    return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
 }
 
 static int
 ProcShmAttach(client)
     register ClientPtr client;
 {
-    struct shmid_ds buf;
+    SHMSTAT_TYPE buf;
     ShmDescPtr shmdesc;
     REQUEST(xShmAttachReq);
 
@@ -417,7 +469,7 @@ ProcShmAttach(client)
 	shmdesc->addr = shmat(stuff->shmid, 0,
 			      stuff->readOnly ? SHM_RDONLY : 0);
 	if ((shmdesc->addr == ((char *)-1)) ||
-	    shmctl(stuff->shmid, IPC_STAT, &buf))
+	    SHMSTAT(stuff->shmid, &buf))
 	{
 	    xfree(shmdesc);
 	    return BadAccess;
@@ -427,7 +479,7 @@ ProcShmAttach(client)
 	 * do manual checking of access rights for the credentials 
 	 * of the client */
 
-	if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
+	if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) {
 	    shmdt(shmdesc->addr);
 	    xfree(shmdesc);
 	    return BadAccess;
@@ -436,7 +488,7 @@ ProcShmAttach(client)
 	shmdesc->shmid = stuff->shmid;
 	shmdesc->refcnt = 1;
 	shmdesc->writable = !stuff->readOnly;
-	shmdesc->size = buf.shm_segsz;
+	shmdesc->size = SHM_SEGSZ(buf);
 	shmdesc->next = Shmsegs;
 	Shmsegs = shmdesc;
     }
diff --git a/configure.ac b/configure.ac
index 6565445..444edfd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,7 +179,7 @@ dnl Checks for library functions.
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \
 		strtol getopt getopt_long vsnprintf walkcontext backtrace \
-		getisax getzoneid])
+		getisax getzoneid shmctl64])
 AC_FUNC_ALLOCA
 dnl Old HAS_* names used in os/*.c.
 AC_CHECK_FUNC([getdtablesize],
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 3b9f15c..5635d64 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -184,6 +184,9 @@
 /* Define to 1 if you have the <rpcsvc/dbm.h> header file. */
 #undef HAVE_RPCSVC_DBM_H
 
+/* Define to 1 if you have the `shmctl64' function. */
+#undef HAVE_SHMCTL64
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
commit 49c8285e38e0e71c9ea43df63add08a4f2564ed1
Author: Christian Weisgerber <naddy at freebsd.org>
Date:   Tue Oct 9 15:25:16 2007 -0700

    FreeBSD/alpha server build requires libio (missed in modularization).

diff --git a/configure.ac b/configure.ac
index ae1170a..6565445 100644
--- a/configure.ac
+++ b/configure.ac
@@ -290,6 +290,7 @@ case $host_cpu in
   alpha*)
 	ALPHA_VIDEO=yes
 	case $host_os in
+	        *freebsd*)	SYS_LIBS=-lio ;;
 		*netbsd*)	AC_DEFINE(USE_ALPHA_PIO, 1, [NetBSD PIO alpha IO]) ;;
 	esac
 	;;
commit 6aab6a6e2ae0ef5fdedae09cf2cdc86f382e3a8a
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Mon Oct 8 13:25:38 2007 +0200

    EXA: dude, don't validation driver hooks twice !

diff --git a/exa/exa.c b/exa/exa.c
index 1403d4f..7ad226f 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -722,48 +722,6 @@ exaDriverAlloc(void)
     return xcalloc(1, sizeof(ExaDriverRec));
 }
 
-static Bool
-exaDriverValidateEntryPoints (ExaDriverPtr  pExaDriver)
-{
-    Bool res=TRUE ;
-
-    if (!pExaDriver)
-        return FALSE ;
-
-    if (!pExaDriver->memoryBase) {
-        LogMessage(X_ERROR,
-                   "Exa: Exa::memoryBase member "
-                   "must be assigned to a value different from zero\n") ;
-        res = FALSE ;
-    }
-    if (!pExaDriver->memorySize) {
-        LogMessage(X_ERROR,
-                   "Exa: Exa::memorySize member must be different from zero\n") ;
-        res = FALSE ;
-    }
-    if (pExaDriver->offScreenBase > pExaDriver->memorySize) {
-        LogMessage(X_ERROR,
-                   "Exa: Exa::ffscreenBase must be <= pExaDriver->memorySize member\n") ;
-        res = FALSE ;
-    }
-    if (!pExaDriver->PrepareSolid) {
-        LogMessage(X_ERROR,
-                   "Exa: Exa::PrepareSolid member is required to be non NULL\n") ;
-        res = FALSE ;
-    }
-    if (!pExaDriver->PrepareCopy) {
-        LogMessage(X_ERROR,
-                   "Exa: Exa::PrepareCopy member is required to be non NULL\n") ;
-        res = FALSE ;
-    }
-    if (!pExaDriver->WaitMarker) {
-        LogMessage(X_ERROR,
-                   "Exa: Exa::WaitWarker member is required to be non NULL\n") ;
-        res = FALSE ;
-    }
-    return res ;
-}
-
 /**
  * @param pScreen screen being initialized
  * @param pScreenInfo EXA driver record
@@ -848,12 +806,6 @@ exaDriverInit (ScreenPtr		pScreen,
     {
         pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
     }
-    if (!exaDriverValidateEntryPoints(pScreenInfo))
-    {
-	LogMessage(X_ERROR, "Exa(%d): EXA driver entry points validation failed\n",
-		   pScreen->myNum) ;
-	return FALSE ;
-    }
 
 #ifdef RENDER
     ps = GetPictureScreenIfSet(pScreen);
commit 4611f9568cdadf9c00f4b7ca4c77c8c6f07e94f8
Merge: ab11bad... 3549a12...
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Thu Oct 4 13:07:50 2007 +0200

    updated from 'master'

commit ab11bad54707941eb41be62c025b983760ce3900
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Thu Oct 4 13:05:29 2007 +0200

    Xephyr: remove a potential crasher
    
    	* hw/kdrive/ephyr/hostx.c:
    	  (hostx_has_dri): be more defensive.

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 181edd2..b5ffdd0 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -1328,6 +1328,9 @@ hostx_has_dri (void)
     int event_base=0, error_base=0 ;
     Display *dpy=hostx_get_display () ;
 
+    if (!dpy)
+        return FALSE ;
+
     if (!XF86DRIQueryExtension (dpy,
                                 &event_base,
                                 &error_base)) {
commit 06c8977966e76255ce7798f4839ef6e3530264a8
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Thu Oct 4 13:01:24 2007 +0200

    Xephyr: better handling of the -nodri option
    
            * hw/kdrive/ephyr/ephyr.c:
              (ephyrInitScreen): try and detect when the host has no
              DRI support. In that case, switch to the -nodri behaviour.
              When in the -nodri case, make sure not to skip glx visual
              initialisation.

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 85aab28..f46a89d 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -40,6 +40,10 @@
 #endif /*XEPHYR_DRI*/
 
 extern int KdTsPhyScreen;
+#ifdef GLXEXT
+extern Bool noGlxVisualInit;
+#endif
+
 KdKeyboardInfo *ephyrKbd;
 KdPointerInfo *ephyrMouse;
 EphyrKeySyms ephyrKeySyms;
@@ -628,6 +632,11 @@ ephyrInitScreen (ScreenPtr pScreen)
 #endif /*XV*/
 
 #ifdef XEPHYR_DRI
+  if (!ephyrNoDRI && !hostx_has_dri ()) {
+      EPHYR_LOG ("host x does not support DRI. Disabling DRI forwarding\n") ;
+      ephyrNoDRI = TRUE ;
+      noGlxVisualInit = FALSE ;
+  }
   if (!ephyrNoDRI) {
     ephyrDRIExtensionInit (pScreen) ;
     ephyrHijackGLXExtension () ;
@@ -635,6 +644,12 @@ ephyrInitScreen (ScreenPtr pScreen)
   }
 #endif
 
+#ifdef GLXEXT
+  if (ephyrNoDRI) {
+      noGlxVisualInit = FALSE ;
+  }
+#endif
+
   return TRUE;
 }
 
commit ea94f59e9b8824b1a638c63e06ca16f0efd43869
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Thu Oct 4 12:54:26 2007 +0200

    Xephyr: don't disable glx visual init by default
    
            * hw/kdrive/ephyr/ephyrinit.c:
              (ddxProcessArgument): disabling visual init here
              is bad because it gets disabled even when we want
              to use software GL, leading to Xephyr :1 -nodri
              crashing in mesa.

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 5034ba5..6196996 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -148,8 +148,6 @@ ddxProcessArgument (int argc, char **argv, int i)
 {
   EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] );
 
-  noGlxVisualInit = TRUE ;
-
   if (!strcmp (argv[i], "-parent"))
     {
       if(i+1 < argc)
commit a7f210e6fcda14eae4de64186904c6c676c758ee
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Thu Oct 4 12:51:08 2007 +0200

    Xephyr: fix a compiler warning

diff --git a/hw/kdrive/ephyr/os.c b/hw/kdrive/ephyr/os.c
index b58daae..4bf6e88 100644
--- a/hw/kdrive/ephyr/os.c
+++ b/hw/kdrive/ephyr/os.c
@@ -28,6 +28,8 @@
 #endif
 #include "ephyr.h"
 
+extern void processScreenArg (char *screen_size, char *parent_id) ;
+
 static int
 EphyrInit (void)
 {
commit 5d6eac1251f1e17baa74d0893bb225b775e8ec2e
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Thu Oct 4 12:47:05 2007 +0200

    Xephyr: remove an unused variable

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 4a6a11d..5034ba5 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -118,7 +118,6 @@ void
 processScreenArg (char *screen_size, char *parent_id)
 {
   KdCardInfo   *card;
-  static int card_exists;
 
   InitCard (0);  /*Put each screen on a separate card*/
   card = KdCardInfoLast ();
commit 8018733c39c283a931df424dcfd11e7aefbcd8cf
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Thu Oct 4 12:06:19 2007 +0200

    Xephyr: better compilation without GLX
    
    	* hw/kdrive/ephyr/ephyrinit.c: protect GLX related code with GLXEXT
    	  macro

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index cc7a367..4a6a11d 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -33,9 +33,12 @@ extern Window EphyrPreExistingHostWin;
 extern Bool   EphyrWantGrayScale;
 extern Bool   kdHasPointer;
 extern Bool   kdHasKbd;
+
+#ifdef GLXEXT
 extern Bool   ephyrNoDRI;
-extern Bool   ephyrNoXV;
 extern Bool noGlxVisualInit;
+#endif
+extern Bool   ephyrNoXV;
 
 void processScreenArg (char *screen_size, char *parent_id) ;
 
@@ -102,7 +105,9 @@ ddxUseMsg (void)
   ErrorF("-grayscale           Simulate 8bit grayscale\n");
   ErrorF("-fakexa              Simulate acceleration using software rendering\n");
   ErrorF("-verbosity <level>   Set log verbosity level\n");
+#ifdef GLXEXT
   ErrorF("-nodri               do not use DRI\n");
+#endif
   ErrorF("-noxv                do not use XV\n");
   ErrorF("\n");
 
@@ -206,6 +211,7 @@ ddxProcessArgument (int argc, char **argv, int i)
 	  exit(1) ;
 	}
     }
+#ifdef GLXEXT
   else if (!strcmp (argv[i], "-nodri"))
    {
        noGlxVisualInit = FALSE ;
@@ -213,6 +219,7 @@ ddxProcessArgument (int argc, char **argv, int i)
        EPHYR_LOG ("no direct rendering enabled\n") ;
        return 1 ;
    }
+#endif
   else if (!strcmp (argv[i], "-noxv"))
    {
        ephyrNoXV = TRUE ;
commit 3549a1282365e69e70c7c2546cfa7d25923cce31
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Oct 4 11:38:01 2007 +0200

    EXA: Disable 1x1 pixmap fill optimization for drivers that handle pixmaps.
    
    This reverts commit 1365aeff5499a051375e43a9fcbf54733ac93929.
    
    It defeated the optimization for drivers that don't provide a CreatePixmap
    hook. The optimization makes no sense for drivers that do anyway, so disable
    it for them completely.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index e10bf5c..8bbf036 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1134,23 +1134,22 @@ exaFillRegionSolid (DrawablePtr	pDrawable,
 	(*pExaScr->info->DoneSolid) (pPixmap);
 	exaMarkSync(pDrawable->pScreen);
 
-	if (pDrawable->width == 1 && pDrawable->height == 1 &&
+	if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) &&
+	    pDrawable->width == 1 && pDrawable->height == 1 &&
 	    pDrawable->bitsPerPixel != 24) {
 	    ExaPixmapPriv(pPixmap);
 
-	    exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
 	    switch (pDrawable->bitsPerPixel) {
 	    case 32:
-		*(CARD32*)pPixmap->devPrivate.ptr = pixel;
+		*(CARD32*)pExaPixmap->sys_ptr = pixel;
 		break;
 	    case 16:
-		*(CARD16*)pPixmap->devPrivate.ptr = pixel;
+		*(CARD16*)pExaPixmap->sys_ptr = pixel;
 		break;
 	    case 8:
-		*(CARD8*)pPixmap->devPrivate.ptr = pixel;
+		*(CARD8*)pExaPixmap->sys_ptr = pixel;
 	    }
 
-	    exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
 	    REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
 			 pRegion);
 	}
commit 604ebb5a6de372e6a8a96e0ee997db7929126860
Merge: 1365aef... 4ba76a7...
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Wed Oct 3 16:13:16 2007 +0200

    Merge Xephyr-XV/GL stuff into master

commit 4ba76a7e2b62d26f43c0e670de571afb75ec92f4
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Wed Oct 3 13:03:34 2007 +0200

    Xephyr: port XV/GL stuff of the new multiscreen architecture
    
            We can now launch GL or XV apps in any of the
            Xephyr screens we want.
    
    	* hw/kdrive/ephyr/hostx.c,h:
    	 (hostx_get_window):
    	 (hostx_create_window): make these functions be screen
    	 number aware.
    	* hw/kdrive/ephyr/XF86dri.c : fix some compiler warnings.
    	* hw/kdrive/ephyr/ephyrdri.c:
    	 (ephyrDRIQueryDirectRenderingCapable),
    	 (ephyrDRIOpenConnection),
    	 (ephyrDRIAuthConnection),
    	 (ephyrDRICloseConnection),
    	 (ephyrDRIGetClientDriverName),
    	 (ephyrDRICreateContext),
    	 (ephyrDRIDestroyContext),
    	 (ephyrDRICreateDrawable),
    	 (ephyrDRIGetDrawableInfo),
    	 (ephyrDRIGetDeviceInfo): in all those functions, don't forward
    	 the screen number we receive - from the client - to the host X.
    	 We (Xephyr) are always targetting the same X display screen, which is
    	 the one Xephyr got launched against. So we enforce that in the code.
    	* hw/kdrive/ephyr/ephyrdriext.c:
    	 (EphyrMirrorHostVisuals): make this duplicate the visuals of the host X
    	  default screen into a given Xephyr screen. This way we have a chance
    	  to update the visuals of all Xephyr screen to make them mirror those
    	  of the host X.
    	 (many other places): specify screen number where required by the api
    	 change in hostx.h.
    	* hw/kdrive/ephyr/ephyrglxext.c: specify screen number where required
    	 by the api change in hostx.h
    	* hw/kdrive/ephyr/ephyrhostglx.c: don't forward the screen number we
    	  receive - from the client - to the host X.
    	  We (Xephyr) are always targetting the same
    	  X display screen, which is
    	 the one Xephyr got launched against. So we enforce that in the code.
    	* hw/kdrive/ephyr/ephyrhostvideo.c,h: take in account the screen number received
    	  from the client app. This is useful to know on which Xephyr screen we
    	  need to display video stuff.
    	* hw/kdrive/ephyr/ephyrvideo.c: update this to reflect the API change
    	  in hw/kdrive/ephyr/ephyrhostvideo.h.
    	  (ephyrSetPortAttribute): when parameters are not valid
    	   - they exceed their validity range - send them to the host anyway
    	   and do not return an error to clients.
    	  Some host expose buggy validity range, so rejecting client for that
    	  is too harsh.

diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c
index f3f3179..ae2ec89 100644
--- a/hw/kdrive/ephyr/XF86dri.c
+++ b/hw/kdrive/ephyr/XF86dri.c
@@ -107,6 +107,8 @@ static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
 #define TRACE(msg)
 #endif
 
+Bool XF86DRIOpenFullScreen(Display *dpy, int screen, Drawable drawable);
+Bool XF86DRICloseFullScreen(Display *dpy, int screen, Drawable drawable);
 
 Bool XF86DRIQueryExtension (Display *dpy, int *event_basep, int *error_basep)
 {
diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
index e7d4128..53a96ba 100644
--- a/hw/kdrive/ephyr/ephyrdri.c
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -59,7 +59,8 @@ ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable)
 
     EPHYR_RETURN_VAL_IF_FAIL (a_is_capable, FALSE) ;
     EPHYR_LOG ("enter\n") ;
-    is_ok = XF86DRIQueryDirectRenderingCapable (dpy, a_screen, a_is_capable) ;
+    is_ok = XF86DRIQueryDirectRenderingCapable (dpy, DefaultScreen (dpy),
+                                                a_is_capable) ;
     EPHYR_LOG ("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok) ;
 
     return is_ok ;
@@ -75,7 +76,9 @@ ephyrDRIOpenConnection (int a_screen,
 
     EPHYR_RETURN_VAL_IF_FAIL (a_bus_id_string, FALSE) ;
     EPHYR_LOG ("enter. screen:%d\n", a_screen) ;
-    is_ok = XF86DRIOpenConnection (dpy, a_screen, a_sarea, a_bus_id_string) ;
+    is_ok = XF86DRIOpenConnection (dpy, DefaultScreen (dpy),
+                                   a_sarea,
+                                   a_bus_id_string) ;
     if (*a_bus_id_string) {
         EPHYR_LOG ("leave. bus_id_string:%s, is_ok:%d\n",
                    *a_bus_id_string, is_ok) ;
@@ -93,7 +96,7 @@ ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic)
     Bool is_ok=FALSE ;
 
     EPHYR_LOG ("enter\n") ;
-    is_ok = XF86DRIAuthConnection (dpy, a_screen, a_magic) ;
+    is_ok = XF86DRIAuthConnection (dpy, DefaultScreen (dpy), a_magic) ;
     EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
     return is_ok ;
 }
@@ -105,7 +108,7 @@ ephyrDRICloseConnection (int a_screen)
     Bool is_ok=FALSE ;
 
     EPHYR_LOG ("enter\n") ;
-    is_ok = XF86DRICloseConnection (dpy, a_screen) ;
+    is_ok = XF86DRICloseConnection (dpy, DefaultScreen (dpy)) ;
     EPHYR_LOG ("leave\n") ;
     return is_ok ;
 }
@@ -126,7 +129,7 @@ ephyrDRIGetClientDriverName (int a_screen,
                               && a_client_driver_name,
                               FALSE);
     EPHYR_LOG ("enter\n") ;
-    is_ok = XF86DRIGetClientDriverName (dpy, a_screen,
+    is_ok = XF86DRIGetClientDriverName (dpy, DefaultScreen (dpy),
                                         a_ddx_driver_major_version,
                                         a_ddx_driver_minor_version,
                                         a_ddx_driver_patch_version,
@@ -154,7 +157,7 @@ ephyrDRICreateContext (int a_screen,
     memset (&v, 0, sizeof (v)) ;
     v.visualid = a_visual_id ;
     is_ok = XF86DRICreateContext (dpy,
-                                  a_screen,
+                                  DefaultScreen (dpy),
                                   &v,
                                   a_returned_ctxt_id,
                                   a_hw_ctxt) ;
@@ -170,7 +173,7 @@ ephyrDRIDestroyContext (int a_screen,
     Bool is_ok=FALSE ;
 
     EPHYR_LOG ("enter\n") ;
-    is_ok = XF86DRIDestroyContext (dpy, a_screen, a_context_id) ;
+    is_ok = XF86DRIDestroyContext (dpy, DefaultScreen (dpy), a_context_id) ;
     EPHYR_LOG ("leave:%d\n", is_ok) ;
     return is_ok ;
 }
@@ -184,7 +187,8 @@ ephyrDRICreateDrawable (int a_screen,
     Display *dpy=hostx_get_display () ;
 
     EPHYR_LOG ("enter\n") ;
-    is_ok = XF86DRICreateDrawable (dpy, a_screen, a_drawable, a_hw_drawable) ;
+    is_ok = XF86DRICreateDrawable (dpy, DefaultScreen (dpy),
+                                   a_drawable, a_hw_drawable) ;
     EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
     return is_ok ;
 }
@@ -228,7 +232,7 @@ ephyrDRIGetDrawableInfo (int a_screen,
         EPHYR_LOG_ERROR ("failed to query host window attributes\n") ;
         goto out;
     }
-    if (!XF86DRIGetDrawableInfo (dpy, a_screen, a_drawable,
+    if (!XF86DRIGetDrawableInfo (dpy, DefaultScreen (dpy), a_drawable,
                                  a_index, a_stamp,
                                  a_x, a_y,
                                  a_w, a_h,
@@ -277,7 +281,7 @@ ephyrDRIGetDeviceInfo (int a_screen,
 
     EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
     EPHYR_LOG ("enter\n") ;
-    is_ok = XF86DRIGetDeviceInfo (dpy, a_screen, a_frame_buffer,
+    is_ok = XF86DRIGetDeviceInfo (dpy, DefaultScreen (dpy), a_frame_buffer,
                                   a_fb_origin, a_fb_size, a_fb_stride,
                                   a_dev_private_size, a_dev_private) ;
     EPHYR_LOG ("leave:%d\n", is_ok) ;
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index 26c792d..e3d0cfb 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -111,7 +111,7 @@ static Bool ephyrDRIPositionWindow (WindowPtr a_win,
 static void ephyrDRIClipNotify (WindowPtr a_win,
                                 int a_x, int a_y) ;
 
-static Bool EphyrMirrorHostVisuals (void) ;
+static Bool EphyrMirrorHostVisuals (ScreenPtr a_screen) ;
 static Bool destroyHostPeerWindow (const WindowPtr a_win) ;
 static Bool findWindowPairFromLocal (WindowPtr a_local,
                                      EphyrWindowPair **a_pair);
@@ -182,7 +182,7 @@ ephyrDRIExtensionInit (ScreenPtr a_screen)
         EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ;
         goto out ;
     }
-    EphyrMirrorHostVisuals () ;
+    EphyrMirrorHostVisuals (a_screen) ;
     if (ephyrDRIGeneration != serverGeneration) {
         ephyrDRIGeneration = serverGeneration ;
     }
@@ -607,7 +607,7 @@ out:
  * GLX.
  */
 static Bool
-EphyrMirrorHostVisuals (void)
+EphyrMirrorHostVisuals (ScreenPtr a_screen)
 {
     Bool is_ok=FALSE;
     EphyrHostVisualInfo  *visuals=NULL;
@@ -619,7 +619,7 @@ EphyrMirrorHostVisuals (void)
         goto out ;
     }
     for (i=0; i<nb_visuals; i++) {
-        if (!EphyrDuplicateVisual (visuals[i].screen,
+        if (!EphyrDuplicateVisual (a_screen->myNum,
                                    visuals[i].depth,
                                    visuals[i].class,
                                    visuals[i].bits_per_rgb,
@@ -980,6 +980,8 @@ createHostPeerWindow (const WindowPtr a_win,
     EphyrBox geo ;
 
     EPHYR_RETURN_VAL_IF_FAIL (a_win && a_peer_win, FALSE) ;
+    EPHYR_RETURN_VAL_IF_FAIL (a_win->drawable.pScreen,
+                              FALSE) ;
 
     EPHYR_LOG ("enter. a_win '%#x'\n", (unsigned int)a_win) ;
     if (!getWindowVisual (a_win, &visual)) {
@@ -995,7 +997,8 @@ createHostPeerWindow (const WindowPtr a_win,
     geo.y = a_win->drawable.y ;
     geo.width = a_win->drawable.width ;
     geo.height = a_win->drawable.height ;
-    if (!hostx_create_window (&geo, visual->vid, a_peer_win)) {
+    if (!hostx_create_window (a_win->drawable.pScreen->myNum,
+                              &geo, visual->vid, a_peer_win)) {
         EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
         goto out ;
     }
diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
index 47c4fb1..381c9d7 100644
--- a/hw/kdrive/ephyr/ephyrglxext.c
+++ b/hw/kdrive/ephyr/ephyrglxext.c
@@ -438,7 +438,8 @@ ephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap)
                (int)a_req->visual, (int)a_req->isDirect) ;
 
     memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ;
-    if (!hostx_get_window_attributes (hostx_get_window (), &host_w_attrs)) {
+    if (!hostx_get_window_attributes (hostx_get_window (a_req->screen),
+                                      &host_w_attrs)) {
         EPHYR_LOG_ERROR ("failed to get host window attrs\n") ;
         goto out ;
     }
@@ -513,10 +514,22 @@ ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
     int res=BadImplementation;
     xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
     xGLXMakeCurrentReply reply ;
+    DrawablePtr drawable=NULL;
+    int rc=0;
 
     EPHYR_LOG ("enter\n") ;
+    rc = dixLookupDrawable (&drawable,
+                            req->drawable,
+                            a_cl->client,
+                            0,
+                            DixReadAccess);
+    EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ;
+    EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ;
+    EPHYR_LOG ("screen nummber requested:%d\n",
+               drawable->pScreen->myNum) ;
+
     memset (&reply, 0, sizeof (reply)) ;
-    if (!ephyrHostGLXMakeCurrent (hostx_get_window (),
+    if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum),
                                   req->context,
                                   req->oldContextTag,
                                   (int*)&reply.contextTag)) {
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
index ad86d30..5d9a482 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -188,7 +188,7 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
     GetReq (GLXGenericGetString, req);
     req->reqType = major_opcode;
     req->glxCode = get_string_op;
-    req->for_whom = a_screen_number;
+    req->for_whom = DefaultScreen (dpy);
     req->name = a_string_name;
 
     _XReply (dpy, (xReply *)&reply, 0, False);
@@ -263,7 +263,7 @@ ephyrHostGLXGetVisualConfigsInternal (enum VisualConfRequestType a_type,
         GetReq(GLXGetFBConfigs,fb_req);
         fb_req->reqType = major_opcode;
         fb_req->glxCode = X_GLXGetFBConfigs;
-        fb_req->screen = a_screen;
+        fb_req->screen = DefaultScreen (dpy);
         break;
 
         case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX:
@@ -276,14 +276,14 @@ ephyrHostGLXGetVisualConfigsInternal (enum VisualConfRequestType a_type,
         sgi_req->reqType = major_opcode;
         sgi_req->glxCode = X_GLXVendorPrivateWithReply;
         sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
-        sgi_req->screen = a_screen;
+        sgi_req->screen = DefaultScreen (dpy);
         break;
 
         case EPHYR_GET_VISUAL_CONFIGS:
         GetReq(GLXGetVisualConfigs,req);
         req->reqType = major_opcode;
         req->glxCode = X_GLXGetVisualConfigs;
-        req->screen = a_screen;
+        req->screen = DefaultScreen (dpy);
         break;
     }
 
@@ -460,7 +460,7 @@ ephyrHostGLXCreateContext (int a_screen,
     req->glxCode = X_GLXCreateContext;
     req->context = remote_context_id;
     req->visual = a_visual_id;
-    req->screen = a_screen;
+    req->screen = DefaultScreen (dpy);
     req->shareList = a_share_list_ctxt_id;
     req->isDirect = a_direct;
 
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index a0ca76b..562c2a4 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -745,7 +745,8 @@ ephyrHostFree (void *a_pointer)
 }
 
 Bool
-ephyrHostXVPutImage (int a_port_id,
+ephyrHostXVPutImage (int a_screen_num,
+                     int a_port_id,
                      int a_image_id,
                      int a_drw_x,
                      int a_drw_y,
@@ -774,7 +775,7 @@ ephyrHostXVPutImage (int a_port_id,
     EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
 
     memset (&gc_values, 0, sizeof (gc_values)) ;
-    gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
+    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
     if (!gc) {
         EPHYR_LOG_ERROR ("failed to create gc \n") ;
         goto out ;
@@ -802,7 +803,8 @@ ephyrHostXVPutImage (int a_port_id,
         XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ;
         /*this always returns 1*/
     }
-    res = XvPutImage (dpy, a_port_id, hostx_get_window (),
+    res = XvPutImage (dpy, a_port_id,
+                      hostx_get_window (a_screen_num),
                       gc, xv_image,
                       a_src_x, a_src_y, a_src_w, a_src_h,
                       a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
@@ -830,7 +832,7 @@ out:
 }
 
 Bool
-ephyrHostXVPutVideo (int a_port_id,
+ephyrHostXVPutVideo (int a_screen_num, int a_port_id,
                      int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
                      int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
 {
@@ -842,12 +844,12 @@ ephyrHostXVPutVideo (int a_port_id,
 
     EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
 
-    gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
+    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
     if (!gc) {
         EPHYR_LOG_ERROR ("failed to create gc \n") ;
         goto out ;
     }
-    res = XvPutVideo (dpy, a_port_id, hostx_get_window (), gc,
+    res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
                       a_vid_x, a_vid_y, a_vid_w, a_vid_h,
                       a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
 
@@ -867,7 +869,7 @@ out:
 }
 
 Bool
-ephyrHostXVGetVideo (int a_port_id,
+ephyrHostXVGetVideo (int a_screen_num, int a_port_id,
                      int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
                      int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
 {
@@ -879,12 +881,12 @@ ephyrHostXVGetVideo (int a_port_id,
 
     EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
 
-    gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
+    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
     if (!gc) {
         EPHYR_LOG_ERROR ("failed to create gc \n") ;
         goto out ;
     }
-    res = XvGetVideo (dpy, a_port_id, hostx_get_window (), gc,
+    res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
                       a_vid_x, a_vid_y, a_vid_w, a_vid_h,
                       a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
 
@@ -904,7 +906,7 @@ out:
 }
 
 Bool
-ephyrHostXVPutStill (int a_port_id,
+ephyrHostXVPutStill (int a_screen_num, int a_port_id,
                      int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
                      int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
 {
@@ -916,12 +918,12 @@ ephyrHostXVPutStill (int a_port_id,
 
     EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
 
-    gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
+    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
     if (!gc) {
         EPHYR_LOG_ERROR ("failed to create gc \n") ;
         goto out ;
     }
-    res = XvPutStill (dpy, a_port_id, hostx_get_window (), gc,
+    res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
                       a_vid_x, a_vid_y, a_vid_w, a_vid_h,
                       a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
 
@@ -941,7 +943,7 @@ out:
 }
 
 Bool
-ephyrHostXVGetStill (int a_port_id,
+ephyrHostXVGetStill (int a_screen_num, int a_port_id,
                      int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
                      int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
 {
@@ -953,12 +955,12 @@ ephyrHostXVGetStill (int a_port_id,
 
     EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
 
-    gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
+    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
     if (!gc) {
         EPHYR_LOG_ERROR ("failed to create gc \n") ;
         goto out ;
     }
-    res = XvGetStill (dpy, a_port_id, hostx_get_window (), gc,
+    res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
                       a_vid_x, a_vid_y, a_vid_w, a_vid_h,
                       a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
 
@@ -978,7 +980,7 @@ out:
 }
 
 Bool
-ephyrHostXVStopVideo (int a_port_id)
+ephyrHostXVStopVideo (int a_screen_num, int a_port_id)
 {
     int ret=0 ;
     Bool is_ok=FALSE ;
@@ -988,7 +990,7 @@ ephyrHostXVStopVideo (int a_port_id)
 
     EPHYR_LOG ("enter\n") ;
 
-    ret = XvStopVideo (dpy, a_port_id, hostx_get_window ()) ;
+    ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ;
     if (ret != Success) {
         EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
         goto out ;
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
index 64b224f..05ee38a 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.h
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -189,7 +189,8 @@ char* ephyrHostGetAtomName (int a_atom) ;
  *PutImage
  * (ignore clipping for now)
  */
-Bool ephyrHostXVPutImage (int a_port_id,
+Bool ephyrHostXVPutImage (int a_screen_num,
+                          int a_port_id,
                           int a_image_id,
                           int a_drw_x,
                           int a_drw_y,
@@ -208,26 +209,30 @@ Bool ephyrHostXVPutImage (int a_port_id,
 /*
  * Putvideo/PutStill/GetVideo
  */
-Bool ephyrHostXVPutVideo (int a_port_id,
+Bool ephyrHostXVPutVideo (int a_screen_num,
+                          int a_port_id,
                           int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
                           int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
 
-Bool ephyrHostXVGetVideo (int a_port_id,
+Bool ephyrHostXVGetVideo (int a_screen_num,
+                          int a_port_id,
                           int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
                           int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
 
-Bool ephyrHostXVPutStill (int a_port_id,
+Bool ephyrHostXVPutStill (int a_screen_num,
+                          int a_port_id,
                           int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
                           int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
 
-Bool ephyrHostXVGetStill (int a_port_id,
+Bool ephyrHostXVGetStill (int a_screen_num,
+                          int a_port_id,
                           int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
                           int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
 
 /*
  * StopVideo
  */
-Bool ephyrHostXVStopVideo (int a_port_id) ;
+Bool ephyrHostXVStopVideo (int a_screen_num, int a_port_id) ;
 
 #endif /*__EPHYRHOSTVIDEO_H__*/
 
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 521f3a6..bfe4d72 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -705,6 +705,11 @@ ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
         if (a_attrs[i].min_value > a_attr_value ||
             a_attrs[i].max_value < a_attr_value) {
             *a_is_valid = FALSE ;
+            EPHYR_LOG_ERROR ("attribute was not valid\n"
+                             "value:%d. min:%d. max:%d\n",
+                             a_attr_value,
+                             a_attrs[i].min_value,
+                             a_attrs[i].max_value) ;
         } else {
             *a_is_valid = TRUE ;
         }
@@ -771,10 +776,12 @@ ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
 {
     EphyrPortPriv *port_priv = a_port_priv ;
 
+    EPHYR_RETURN_IF_FAIL (a_info && a_info->pScreen) ;
     EPHYR_RETURN_IF_FAIL (port_priv) ;
 
     EPHYR_LOG ("enter\n") ;
-    if (!ephyrHostXVStopVideo (port_priv->port_number)) {
+    if (!ephyrHostXVStopVideo (a_info->pScreen->myNum,
+                               port_priv->port_number)) {
         EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ;
     }
     EPHYR_LOG ("leave\n") ;
@@ -817,14 +824,18 @@ ephyrSetPortAttribute (KdScreenInfo *a_info,
                                       &is_attr_valid)) {
         EPHYR_LOG_ERROR ("failed to validate attribute %s\n",
                          NameForAtom (a_attr_name)) ;
-        res = BadMatch ;
-        goto out ;
+        /*
+         res = BadMatch ;
+         goto out ;
+         */
     }
     if (!is_attr_valid) {
         EPHYR_LOG_ERROR ("attribute %s is not valid\n",
                          NameForAtom (a_attr_name)) ;
+        /*
         res = BadMatch ;
         goto out ;
+        */
     }
 
     if (!ephyrHostXVSetPortAttribute (port_priv->port_number,
@@ -929,11 +940,13 @@ ephyrPutImage (KdScreenInfo *a_info,
     Bool is_ok=FALSE ;
     int result=BadImplementation, image_size=0 ;
 
+    EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
     EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
 
     EPHYR_LOG ("enter\n") ;
 
-    if (!ephyrHostXVPutImage (port_priv->port_number,
+    if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
+                              port_priv->port_number,
                               a_id,
                               a_drw_x, a_drw_y, a_drw_w, a_drw_h,
                               a_src_x, a_src_y, a_src_w, a_src_h,
@@ -999,6 +1012,7 @@ ephyrReputImage (KdScreenInfo *a_info,
     EphyrPortPriv *port_priv = a_port_priv ;
     int result=BadImplementation ;
 
+    EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, FALSE) ;
     EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
 
     EPHYR_LOG ("enter\n") ;
@@ -1007,7 +1021,9 @@ ephyrReputImage (KdScreenInfo *a_info,
         EPHYR_LOG_ERROR ("has null image buf in cache\n") ;
         goto out ;
     }
-    if (!ephyrHostXVPutImage (port_priv->port_number, port_priv->image_id,
+    if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
+                              port_priv->port_number,
+                              port_priv->image_id,
                               a_drw_x, a_drw_y,
                               port_priv->drw_w, port_priv->drw_h,
                               port_priv->src_x, port_priv->src_y,
@@ -1042,6 +1058,7 @@ ephyrPutVideo (KdScreenInfo *a_info,
     int result=BadImplementation ;
     int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
 
+    EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, BadValue) ;
     EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
 
     EPHYR_LOG ("enter\n") ;
@@ -1063,7 +1080,8 @@ ephyrPutVideo (KdScreenInfo *a_info,
     drw_w = clipped_area.x2 - clipped_area.x1 ;
     drw_h = clipped_area.y2 - clipped_area.y1 ;
 
-    if (!ephyrHostXVPutVideo (port_priv->port_number,
+    if (!ephyrHostXVPutVideo (a_info->pScreen->myNum,
+                              port_priv->port_number,
                               a_vid_x, a_vid_y, a_vid_w, a_vid_h,
                               a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
         EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ;
@@ -1091,6 +1109,7 @@ ephyrGetVideo (KdScreenInfo *a_info,
     int result=BadImplementation ;
     int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
 
+    EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
     EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
 
     EPHYR_LOG ("enter\n") ;
@@ -1112,7 +1131,8 @@ ephyrGetVideo (KdScreenInfo *a_info,
     drw_w = clipped_area.x2 - clipped_area.x1 ;
     drw_h = clipped_area.y2 - clipped_area.y1 ;
 
-    if (!ephyrHostXVGetVideo (port_priv->port_number,
+    if (!ephyrHostXVGetVideo (a_info->pScreen->myNum,
+                              port_priv->port_number,
                               a_vid_x, a_vid_y, a_vid_w, a_vid_h,
                               a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
         EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ;
@@ -1140,6 +1160,7 @@ ephyrPutStill (KdScreenInfo *a_info,
     int result=BadImplementation ;
     int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
 
+    EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
     EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
 
     EPHYR_LOG ("enter\n") ;
@@ -1161,7 +1182,8 @@ ephyrPutStill (KdScreenInfo *a_info,
     drw_w = clipped_area.x2 - clipped_area.x1 ;
     drw_h = clipped_area.y2 - clipped_area.y1 ;
 
-    if (!ephyrHostXVPutStill (port_priv->port_number,
+    if (!ephyrHostXVPutStill (a_info->pScreen->myNum,
+                              port_priv->port_number,
                               a_vid_x, a_vid_y, a_vid_w, a_vid_h,
                               a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
         EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ;
@@ -1189,6 +1211,7 @@ ephyrGetStill (KdScreenInfo *a_info,
     int result=BadImplementation ;
     int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
 
+    EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
     EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
 
     EPHYR_LOG ("enter\n") ;
@@ -1210,7 +1233,8 @@ ephyrGetStill (KdScreenInfo *a_info,
     drw_w = clipped_area.x2 - clipped_area.x1 ;
     drw_h = clipped_area.y2 - clipped_area.y1 ;
 
-    if (!ephyrHostXVGetStill (port_priv->port_number,
+    if (!ephyrHostXVGetStill (a_info->pScreen->myNum,
+                              port_priv->port_number,
                               a_vid_x, a_vid_y, a_vid_w, a_vid_h,
                               a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
         EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 0ef1a62..181edd2 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -978,9 +978,13 @@ hostx_get_display(void)
 }
 
 int
-hostx_get_window(void)
+hostx_get_window (int a_screen_number)
 {
-    return HostX.win ;
+    if (a_screen_number < 0 || a_screen_number >= HostX.n_screens) {
+        EPHYR_LOG_ERROR ("bad screen number:%d\n", a_screen_number) ;
+        return 0;
+    }
+    return HostX.screens[a_screen_number].win ;
 }
 
 int
@@ -1085,7 +1089,8 @@ static ResourcePair resource_peers[RESOURCE_PEERS_SIZE] ;
 
 
 int
-hostx_create_window (EphyrBox *a_geometry,
+hostx_create_window (int a_screen_number,
+                     EphyrBox *a_geometry,
                      int a_visual_id,
                      int *a_host_peer /*out parameter*/)
 {
@@ -1120,7 +1125,7 @@ hostx_create_window (EphyrBox *a_geometry,
                                       AllocNone) ;
     winmask = CWColormap;
 
-    win = XCreateWindow (dpy, hostx_get_window (),
+    win = XCreateWindow (dpy, hostx_get_window (a_screen_number),
                          a_geometry->x, a_geometry->y,
                          a_geometry->width, a_geometry->height, 0,
                          visual_info->depth, InputOutput,
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 941eece..3caa466 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -193,16 +193,16 @@ hostx_paint_rect(EphyrScreenInfo screen,
 
 
 void
-hostx_load_keymap(void);
+hostx_load_keymap (void);
 
 int
-hostx_get_event(EphyrHostXEvent *ev);
+hostx_get_event (EphyrHostXEvent *ev);
 
 void*
-hostx_get_display(void) ;
+hostx_get_display (void) ;
 
 int
-hostx_get_window(void) ;
+hostx_get_window (int a_screen_number) ;
 
 int
 hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attr)  ;
@@ -216,7 +216,8 @@ int
 hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
                         int *a_num_entries) ;
 
-int hostx_create_window (EphyrBox *a_geometry,
+int hostx_create_window (int a_screen_number,
+                         EphyrBox *a_geometry,
                          int a_visual_id,
                          int *a_host_win /*out parameter*/) ;
 
@@ -228,6 +229,7 @@ int hostx_set_window_geometry (int a_win, EphyrBox *a_geo) ;
 int hostx_set_window_bounding_rectangles (int a_window,
                                           EphyrRect *a_rects,
                                           int a_num_rects) ;
+
 int hostx_set_window_clipping_rectangles (int a_window,
                                           EphyrRect *a_rects,
                                           int a_num_rects) ;
commit 1365aeff5499a051375e43a9fcbf54733ac93929
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Oct 3 12:00:16 2007 +1000

    exa: direct access to the pixmap sys ptr is bad if the pixmap isn't mapped

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index abe5c20..e10bf5c 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1138,17 +1138,19 @@ exaFillRegionSolid (DrawablePtr	pDrawable,
 	    pDrawable->bitsPerPixel != 24) {
 	    ExaPixmapPriv(pPixmap);
 
+	    exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
 	    switch (pDrawable->bitsPerPixel) {
 	    case 32:
-		*(CARD32*)pExaPixmap->sys_ptr = pixel;
+		*(CARD32*)pPixmap->devPrivate.ptr = pixel;
 		break;
 	    case 16:
-		*(CARD16*)pExaPixmap->sys_ptr = pixel;
+		*(CARD16*)pPixmap->devPrivate.ptr = pixel;
 		break;
 	    case 8:
-		*(CARD8*)pExaPixmap->sys_ptr = pixel;
+		*(CARD8*)pPixmap->devPrivate.ptr = pixel;
 	    }
 
+	    exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
 	    REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
 			 pRegion);
 	}
commit 566dd3b7d789ba60d0adf33b3f729cfb02ff33cd
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Oct 3 11:59:52 2007 +1000

    exa: add new flags to denote driver handles all pixmap migration/hiding

diff --git a/exa/exa.c b/exa/exa.c
index 8a4b8c1..7ad226f 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -410,7 +410,7 @@ exaPixmapIsOffscreen(PixmapPtr p)
 
     save_ptr = p->devPrivate.ptr;
 
-    if (!save_ptr && pExaPixmap)
+    if (!save_ptr && pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS))
 	p->devPrivate.ptr = ExaGetPixmapAddress(p);
 
     if (pExaScr->info->PixmapIsOffscreen)
@@ -460,7 +460,7 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
     Bool	    offscreen = exaPixmapIsOffscreen(pPixmap);
 
     /* Unhide pixmap pointer */
-    if (pPixmap->devPrivate.ptr == NULL) {
+    if (pPixmap->devPrivate.ptr == NULL && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
 	pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
     }
 
@@ -521,8 +521,7 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
     ExaPixmapPriv  (pPixmap);
 
     /* Rehide pixmap pointer if we're doing that. */
-    if (pExaPixmap)
-    {
+    if (pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
 	pPixmap->devPrivate.ptr = NULL;
     }
 
diff --git a/exa/exa.h b/exa/exa.h
index f852df4..1ff0518 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -733,6 +733,13 @@ typedef struct _ExaDriver {
  * (right-to-left, bottom-to-top).
  */
 #define EXA_TWO_BITBLT_DIRECTIONS	(1 << 2)
+
+/**
+ * EXA_HANDLES_PIXMAPS indicates to EXA that the driver can handle
+ * all pixmap addressing and migration.
+ */
+#define EXA_HANDLES_PIXMAPS             (1 << 3)
+
 /** @} */
 
 ExaDriverPtr
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index c0e022c..7968521 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -553,6 +553,9 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
     ExaScreenPriv(pScreen);
     int i, j;
 
+    if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS)
+        return;
+
     /* If this debugging flag is set, check each pixmap for whether it is marked
      * as clean, and if so, actually check if that's the case.  This should help
      * catch issues with failing to mark a drawable as dirty.  While it will
commit 1df1fee82d3565f6d8cfb91ce25a81c23a10a4b5
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Oct 3 11:56:04 2007 +1000

    exa: make sure we set fb_ptr to NULL

diff --git a/exa/exa.c b/exa/exa.c
index 3e8054d..8a4b8c1 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -286,8 +286,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
 
         (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
                                        paddedWidth, NULL);
-         pExaPixmap->driverPriv = driver_priv;
-         pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+        pExaPixmap->driverPriv = driver_priv;
+        pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+        pExaPixmap->fb_ptr = NULL;
     } else {
          pExaPixmap->driverPriv = NULL;
          /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
commit c8ccf469dcb2d7609b23faa8b4999c436263051e
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Tue Oct 2 08:59:40 2007 -0700

    Do not build hw/xfree86/os-support/bus/ix86Pci.c on Linux.
    
    Linux has custom PCI bus support functions, so this generic code is
    unnecessary.

diff --git a/configure.ac b/configure.ac
index 5c5ff7d..a5f1866 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1428,6 +1428,7 @@ dnl has it in libc), or if libdl is needed to get it.
                case $host_os in
                  darwin*) ;;
 		 *bsd*) ;;
+		 linux*) ;;
                  *) xorg_bus_ix86pci=yes ;;
                esac
 		;;
@@ -1446,7 +1447,7 @@ dnl has it in libc), or if libdl is needed to get it.
 		;;
 	  x86_64*|amd64*)
 		case $host_os in
-		  darwin*|*bsd*)
+		  darwin*|*bsd*|linux*)
 			;;
 		  *)
 			xorg_bus_ix86pci="yes"
commit dcb4db1bf5b6fcfaed4e7162eb6c7a3a509e14bd
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Wed Sep 19 15:46:09 2007 +0200

    Xephyr: glx fixlet
    
    	* hw/kdrive/ephyr/ephyrhostglx.c:
    	  (ephyrHostGLXQueryVersion): properly query
    	  the host for its gxl version.

diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
index 21a109e..ad86d30 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -85,18 +85,35 @@ ephyrHostGLXQueryVersion (int *a_major, int *a_minor)
 {
     Bool is_ok = FALSE ;
     Display *dpy = hostx_get_display () ;
+    int major_opcode=0;
+    xGLXQueryVersionReq *req=NULL;
+    xGLXQueryVersionReply reply;
 
     EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ;
     EPHYR_LOG ("enter\n") ;
 
-    *a_major = 1 ;
-    *a_minor = 2 ;
-    /*
-    if (!glXQueryVersion (dpy, a_major, a_minor)) {
-        EPHYR_LOG_ERROR ("glxQueryVersion() failed\n") ;
+    if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+        EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
         goto out ;
     }
-    */
+    EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
+
+    /* Send the glXQueryVersion request */
+    memset (&reply, 0, sizeof (reply)) ;
+    LockDisplay (dpy);
+    GetReq (GLXQueryVersion, req);
+    req->reqType = major_opcode;
+    req->glxCode = X_GLXQueryVersion;
+    req->majorVersion = 2;
+    req->minorVersion = 1;
+    _XReply(dpy, (xReply*) &reply, 0, False);
+    UnlockDisplay (dpy);
+    SyncHandle ();
+
+    *a_major = reply.majorVersion ;
+    *a_minor = reply.minorVersion ;
+
+    EPHYR_LOG ("major:%d, minor:%d\n", *a_major, *a_minor) ;
 
     is_ok = TRUE ;
 out:
commit 6a435b00003fb00930299a0e0810c93afc23a72e
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Wed Sep 19 15:35:51 2007 +0200

    Xephyr: check presence of extensions in host X
    
    	* hw/kdrive/ephyr/hostx.c,h:
    	  (hostx_has_xshape),
    	  (hostx_has_glx),
    	  (hostx_has_dri): added these new entry points
    	* hw/kdrive/ephyr/ephyrdriext.c:
    	  (ephyrDRIExtensionInit):
    	  check presence of DRI and XShape extensions before
    	  trying to use them.
    	* hw/kdrive/ephyr/ephyrglxext.c:
    	  (ephyrHijackGLXExtension):
    	  check presence of glx extension before we use it.

diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index 41a1f4b..26c792d 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -136,6 +136,16 @@ ephyrDRIExtensionInit (ScreenPtr a_screen)
     EphyrDRIScreenPrivPtr screen_priv=NULL ;
 
     EPHYR_LOG ("enter\n") ;
+    if (!hostx_has_dri ()) {
+        EPHYR_LOG ("host does not have DRI extension\n") ;
+        goto out ;
+    }
+    EPHYR_LOG ("host X does have DRI extension\n") ;
+    if (!hostx_has_xshape ()) {
+        EPHYR_LOG ("host does not have XShape extension\n") ;
+        goto out ;
+    }
+    EPHYR_LOG ("host X does have XShape extension\n") ;
 
 #ifdef XF86DRI_EVENTS
     EventType = CreateNewResourceType (XF86DRIFreeEvents);
diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
index 27b2a2d..47c4fb1 100644
--- a/hw/kdrive/ephyr/ephyrglxext.c
+++ b/hw/kdrive/ephyr/ephyrglxext.c
@@ -81,7 +81,12 @@ ephyrHijackGLXExtension (void)
 {
     const void *(*dispatch_functions)[2];
 
-    EPHYR_LOG ("going to hijack some glx entry points ...\n") ;
+    if (!hostx_has_glx ()) {
+        EPHYR_LOG ("host X does not have GLX\n") ;
+        return FALSE ;
+    }
+    EPHYR_LOG ("host X does have GLX\n") ;
+
     if (!Single_dispatch_info.dispatch_functions) {
         EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ;
         return FALSE ;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index dd988dc..0ef1a62 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -23,6 +23,10 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
 #include "hostx.h"
 
 #include <stdlib.h>
@@ -41,8 +45,17 @@
 #include <X11/keysym.h>
 #include <X11/extensions/XShm.h>
 #include <X11/extensions/shape.h>
+#ifdef XEPHYR_DRI
+#include <GL/glx.h>
+#endif /*XEPHYR_DRI*/
 #include "ephyrlog.h"
 
+#ifdef XEPHYR_DRI
+extern Bool XF86DRIQueryExtension (Display *dpy,
+                                   int *event_basep,
+                                   int *error_basep);
+#endif
+
 /*  
  * All xlib calls go here, which gets built as its own .a .
  * Mixing kdrive and xlib headers causes all sorts of types
@@ -1070,68 +1083,6 @@ typedef struct {
 #define RESOURCE_PEERS_SIZE 1024*10
 static ResourcePair resource_peers[RESOURCE_PEERS_SIZE] ;
 
-int
-hostx_allocate_resource_id_peer (int a_local_resource_id,
-                                 int *a_remote_resource_id)
-{
-    int i=0 ;
-    ResourcePair *peer=NULL ;
-    Display *dpy=hostx_get_display ();
-
-    /*
-     * first make sure a resource peer
-     * does not exist already for
-     * a_local_resource_id
-     */
-    for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
-        if (resource_peers[i].is_valid
-            && resource_peers[i].local_id == a_local_resource_id) {
-            peer = &resource_peers[i] ;
-            break ;
-        }
-    }
-    /*
-     * find one free peer entry, an feed it with
-     */
-    if (!peer) {
-        for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
-            if (!resource_peers[i].is_valid) {
-                peer = &resource_peers[i] ;
-                break ;
-            }
-        }
-        if (peer) {
-            peer->remote_id = XAllocID (dpy);
-            peer->local_id = a_local_resource_id ;
-            peer->is_valid = TRUE ;
-        }
-    }
-    if (peer) {
-        *a_remote_resource_id = peer->remote_id ;
-        return TRUE ;
-    }
-    return FALSE ;
-}
-
-int
-hostx_get_resource_id_peer (int a_local_resource_id,
-                            int *a_remote_resource_id)
-{
-    int i=0 ;
-    ResourcePair *peer=NULL ;
-    for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
-        if (resource_peers[i].is_valid
-            && resource_peers[i].local_id == a_local_resource_id) {
-            peer = &resource_peers[i] ;
-            break ;
-        }
-    }
-    if (peer) {
-        *a_remote_resource_id = peer->remote_id ;
-        return TRUE ;
-    }
-    return FALSE ;
-}
 
 int
 hostx_create_window (EphyrBox *a_geometry,
@@ -1289,3 +1240,108 @@ hostx_set_window_clipping_rectangles (int a_window,
     return is_ok;
 }
 
+int
+hostx_has_xshape (void)
+{
+    int event_base=0, error_base=0 ;
+    Display *dpy=hostx_get_display () ;
+    if (!XShapeQueryExtension (dpy,
+                               &event_base,
+                               &error_base)) {
+        return FALSE ;
+    }
+    return TRUE;
+}
+
+#ifdef XEPHYR_DRI
+int
+hostx_allocate_resource_id_peer (int a_local_resource_id,
+                                 int *a_remote_resource_id)
+{
+    int i=0 ;
+    ResourcePair *peer=NULL ;
+    Display *dpy=hostx_get_display ();
+
+    /*
+     * first make sure a resource peer
+     * does not exist already for
+     * a_local_resource_id
+     */
+    for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+        if (resource_peers[i].is_valid
+            && resource_peers[i].local_id == a_local_resource_id) {
+            peer = &resource_peers[i] ;
+            break ;
+        }
+    }
+    /*
+     * find one free peer entry, an feed it with
+     */
+    if (!peer) {
+        for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+            if (!resource_peers[i].is_valid) {
+                peer = &resource_peers[i] ;
+                break ;
+            }
+        }
+        if (peer) {
+            peer->remote_id = XAllocID (dpy);
+            peer->local_id = a_local_resource_id ;
+            peer->is_valid = TRUE ;
+        }
+    }
+    if (peer) {
+        *a_remote_resource_id = peer->remote_id ;
+        return TRUE ;
+    }
+    return FALSE ;
+}
+
+int
+hostx_get_resource_id_peer (int a_local_resource_id,
+                            int *a_remote_resource_id)
+{
+    int i=0 ;
+    ResourcePair *peer=NULL ;
+    for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+        if (resource_peers[i].is_valid
+            && resource_peers[i].local_id == a_local_resource_id) {
+            peer = &resource_peers[i] ;
+            break ;
+        }
+    }
+    if (peer) {
+        *a_remote_resource_id = peer->remote_id ;
+        return TRUE ;
+    }
+    return FALSE ;
+}
+
+int
+hostx_has_dri (void)
+{
+    int event_base=0, error_base=0 ;
+    Display *dpy=hostx_get_display () ;
+
+    if (!XF86DRIQueryExtension (dpy,
+                                &event_base,
+                                &error_base)) {
+        return FALSE ;
+    }
+    return TRUE ;
+}
+
+int
+hostx_has_glx (void)
+{
+    Display *dpy=hostx_get_display () ;
+    int event_base=0, error_base=0 ;
+
+    if (!glXQueryExtension (dpy, &event_base, &error_base)) {
+        return FALSE ;
+    }
+    return TRUE ;
+}
+
+#endif /*XEPHYR_DRI*/
+
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 70255a1..941eece 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -215,12 +215,6 @@ hostx_get_extension_info (const char *a_ext_name,
 int
 hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
                         int *a_num_entries) ;
-int
-hostx_allocate_resource_id_peer (int a_local_resource_id,
-                                 int *a_remote_resource_id) ;
-int
-hostx_get_resource_id_peer (int a_local_resource_id,
-                            int *a_remote_resource_id) ;
 
 int hostx_create_window (EphyrBox *a_geometry,
                          int a_visual_id,
@@ -230,8 +224,6 @@ int hostx_destroy_window (int a_win) ;
 
 int hostx_set_window_geometry (int a_win, EphyrBox *a_geo) ;
 
-int hostx_lookup_peer_window (void *a_local_window,
-                              int *a_host_peer /*out parameter*/) ;
 
 int hostx_set_window_bounding_rectangles (int a_window,
                                           EphyrRect *a_rects,
@@ -239,4 +231,20 @@ int hostx_set_window_bounding_rectangles (int a_window,
 int hostx_set_window_clipping_rectangles (int a_window,
                                           EphyrRect *a_rects,
                                           int a_num_rects) ;
-#endif
+int hostx_has_xshape (void) ;
+
+#ifdef XEPHYR_DRI
+int hostx_lookup_peer_window (void *a_local_window,
+                              int *a_host_peer /*out parameter*/) ;
+int
+hostx_allocate_resource_id_peer (int a_local_resource_id,
+                                 int *a_remote_resource_id) ;
+int
+hostx_get_resource_id_peer (int a_local_resource_id,
+                            int *a_remote_resource_id) ;
+int hostx_has_dri (void) ;
+
+int hostx_has_glx (void) ;
+#endif /*XEPHYR_DRI*/
+
+#endif /*_XLIBS_STUFF_H_*/
commit 2b217fc055300d4c709dd27c4e8ec8166183993b
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Wed Sep 19 15:00:43 2007 +0200

    Xephyr: cleanup XF86dri.c a bit

diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c
index bf6c54f..f3f3179 100644
--- a/hw/kdrive/ephyr/XF86dri.c
+++ b/hw/kdrive/ephyr/XF86dri.c
@@ -108,9 +108,7 @@ static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
 #endif
 
 
-Bool XF86DRIQueryExtension (dpy, event_basep, error_basep)
-    Display *dpy;
-    int *event_basep, *error_basep;
+Bool XF86DRIQueryExtension (Display *dpy, int *event_basep, int *error_basep)
 {
     XExtDisplayInfo *info = find_display (dpy);
 
commit f731b9da7dbafad50dd5a1e8da28ce86ffab19b7
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Tue Sep 18 18:41:18 2007 +0200

    Xephyr: add -nodri and -noxv switches.
    
    	* hw/kdrive/ephyr/ephyr.c,ephyrinit.c::
    	  add -nodri and -noxv to disable either DRI or XV.
    	  When -nodri, mesa GL (non acceleretated) works.

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 63e0cb1..85aab28 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -43,6 +43,8 @@ extern int KdTsPhyScreen;
 KdKeyboardInfo *ephyrKbd;
 KdPointerInfo *ephyrMouse;
 EphyrKeySyms ephyrKeySyms;
+Bool ephyrNoDRI=FALSE ;
+Bool ephyrNoXV=FALSE ;
 
 static int mouseState = 0;
 
@@ -616,18 +618,23 @@ ephyrInitScreen (ScreenPtr pScreen)
   pScreen->CreateColormap = ephyrCreateColormap;
 
 #ifdef XV
-  if (!ephyrInitVideo (pScreen)) {
-      EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
-  } else {
-      EPHYR_LOG ("initialized xvideo okay\n") ;
+  if (!ephyrNoXV) {
+      if (!ephyrInitVideo (pScreen)) {
+          EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
+      } else {
+          EPHYR_LOG ("initialized xvideo okay\n") ;
+      }
   }
 #endif /*XV*/
 
 #ifdef XEPHYR_DRI
+  if (!ephyrNoDRI) {
     ephyrDRIExtensionInit (pScreen) ;
     ephyrHijackGLXExtension () ;
     ephyrProxyExtensionInit ("ATIFGLRXDRI") ;
+  }
 #endif
+
   return TRUE;
 }
 
@@ -639,12 +646,12 @@ ephyrFinishInitScreen (ScreenPtr pScreen)
    */
   if (!shadowSetup (pScreen))
     return FALSE;
-  
+
 #ifdef RANDR
   if (!ephyrRandRInit (pScreen))
     return FALSE;
 #endif
-    
+
   return TRUE;
 }
 
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index c8fbdff..cc7a367 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -33,6 +33,9 @@ extern Window EphyrPreExistingHostWin;
 extern Bool   EphyrWantGrayScale;
 extern Bool   kdHasPointer;
 extern Bool   kdHasKbd;
+extern Bool   ephyrNoDRI;
+extern Bool   ephyrNoXV;
+extern Bool noGlxVisualInit;
 
 void processScreenArg (char *screen_size, char *parent_id) ;
 
@@ -99,6 +102,8 @@ ddxUseMsg (void)
   ErrorF("-grayscale           Simulate 8bit grayscale\n");
   ErrorF("-fakexa              Simulate acceleration using software rendering\n");
   ErrorF("-verbosity <level>   Set log verbosity level\n");
+  ErrorF("-nodri               do not use DRI\n");
+  ErrorF("-noxv                do not use XV\n");
   ErrorF("\n");
 
   exit(1);
@@ -139,6 +144,8 @@ ddxProcessArgument (int argc, char **argv, int i)
 {
   EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] );
 
+  noGlxVisualInit = TRUE ;
+
   if (!strcmp (argv[i], "-parent"))
     {
       if(i+1 < argc)
@@ -199,6 +206,19 @@ ddxProcessArgument (int argc, char **argv, int i)
 	  exit(1) ;
 	}
     }
+  else if (!strcmp (argv[i], "-nodri"))
+   {
+       noGlxVisualInit = FALSE ;
+       ephyrNoDRI = TRUE ;
+       EPHYR_LOG ("no direct rendering enabled\n") ;
+       return 1 ;
+   }
+  else if (!strcmp (argv[i], "-noxv"))
+   {
+       ephyrNoXV = TRUE ;
+       EPHYR_LOG ("no XVideo enabled\n") ;
+       return 1 ;
+   }
   else if (argv[i][0] == ':')
     {
       hostx_set_display_name(argv[i]);
commit 50674391388b3cfe987782a3ad81b4f240f3db67
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Tue Sep 18 18:37:49 2007 +0200

    Kdrive: use fbcmap_mi.c instead of fbcmap.c
    
    	* hw/kdrive/src/Makefile.am: use fb/fbcmap_mi.c
    	  and not fb/fbcmap.c. This allows kdrive to take advantage of
    	  extensions redefining the entry points of  micmap.c stuff.
    	  For instance it allows Xephyr to have a working GL, which is not
    	  possible otherwise, because GL redefines mInitVisualsProc
    	  to initialise its visuals.

diff --git a/hw/kdrive/src/Makefile.am b/hw/kdrive/src/Makefile.am
index 20fae55..07ab8c8 100644
--- a/hw/kdrive/src/Makefile.am
+++ b/hw/kdrive/src/Makefile.am
@@ -37,4 +37,4 @@ libkdrive_a_SOURCES =	\
         $(top_srcdir)/mi/miinitext.c
 
 libkdrivestubs_a_SOURCES = \
-        $(top_srcdir)/fb/fbcmap.c
+        $(top_srcdir)/fb/fbcmap_mi.c
commit a5bd536869f646e4024befa84f6e677b990310bc
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Tue Sep 18 18:28:25 2007 +0200

    fbcmap_mi.c: add a missing api
    
            * fb/fbcmap_mi.c:
             (fbSetVisualTypesAndMasks): added this entry point that was missing.
             This is useful so that servers using this entry point can use fbcmap_mi.c,
             and be obliged to stick to fbcmap.c. Note that fbcmap.c does implement this
             entry point. Up to now, kdrive based server could not use fbcmap_mi.c because this
             entry point was missing. The will allow Xephyr to properly use GL.

diff --git a/fb/fbcmap_mi.c b/fb/fbcmap_mi.c
index 58bcae3..188decd 100644
--- a/fb/fbcmap_mi.c
+++ b/fb/fbcmap_mi.c
@@ -103,6 +103,14 @@ fbSetVisualTypes (int depth, int visuals, int bitsPerRGB)
     return miSetVisualTypes(depth, visuals, bitsPerRGB, -1);
 }
 
+Bool
+fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB,
+                          Pixel redMask, Pixel greenMask, Pixel blueMask)
+{
+    return miSetVisualTypesAndMasks(depth, visuals, bitsPerRGB, -1,
+                                    redMask, greenMask, blueMask);
+}
+
 /*
  * Given a list of formats for a screen, create a list
  * of visuals and depths for the screen which coorespond to
commit 6307ee77091041af2d34e93bc164352d4438a808
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Tue Sep 18 18:22:44 2007 +0200

    GLX: allow skipping of visual init wrapping
    
    	* GL/glx/glxvisuals.c: added boolean to disable
    	  calling init_visuals(). This gives a chance to Xephyr
    	  to take over visuals manipulation and avoid a crash at
    	  server shutdown in __glXMesaScreenDestroy(), due to the fact
    	  that mesa might sees more visual than what it has actually created in
    	  init_visuals(). It might see more visuals because Xephyr can augment
    	  the number of visuals, dynamically.
    	* os/utils.c: the boolean is actually defined here.

diff --git a/GL/glx/glxvisuals.c b/GL/glx/glxvisuals.c
index 0e9bded..46b380b 100644
--- a/GL/glx/glxvisuals.c
+++ b/GL/glx/glxvisuals.c
@@ -55,6 +55,7 @@
 
 void GlxWrapInitVisuals(miInitVisualsProcPtr *);
 
+extern Bool noGlxVisualInit;
 #include "glcontextmodes.h"
 
 struct ScreenVisualsRec {
@@ -452,14 +453,15 @@ Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
     /*
      * Setup the visuals supported by this particular screen.
      */
-    init_visuals(nvisualp, visualp, defaultVisp,
-		 *ndepthp, *depthp, *rootDepthp);
+    if (!noGlxVisualInit) {
+        init_visuals(nvisualp, visualp, defaultVisp,
+                     *ndepthp, *depthp, *rootDepthp);
+    }
 
 
     return True;
 }
 
-
 /************************************************************************/
 
 
diff --git a/os/utils.c b/os/utils.c
index 36c8dfe..31cb0af 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -160,6 +160,7 @@ _X_EXPORT Bool noFontCacheExtension = FALSE;
 #endif
 #ifdef GLXEXT
 _X_EXPORT Bool noGlxExtension = FALSE;
+_X_EXPORT Bool noGlxVisualInit = FALSE;
 #endif
 #ifdef SCREENSAVER
 _X_EXPORT Bool noScreenSaverExtension = FALSE;
commit ffe9ce6a843443606ad9367eca1645bf5e0635e5
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Mon Sep 17 22:13:51 2007 +0200

    Xephyr: fix a clipping issue xephyr-dri
    
    	* hw/kdrive/ephyr/ephyrdri.c:
    	  (ephyrDRIGetDrawableInfo): force the back clipping rects
    	  to equal the front clipping rects.
    	* hw/kdrive/ephyr/ephyrdriext.c:
    	  (ProcXF86DRIGetDrawableInfo): properly overclip the clipping rects we
    	   got from the client. This bug fixes a clipping rect that was too
    	   small in height, basically. Also fix a possible mem corruption.
    	* hw/kdrive/ephyr/hostx.c:
    	  (hostx_set_window_geometry): remove a useless XSync

diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
index c4637d0..e7d4128 100644
--- a/hw/kdrive/ephyr/ephyrdri.c
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -240,7 +240,7 @@ ephyrDRIGetDrawableInfo (int a_screen,
         goto out ;
     }
     EPHYR_LOG ("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h) ;
-    if (*a_num_back_clip_rects != *a_num_clip_rects) {
+    if (*a_num_clip_rects) {
         free (*a_back_clip_rects) ;
         *a_back_clip_rects = calloc (*a_num_clip_rects,
                                      sizeof (drm_clip_rect_t)) ;
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index be07e64..41a1f4b 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -1137,7 +1137,7 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
     WindowPtr window=NULL;
     EphyrWindowPair *pair=NULL;
     int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0, i=0;
-    drm_clip_rect_t *clipRects=NULL, *clippedRects=NULL;
+    drm_clip_rect_t *clipRects=NULL;
     drm_clip_rect_t *backClipRects=NULL;
 
     EPHYR_LOG ("enter\n") ;
@@ -1197,7 +1197,6 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
     }
     EPHYR_LOG ("num clip rects:%d, num back clip rects:%d\n",
                (int)rep.numClipRects, (int)rep.numBackClipRects) ;
-    backClipRects = clipRects ;
 
     rep.drawableX = X;
     rep.drawableY = Y;
@@ -1209,37 +1208,37 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
     rep.backX = backX;
     rep.backY = backY;
 
-    if (rep.numBackClipRects)
-        rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
-
-    clippedRects = clipRects;
 
     if (rep.numClipRects) {
-        /* Clip cliprects to screen dimensions (redirected windows) */
-        clippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t));
-
-        if (clippedRects) {
+        if (clipRects) {
             ScreenPtr pScreen = screenInfo.screens[stuff->screen];
             int i=0;
-
             EPHYR_LOG ("clip list of host gl drawable:\n") ;
             for (i = 0; i < rep.numClipRects; i++) {
-                clippedRects[i].x1 = max(clipRects[i].x1, 0);
-                clippedRects[i].y1 = max(clipRects[i].y1, 0);
-                clippedRects[i].x2 = min(clipRects[i].x2, pScreen->width);
-                clippedRects[i].y2 = min(clipRects[i].y2, pScreen->height);
+                clipRects[i].x1 = max (clipRects[i].x1, 0);
+                clipRects[i].y1 = max (clipRects[i].y1, 0);
+                clipRects[i].x2 = min (clipRects[i].x2,
+                                       pScreen->width + clipRects[i].x1) ;
+                clipRects[i].y2 = min (clipRects[i].y2,
+                                       pScreen->width + clipRects[i].y1) ;
+
                 EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
-                           clippedRects[i].x1, clippedRects[i].y1,
-                           clippedRects[i].x2, clippedRects[i].y2) ;
+                           clipRects[i].x1, clipRects[i].y1,
+                           clipRects[i].x2, clipRects[i].y2) ;
             }
-
-            /*rep.numClipRects = j*/;
-            EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ;
         } else {
             rep.numClipRects = 0;
         }
-        rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+    } else {
+        EPHYR_LOG ("got zero host gl drawable clipping rects\n") ;
     }
+    rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+    backClipRects = clipRects ;
+    rep.numBackClipRects = rep.numClipRects ;
+    if (rep.numBackClipRects)
+        rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
+    EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ;
+    EPHYR_LOG ("num host back clip rects:%d\n", (int)rep.numBackClipRects) ;
 
     rep.length = ((rep.length + 3) & ~3) >> 2;
 
@@ -1248,8 +1247,7 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
     if (rep.numClipRects) {
         WriteToClient(client,
                       sizeof(drm_clip_rect_t) * rep.numClipRects,
-                      (char *)clippedRects);
-        xfree(clippedRects);
+                      (char *)clipRects);
     }
 
     if (rep.numBackClipRects) {
@@ -1257,6 +1255,10 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
                       sizeof(drm_clip_rect_t) * rep.numBackClipRects,
                       (char *)backClipRects);
     }
+    if (clipRects) {
+        xfree(clipRects);
+        clipRects = NULL ;
+    }
     EPHYR_LOG ("leave\n") ;
 
     return (client->noClientException);
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index d50c6b1..dd988dc 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -1211,7 +1211,6 @@ hostx_set_window_geometry (int a_win, EphyrBox *a_geo)
 
     XMoveWindow (dpy, a_win, a_geo->x, a_geo->y) ;
     XResizeWindow (dpy, a_win, a_geo->width, a_geo->height) ;
-    XFlush (dpy) ;
     EPHYR_LOG ("leave\n") ;
     return TRUE;
 }
commit 79782726617d4b5a4f9b376f21936d035fc870e1
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Mon Sep 17 18:15:03 2007 +0200

    Xephyr: properly clip GL drawables in Xephyr

diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c
index fc35ce2..bf6c54f 100644
--- a/hw/kdrive/ephyr/XF86dri.c
+++ b/hw/kdrive/ephyr/XF86dri.c
@@ -467,7 +467,7 @@ Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
 {
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRIGetDrawableInfoReply rep;
-    xXF86DRIGetDrawableInfoReq *req;
+    xXF86DRIGetDrawableInfoReq *req=NULL;
     int total_rects;
 
     TRACE("GetDrawableInfo...");
@@ -521,7 +521,7 @@ Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
        int len = sizeof(drm_clip_rect_t) * (*numClipRects);
 
        *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
-       if (*pClipRects) 
+       if (*pClipRects)
 	  _XRead(dpy, (char*)*pClipRects, len);
     } else {
         *pClipRects = NULL;
diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
index 17ea712..c4637d0 100644
--- a/hw/kdrive/ephyr/ephyrdri.c
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -240,6 +240,17 @@ ephyrDRIGetDrawableInfo (int a_screen,
         goto out ;
     }
     EPHYR_LOG ("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h) ;
+    if (*a_num_back_clip_rects != *a_num_clip_rects) {
+        free (*a_back_clip_rects) ;
+        *a_back_clip_rects = calloc (*a_num_clip_rects,
+                                     sizeof (drm_clip_rect_t)) ;
+        memmove (*a_back_clip_rects,
+                 *a_clip_rects,
+                 *a_num_clip_rects * sizeof (drm_clip_rect_t)) ;
+        *a_num_back_clip_rects = *a_num_clip_rects;
+    }
+    EPHYR_LOG ("num back clip rects:%d, num clip rects:%d\n",
+               *a_num_clip_rects, *a_num_back_clip_rects) ;
     *a_back_x = *a_x ;
     *a_back_y = *a_y ;
     *a_w = attrs.width;
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index 04f3b39..be07e64 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -73,6 +73,7 @@ typedef struct {
     DestroyWindowProcPtr DestroyWindow ;
     MoveWindowProcPtr MoveWindow ;
     PositionWindowProcPtr PositionWindow ;
+    ClipNotifyProcPtr ClipNotify ;
 } EphyrDRIScreenPrivRec;
 typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr;
 
@@ -107,6 +108,9 @@ static void ephyrDRIMoveWindow (WindowPtr a_win,
                                 VTKind a_kind);
 static Bool ephyrDRIPositionWindow (WindowPtr a_win,
                                     int x, int y) ;
+static void ephyrDRIClipNotify (WindowPtr a_win,
+                                int a_x, int a_y) ;
+
 static Bool EphyrMirrorHostVisuals (void) ;
 static Bool destroyHostPeerWindow (const WindowPtr a_win) ;
 static Bool findWindowPairFromLocal (WindowPtr a_local,
@@ -204,11 +208,13 @@ ephyrDRIScreenInit (ScreenPtr a_screen)
     screen_priv->DestroyWindow = a_screen->DestroyWindow ;
     screen_priv->MoveWindow = a_screen->MoveWindow ;
     screen_priv->PositionWindow = a_screen->PositionWindow ;
+    screen_priv->ClipNotify = a_screen->ClipNotify ;
 
     a_screen->CreateWindow = ephyrDRICreateWindow ;
     a_screen->DestroyWindow = ephyrDRIDestroyWindow ;
     a_screen->MoveWindow = ephyrDRIMoveWindow ;
     a_screen->PositionWindow = ephyrDRIPositionWindow ;
+    a_screen->ClipNotify = ephyrDRIClipNotify ;
 
     is_ok = TRUE ;
 out:
@@ -259,7 +265,9 @@ ephyrDRIDestroyWindow (WindowPtr a_win)
                               FALSE) ;
 
     screen->DestroyWindow = screen_priv->DestroyWindow ;
-    is_ok = (*screen->DestroyWindow) (a_win) ;
+    if (screen->DestroyWindow) {
+        is_ok = (*screen->DestroyWindow) (a_win) ;
+    }
     screen->DestroyWindow = ephyrDRIDestroyWindow ;
 
     if (is_ok) {
@@ -298,7 +306,9 @@ ephyrDRIMoveWindow (WindowPtr a_win,
                           && screen_priv->MoveWindow) ;
 
     screen->MoveWindow = screen_priv->MoveWindow ;
-    (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ;
+    if (screen->MoveWindow) {
+        (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ;
+    }
     screen->MoveWindow = ephyrDRIMoveWindow ;
 
     EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
@@ -356,7 +366,9 @@ ephyrDRIPositionWindow (WindowPtr a_win,
                               FALSE) ;
 
     screen->PositionWindow = screen_priv->PositionWindow ;
-    (*screen->PositionWindow) (a_win, a_x, a_y) ;
+    if (screen->PositionWindow) {
+        (*screen->PositionWindow) (a_win, a_x, a_y) ;
+    }
     screen->PositionWindow = ephyrDRIPositionWindow ;
 
     EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
@@ -385,6 +397,73 @@ out:
     return is_ok ;
 }
 
+static void
+ephyrDRIClipNotify (WindowPtr a_win,
+                    int a_x, int a_y)
+{
+    Bool is_ok=FALSE ;
+    ScreenPtr screen=NULL ;
+    EphyrDRIScreenPrivPtr screen_priv =NULL;
+    EphyrDRIWindowPrivPtr win_priv=NULL ;
+    EphyrWindowPair *pair=NULL ;
+    EphyrRect *rects=NULL;
+    int i=0 ;
+
+    EPHYR_RETURN_IF_FAIL (a_win) ;
+
+    EPHYR_LOG ("enter\n") ;
+    screen = a_win->drawable.pScreen ;
+    EPHYR_RETURN_IF_FAIL (screen) ;
+    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+    EPHYR_RETURN_IF_FAIL (screen_priv && screen_priv->ClipNotify) ;
+
+    screen->ClipNotify = screen_priv->ClipNotify ;
+    if (screen->ClipNotify) {
+        (*screen->ClipNotify) (a_win, a_x, a_y) ;
+    }
+    screen->ClipNotify = ephyrDRIClipNotify ;
+
+    EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
+    win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+    if (!win_priv) {
+        EPHYR_LOG ("not a DRI peered window\n") ;
+        is_ok = TRUE ;
+        goto out ;
+    }
+    if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+        EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+        goto out ;
+    }
+    rects = xcalloc (REGION_NUM_RECTS (&a_win->clipList),
+                     sizeof (EphyrRect)) ;
+    for (i=0; i < REGION_NUM_RECTS (&a_win->clipList); i++) {
+        memmove (&rects[i],
+                 &REGION_RECTS (&a_win->clipList)[i],
+                 sizeof (EphyrRect)) ;
+        rects[i].x1 -= a_win->drawable.x;
+        rects[i].x2 -= a_win->drawable.x;
+        rects[i].y1 -= a_win->drawable.y;
+        rects[i].y2 -= a_win->drawable.y;
+    }
+    /*
+     * push the clipping region of this window
+     * to the peer window in the host
+     */
+    is_ok = hostx_set_window_bounding_rectangles
+                                (pair->remote,
+                                 rects,
+                                 REGION_NUM_RECTS (&a_win->clipList)) ;
+    is_ok = TRUE ;
+
+out:
+    if (rects) {
+        xfree (rects) ;
+        rects = NULL ;
+    }
+    EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+    /*do cleanup here*/
+}
+
 /**
  * Duplicates a visual of a_screen
  * In screen a_screen, for depth a_depth, find a visual which
@@ -1057,9 +1136,9 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
     DrawablePtr drawable;
     WindowPtr window=NULL;
     EphyrWindowPair *pair=NULL;
-    int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0;
-    drm_clip_rect_t *pClipRects=NULL, *pClippedRects=NULL;
-    drm_clip_rect_t *pBackClipRects=NULL;
+    int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0, i=0;
+    drm_clip_rect_t *clipRects=NULL, *clippedRects=NULL;
+    drm_clip_rect_t *backClipRects=NULL;
 
     EPHYR_LOG ("enter\n") ;
     memset (&rep, 0, sizeof (rep)) ;
@@ -1091,6 +1170,15 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
         EPHYR_LOG_ERROR ("failed to find remote peer drawable\n") ;
         return BadMatch ;
     }
+    EPHYR_LOG ("clip list of xephyr gl drawable:\n") ;
+    for (i=0; i < REGION_NUM_RECTS (&window->clipList); i++) {
+        EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
+                   REGION_RECTS (&window->clipList)[i].x1,
+                   REGION_RECTS (&window->clipList)[i].y1,
+                   REGION_RECTS (&window->clipList)[i].x2,
+                   REGION_RECTS (&window->clipList)[i].y2) ;
+    }
+
     if (!ephyrDRIGetDrawableInfo (stuff->screen,
                                   pair->remote/*the drawable in hostx*/,
                                   (unsigned int*)&rep.drawableTableIndex,
@@ -1100,54 +1188,56 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
                                   (int*)&W,
                                   (int*)&H,
                                   (int*)&rep.numClipRects,
-                                  &pClipRects,
+                                  &clipRects,
                                   &backX,
                                   &backY,
                                   (int*)&rep.numBackClipRects,
-                                  &pBackClipRects)) {
+                                  &backClipRects)) {
         return BadValue;
     }
+    EPHYR_LOG ("num clip rects:%d, num back clip rects:%d\n",
+               (int)rep.numClipRects, (int)rep.numBackClipRects) ;
+    backClipRects = clipRects ;
 
     rep.drawableX = X;
     rep.drawableY = Y;
     rep.drawableWidth = W;
     rep.drawableHeight = H;
-    rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - 
+    rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
                   SIZEOF(xGenericReply));
 
     rep.backX = backX;
     rep.backY = backY;
 
-    if (rep.numBackClipRects) 
-        rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;    
+    if (rep.numBackClipRects)
+        rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
 
-    pClippedRects = pClipRects;
+    clippedRects = clipRects;
 
     if (rep.numClipRects) {
         /* Clip cliprects to screen dimensions (redirected windows) */
-        pClippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t));
+        clippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t));
 
-        if (pClippedRects) {
+        if (clippedRects) {
             ScreenPtr pScreen = screenInfo.screens[stuff->screen];
-            int i, j;
-
-            for (i = 0, j = 0; i < rep.numClipRects; i++) {
-                pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
-                pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
-                pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
-                pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
-
-                if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
-                        pClippedRects[j].y1 < pClippedRects[j].y2) {
-                    j++;
-                }
+            int i=0;
+
+            EPHYR_LOG ("clip list of host gl drawable:\n") ;
+            for (i = 0; i < rep.numClipRects; i++) {
+                clippedRects[i].x1 = max(clipRects[i].x1, 0);
+                clippedRects[i].y1 = max(clipRects[i].y1, 0);
+                clippedRects[i].x2 = min(clipRects[i].x2, pScreen->width);
+                clippedRects[i].y2 = min(clipRects[i].y2, pScreen->height);
+                EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
+                           clippedRects[i].x1, clippedRects[i].y1,
+                           clippedRects[i].x2, clippedRects[i].y2) ;
             }
 
-            rep.numClipRects = j;
+            /*rep.numClipRects = j*/;
+            EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ;
         } else {
             rep.numClipRects = 0;
         }
-
         rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
     }
 
@@ -1156,16 +1246,16 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
     WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
 
     if (rep.numClipRects) {
-        WriteToClient(client,  
-                sizeof(drm_clip_rect_t) * rep.numClipRects,
-                (char *)pClippedRects);
-        xfree(pClippedRects);
+        WriteToClient(client,
+                      sizeof(drm_clip_rect_t) * rep.numClipRects,
+                      (char *)clippedRects);
+        xfree(clippedRects);
     }
 
     if (rep.numBackClipRects) {
-        WriteToClient(client, 
-                sizeof(drm_clip_rect_t) * rep.numBackClipRects,
-                (char *)pBackClipRects);
+        WriteToClient(client,
+                      sizeof(drm_clip_rect_t) * rep.numBackClipRects,
+                      (char *)backClipRects);
     }
     EPHYR_LOG ("leave\n") ;
 
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index 6509274..a0ca76b 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -773,6 +773,7 @@ ephyrHostXVPutImage (int a_port_id,
 
     EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
 
+    memset (&gc_values, 0, sizeof (gc_values)) ;
     gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
     if (!gc) {
         EPHYR_LOG_ERROR ("failed to create gc \n") ;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 7636e25..d50c6b1 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -40,6 +40,7 @@
 #include <X11/Xatom.h>
 #include <X11/keysym.h>
 #include <X11/extensions/XShm.h>
+#include <X11/extensions/shape.h>
 #include "ephyrlog.h"
 
 /*  
@@ -1215,3 +1216,77 @@ hostx_set_window_geometry (int a_win, EphyrBox *a_geo)
     return TRUE;
 }
 
+int
+hostx_set_window_bounding_rectangles (int a_window,
+                                      EphyrRect *a_rects,
+                                      int a_num_rects)
+{
+    Bool is_ok=FALSE;
+    Display *dpy=hostx_get_display () ;
+    int i=0 ;
+    XRectangle *rects=NULL ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy && a_rects, FALSE) ;
+
+    EPHYR_LOG ("enter. num rects:%d\n", a_num_rects) ;
+
+    rects = calloc (a_num_rects, sizeof (XRectangle)) ;
+    for (i=0; i<a_num_rects; i++) {
+        rects[i].x = a_rects[i].x1 ;
+        rects[i].y = a_rects[i].y1 ;
+        rects[i].width = abs (a_rects[i].x2 - a_rects[i].x1);
+        rects[i].height = abs (a_rects[i].y2 - a_rects[i].y1) ;
+        EPHYR_LOG ("borders clipped to rect[x:%d,y:%d,w:%d,h:%d]\n",
+                   rects[i].x, rects[i].y,
+                   rects[i].width, rects[i].height) ;
+    }
+    /*this aways returns 1*/
+    XShapeCombineRectangles (dpy, a_window, ShapeBounding, 0, 0,
+                             rects, a_num_rects, ShapeSet, YXBanded) ;
+    is_ok = TRUE ;
+
+    if (rects) {
+        free (rects) ;
+        rects = NULL ;
+    }
+    EPHYR_LOG ("leave\n") ;
+    return is_ok;
+}
+
+int
+hostx_set_window_clipping_rectangles (int a_window,
+                                      EphyrRect *a_rects,
+                                      int a_num_rects)
+{
+    Bool is_ok=FALSE;
+    Display *dpy=hostx_get_display () ;
+    int i=0 ;
+    XRectangle *rects=NULL ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy && a_rects, FALSE) ;
+
+    EPHYR_LOG ("enter. num rects:%d\n", a_num_rects) ;
+
+    rects = calloc (a_num_rects, sizeof (XRectangle)) ;
+    for (i=0; i<a_num_rects; i++) {
+        rects[i].x = a_rects[i].x1 ;
+        rects[i].y = a_rects[i].y1 ;
+        rects[i].width = abs (a_rects[i].x2 - a_rects[i].x1);
+        rects[i].height = abs (a_rects[i].y2 - a_rects[i].y1) ;
+        EPHYR_LOG ("clipped to rect[x:%d,y:%d,w:%d,h:%d]\n",
+                   rects[i].x, rects[i].y,
+                   rects[i].width, rects[i].height) ;
+    }
+    /*this aways returns 1*/
+    XShapeCombineRectangles (dpy, a_window, ShapeClip, 0, 0,
+                             rects, a_num_rects, ShapeSet, YXBanded) ;
+    is_ok = TRUE ;
+
+    if (rects) {
+        free (rects) ;
+        rects = NULL ;
+    }
+    EPHYR_LOG ("leave\n") ;
+    return is_ok;
+}
+
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 3cd27ff..70255a1 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -114,6 +114,10 @@ typedef struct {
     int x,y,width,height;
 } EphyrBox;
 
+typedef struct {
+    short x1,y1,x2,y2;
+} EphyrRect;
+
 int
 hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
 
@@ -229,4 +233,10 @@ int hostx_set_window_geometry (int a_win, EphyrBox *a_geo) ;
 int hostx_lookup_peer_window (void *a_local_window,
                               int *a_host_peer /*out parameter*/) ;
 
+int hostx_set_window_bounding_rectangles (int a_window,
+                                          EphyrRect *a_rects,
+                                          int a_num_rects) ;
+int hostx_set_window_clipping_rectangles (int a_window,
+                                          EphyrRect *a_rects,
+                                          int a_num_rects) ;
 #endif
commit 3816d64e50a59e0ef276ddd6cb250cab98a49392
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Sun Sep 9 15:20:51 2007 +0200

    Xephyr: oops, forgot to add ephyrdriext.h

diff --git a/hw/kdrive/ephyr/ephyrdriext.h b/hw/kdrive/ephyr/ephyrdriext.h
new file mode 100644
index 0000000..66af833
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdriext.h
@@ -0,0 +1,32 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifndef __EPHYRDRIEXT_H__
+#define __EPHYRDRIEXT_H__
+Bool ephyrDRIExtensionInit (ScreenPtr a_screen) ;
+#endif /*__EPHYRDRIEXT_H__*/
+
commit cf58781eee7d91a3bbca701a2c4523a36f8e0abb
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Sat Sep 8 00:33:59 2007 +0200

    Xephyr: make accelerated glxgears work in Xephyr
    
    	* hw/kdrive/ephyr/ephyr.c:
    	 (ephyrInitialize): cleanup ephyrDRI extension init.
    	 remove functions that belongs in ephyrdriext.c .
    	* hw/kdrive/ephyr/ephyrdri.c:
    	 (ephyrDRICreateDrawable): create the drawable on the host X peer
    	  window, not on the host xephyr main window.
    	 (ephyrDRIGetDrawableInfo): get drawable info of the host X peer
    	  window.
    	* hw/kdrive/ephyr/ephyrdriext.c: make ephyr DRI extention wrap
    	  a bunch of screen ops so that it can update the host X peer
    	  window whenever DRI bound drawable are moved in Xephyr.
    	  Also code the building blocks of the management of the
    	  host X window peer.
    	* hw/kdrive/ephyr/hostx.c,h:
    	  (hostx_create_window): added this new entry point
    	  (hostx_destroy_window): ditto
    	  ()hostx_set_window_geometry): ditto

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 97eac51..63e0cb1 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -34,6 +34,7 @@
 
 #ifdef XEPHYR_DRI
 #include "ephyrdri.h"
+#include "ephyrdriext.h"
 #include "ephyrglxext.h"
 #include "ephyrproxyext.h"
 #endif /*XEPHYR_DRI*/
@@ -52,11 +53,6 @@ typedef struct _EphyrInputPrivate {
 Bool   EphyrWantGrayScale = 0;
 
 
-#ifdef XEPHYR_DRI
-extern void ephyrDRIExtensionInit(void) ;
-static Bool EphyrMirrorHostVisuals (void) ;
-#endif
-
 Bool
 ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
 {
@@ -628,10 +624,9 @@ ephyrInitScreen (ScreenPtr pScreen)
 #endif /*XV*/
 
 #ifdef XEPHYR_DRI
-    ephyrDRIExtensionInit () ;
+    ephyrDRIExtensionInit (pScreen) ;
     ephyrHijackGLXExtension () ;
     ephyrProxyExtensionInit ("ATIFGLRXDRI") ;
-    EphyrMirrorHostVisuals () ;
 #endif
   return TRUE;
 }
@@ -1048,171 +1043,6 @@ EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
 {
 }
 
-/**
- * Duplicates a visual of a_screen
- * In screen a_screen, for depth a_depth, find a visual which
- * bitsPerRGBValue and colormap size equal
- * a_bits_per_rgb_values and a_colormap_entries.
- * The ID of that duplicated visual is set to a_new_id.
- * That duplicated visual is then added to the list of visuals
- * of the screen.
- */
-static Bool
-EphyrDuplicateVisual (unsigned int a_screen,
-                      short a_depth,
-                      short a_class,
-                      short a_bits_per_rgb_values,
-                      short a_colormap_entries,
-                      unsigned int a_red_mask,
-                      unsigned int a_green_mask,
-                      unsigned int a_blue_mask,
-                      unsigned int a_new_id)
-{
-    Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ;
-    ScreenPtr screen=NULL ;
-    VisualRec new_visual, *new_visuals=NULL ;
-    int i=0 ;
-
-    EPHYR_LOG ("enter\n") ; 
-    if (a_screen > screenInfo.numScreens) {
-        EPHYR_LOG_ERROR ("bad screen number\n") ;
-        goto out;
-    }
-    memset (&new_visual, 0, sizeof (VisualRec)) ;
-
-    /*get the screen pointed to by a_screen*/
-    screen = screenInfo.screens[a_screen] ;
-    EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
-
-    /*
-     * In that screen, first look for an existing visual that has the
-     * same characteristics as those passed in parameter
-     * to this function and copy it.
-     */
-    for (i=0; i < screen->numVisuals; i++) {
-        if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
-            screen->visuals[i].ColormapEntries == a_colormap_entries ) {
-            /*copy the visual found*/
-            memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
-            new_visual.vid = a_new_id ;
-            new_visual.class = a_class ;
-            new_visual.redMask = a_red_mask ;
-            new_visual.greenMask = a_green_mask ;
-            new_visual.blueMask = a_blue_mask ;
-            found_visual = TRUE ;
-            EPHYR_LOG ("found a visual that matches visual id: %d\n",
-                       a_new_id) ;
-            break;
-        }
-    }
-    if (!found_visual) {
-        EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ;
-        goto out ;
-    }
-    /*
-     * be prepare to extend screen->visuals to add new_visual to it
-     */
-    new_visuals = xcalloc (screen->numVisuals+1, sizeof (VisualRec)) ;
-    memmove (new_visuals,
-             screen->visuals,
-             screen->numVisuals*sizeof (VisualRec)) ;
-    memmove (&new_visuals[screen->numVisuals],
-             &new_visual,
-             sizeof (VisualRec)) ;
-    /*
-     * Now, in that same screen, update the screen->allowedDepths member.
-     * In that array, each element represents the visuals applicable to
-     * a given depth. So we need to add an entry matching the new visual
-     * that we are going to add to screen->visuals
-     */
-    for (i=0; i<screen->numDepths; i++) {
-        VisualID *vids=NULL;
-        DepthPtr cur_depth=NULL ;
-        /*find the entry matching a_depth*/
-        if (screen->allowedDepths[i].depth != a_depth)
-            continue ;
-        cur_depth = &screen->allowedDepths[i];
-        /*
-         * extend the list of visual IDs in that entry,
-         * so to add a_new_id in there.
-         */
-        vids = xrealloc (cur_depth->vids,
-                         (cur_depth->numVids+1)*sizeof (VisualID));
-        if (!vids) {
-            EPHYR_LOG_ERROR ("failed to realloc numids\n") ;
-            goto out ;
-        }
-        vids[cur_depth->numVids] = a_new_id ;
-        /*
-         * Okay now commit our change.
-         * Do really update screen->allowedDepths[i]
-         */
-        cur_depth->numVids++ ;
-        cur_depth->vids = vids ;
-        found_depth=TRUE;
-    }
-    if (!found_depth) {
-        EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n",
-                         a_screen) ;
-        goto out ;
-    }
-    /*
-     * Commit our change to screen->visuals
-     */
-    xfree (screen->visuals) ;
-    screen->visuals = new_visuals ;
-    screen->numVisuals++ ;
-    new_visuals = NULL ;
-
-    is_ok = TRUE ;
-out:
-    if (new_visuals) {
-        xfree (new_visuals) ;
-        new_visuals = NULL ;
-    }
-    EPHYR_LOG ("leave\n") ; 
-    return is_ok ;
-}
-
-/**
- * Duplicates the visuals of the host X server.
- * This is necessary to have visuals that have the same
- * ID as those of the host X. It is important to have that for
- * GLX.
- */
-static Bool
-EphyrMirrorHostVisuals (void)
-{
-    Bool is_ok=FALSE;
-    EphyrHostVisualInfo  *visuals=NULL;
-    int nb_visuals=0, i=0;
-
-    EPHYR_LOG ("enter\n") ;
-    if (!hostx_get_visuals_info (&visuals, &nb_visuals)) {
-        EPHYR_LOG_ERROR ("failed to get host visuals\n") ;
-        goto out ;
-    }
-    for (i=0; i<nb_visuals; i++) {
-        if (!EphyrDuplicateVisual (visuals[i].screen,
-                                   visuals[i].depth,
-                                   visuals[i].class,
-                                   visuals[i].bits_per_rgb,
-                                   visuals[i].colormap_size,
-                                   visuals[i].red_mask,
-                                   visuals[i].green_mask,
-                                   visuals[i].blue_mask,
-                                   visuals[i].visualid)) {
-            EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
-                             (int)visuals[i].visualid) ;
-        }
-    }
-
-    is_ok = TRUE ;
-out:
-    EPHYR_LOG ("leave\n") ;
-    return is_ok;
-}
-
 
 KdKeyboardDriver EphyrKeyboardDriver = {
     "ephyr",
diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
index 3f470f8..17ea712 100644
--- a/hw/kdrive/ephyr/ephyrdri.c
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -182,10 +182,9 @@ ephyrDRICreateDrawable (int a_screen,
 {
     Bool is_ok=FALSE;
     Display *dpy=hostx_get_display () ;
-    int host_win=hostx_get_window () ;
 
     EPHYR_LOG ("enter\n") ;
-    is_ok = XF86DRICreateDrawable (dpy, a_screen, host_win, a_hw_drawable) ;
+    is_ok = XF86DRICreateDrawable (dpy, a_screen, a_drawable, a_hw_drawable) ;
     EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
     return is_ok ;
 }
@@ -201,7 +200,7 @@ ephyrDRIDestroyDrawable (int a_screen, int a_drawable)
 
 Bool
 ephyrDRIGetDrawableInfo (int a_screen,
-                         void *a_drawable,
+                         int a_drawable,
                          unsigned int *a_index,
                          unsigned int *a_stamp,
                          int *a_x,
@@ -217,20 +216,19 @@ ephyrDRIGetDrawableInfo (int a_screen,
 {
     Bool is_ok=FALSE;
     Display *dpy=hostx_get_display ()  ;
-    DrawablePtr drawable = a_drawable ;
     EphyrHostWindowAttributes attrs ;
 
-    EPHYR_RETURN_VAL_IF_FAIL (drawable && a_x && a_y && a_w && a_h
+    EPHYR_RETURN_VAL_IF_FAIL (a_x && a_y && a_w && a_h
                               && a_num_clip_rects,
                               FALSE) ;
 
     EPHYR_LOG ("enter\n") ;
     memset (&attrs, 0, sizeof (attrs)) ;
-    if (!hostx_get_window_attributes (hostx_get_window (), &attrs)) {
+    if (!hostx_get_window_attributes (a_drawable, &attrs)) {
         EPHYR_LOG_ERROR ("failed to query host window attributes\n") ;
         goto out;
     }
-    if (!XF86DRIGetDrawableInfo (dpy, a_screen, hostx_get_window (),
+    if (!XF86DRIGetDrawableInfo (dpy, a_screen, a_drawable,
                                  a_index, a_stamp,
                                  a_x, a_y,
                                  a_w, a_h,
@@ -242,12 +240,10 @@ ephyrDRIGetDrawableInfo (int a_screen,
         goto out ;
     }
     EPHYR_LOG ("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h) ;
-    *a_x += drawable->x ;
-    *a_y += drawable->y ;
     *a_back_x = *a_x ;
     *a_back_y = *a_y ;
-    *a_w = drawable->width;
-    *a_h = drawable->height;
+    *a_w = attrs.width;
+    *a_h = attrs.height;
 
     is_ok = TRUE ;
 out:
diff --git a/hw/kdrive/ephyr/ephyrdri.h b/hw/kdrive/ephyr/ephyrdri.h
index ffbbb8e..af8bb11 100644
--- a/hw/kdrive/ephyr/ephyrdri.h
+++ b/hw/kdrive/ephyr/ephyrdri.h
@@ -51,7 +51,7 @@ Bool ephyrDRICreateDrawable (int a_screen,
                              drm_drawable_t *a_hw_drawable) ;
 Bool ephyrDRIDestroyDrawable (int a_screen, int a_drawable) ;
 Bool ephyrDRIGetDrawableInfo (int a_screen,
-                              void* /*DrawablePtr*/ a_drawable,
+                              int /*Drawable*/a_drawable,
                               unsigned int *a_index,
                               unsigned int *a_stamp,
                               int *a_x,
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index 443fe9d..04f3b39 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -49,12 +49,33 @@
 #include "colormapst.h"
 #include "cursorstr.h"
 #include "scrnintstr.h"
+#include "windowstr.h"
 #include "servermd.h"
 #include "swaprep.h"
 #include "ephyrdri.h"
+#include "ephyrdriext.h"
+#include "hostx.h"
 #define _HAVE_XALLOC_DECLS
 #include "ephyrlog.h"
 
+typedef struct {
+    WindowPtr local ;
+    int remote ;
+} EphyrWindowPair;
+
+typedef struct {
+    int foo;
+} EphyrDRIWindowPrivRec;
+typedef EphyrDRIWindowPrivRec* EphyrDRIWindowPrivPtr;
+
+typedef struct {
+    CreateWindowProcPtr CreateWindow ;
+    DestroyWindowProcPtr DestroyWindow ;
+    MoveWindowProcPtr MoveWindow ;
+    PositionWindowProcPtr PositionWindow ;
+} EphyrDRIScreenPrivRec;
+typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr;
+
 static int DRIErrorBase;
 
 static DISPATCH_PROC(ProcXF86DRIQueryVersion);
@@ -77,18 +98,43 @@ static DISPATCH_PROC(SProcXF86DRIDispatch);
 
 static void XF86DRIResetProc(ExtensionEntry* extEntry);
 
+static Bool ephyrDRIScreenInit (ScreenPtr a_screen) ;
+static Bool ephyrDRICreateWindow (WindowPtr a_win) ;
+static Bool ephyrDRIDestroyWindow (WindowPtr a_win) ;
+static void ephyrDRIMoveWindow (WindowPtr a_win,
+                                int a_x, int a_y,
+                                WindowPtr a_siblings,
+                                VTKind a_kind);
+static Bool ephyrDRIPositionWindow (WindowPtr a_win,
+                                    int x, int y) ;
+static Bool EphyrMirrorHostVisuals (void) ;
+static Bool destroyHostPeerWindow (const WindowPtr a_win) ;
+static Bool findWindowPairFromLocal (WindowPtr a_local,
+                                     EphyrWindowPair **a_pair);
+
 static unsigned char DRIReqCode = 0;
 
-extern void ephyrDRIExtensionInit(void);
+static int ephyrDRIGeneration=-1 ;
+static int ephyrDRIWindowIndex=-1 ;
+static int ephyrDRIScreenIndex=-1 ;
+
+#define GET_EPHYR_DRI_WINDOW_PRIV(win) \
+    ((EphyrDRIWindowPrivPtr)((win)->devPrivates[ephyrDRIWindowIndex].ptr))
+#define GET_EPHYR_DRI_SCREEN_PRIV(screen) \
+    ((EphyrDRIScreenPrivPtr)((screen)->devPrivates[ephyrDRIScreenIndex].ptr))
 
-void
-ephyrDRIExtensionInit(void)
+
+Bool
+ephyrDRIExtensionInit (ScreenPtr a_screen)
 {
-    ExtensionEntry* extEntry;
+    Bool is_ok=FALSE ;
+    ExtensionEntry* extEntry=NULL;
+    EphyrDRIScreenPrivPtr screen_priv=NULL ;
+
     EPHYR_LOG ("enter\n") ;
 
 #ifdef XF86DRI_EVENTS
-    EventType = CreateNewResourceType(XF86DRIFreeEvents);
+    EventType = CreateNewResourceType (XF86DRIFreeEvents);
 #endif
 
     if ((extEntry = AddExtension(XF86DRINAME,
@@ -100,10 +146,411 @@ ephyrDRIExtensionInit(void)
 				 StandardMinorOpcode))) {
 	DRIReqCode = (unsigned char)extEntry->base;
 	DRIErrorBase = extEntry->errorBase;
+    } else {
+        EPHYR_LOG_ERROR ("failed to register DRI extension\n") ;
+        goto out ;
+    }
+    if (ephyrDRIGeneration != serverGeneration) {
+        ephyrDRIScreenIndex = AllocateScreenPrivateIndex () ;
+        if (ephyrDRIScreenIndex < 0) {
+            EPHYR_LOG_ERROR ("failed to allocate screen priv index\n") ;
+            goto out ;
+        }
+    }
+    screen_priv = xcalloc (1, sizeof (EphyrDRIScreenPrivRec)) ;
+    if (!screen_priv) {
+        EPHYR_LOG_ERROR ("failed to allocate screen_priv\n") ;
+        goto out ;
+    }
+    a_screen->devPrivates[ephyrDRIScreenIndex].ptr = screen_priv;
+
+    if (!ephyrDRIScreenInit (a_screen)) {
+        EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ;
+        goto out ;
+    }
+    EphyrMirrorHostVisuals () ;
+    if (ephyrDRIGeneration != serverGeneration) {
+        ephyrDRIGeneration = serverGeneration ;
+    }
+    is_ok=TRUE ;
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+static Bool
+ephyrDRIScreenInit (ScreenPtr a_screen)
+{
+    Bool is_ok=FALSE ;
+    EphyrDRIScreenPrivPtr screen_priv=NULL ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_screen, FALSE) ;
+
+    screen_priv=GET_EPHYR_DRI_SCREEN_PRIV (a_screen) ;
+    EPHYR_RETURN_VAL_IF_FAIL (screen_priv, FALSE) ;
+
+    if (ephyrDRIGeneration != serverGeneration) {
+        ephyrDRIWindowIndex = AllocateWindowPrivateIndex () ;
+        if (ephyrDRIWindowIndex < 0) {
+            EPHYR_LOG_ERROR ("failed to allocate window priv index\n") ;
+            goto out ;
+        }
+    }
+    if (!AllocateWindowPrivate (a_screen, ephyrDRIWindowIndex, 0)) {
+        EPHYR_LOG_ERROR ("failed to allocate window privates\n") ;
+        goto out ;
+    }
+    screen_priv->CreateWindow = a_screen->CreateWindow ;
+    screen_priv->DestroyWindow = a_screen->DestroyWindow ;
+    screen_priv->MoveWindow = a_screen->MoveWindow ;
+    screen_priv->PositionWindow = a_screen->PositionWindow ;
+
+    a_screen->CreateWindow = ephyrDRICreateWindow ;
+    a_screen->DestroyWindow = ephyrDRIDestroyWindow ;
+    a_screen->MoveWindow = ephyrDRIMoveWindow ;
+    a_screen->PositionWindow = ephyrDRIPositionWindow ;
+
+    is_ok = TRUE ;
+out:
+    return is_ok ;
+}
+
+static Bool
+ephyrDRICreateWindow (WindowPtr a_win)
+{
+    Bool is_ok=FALSE ;
+    ScreenPtr screen=NULL ;
+    EphyrDRIScreenPrivPtr screen_priv =NULL;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+    screen = a_win->drawable.pScreen ;
+    EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+    EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+                              && screen_priv->CreateWindow,
+                              FALSE) ;
+
+    EPHYR_LOG ("enter. win:%#x\n",
+               (unsigned int)a_win) ;
+
+    screen->CreateWindow = screen_priv->CreateWindow ;
+    is_ok = (*screen->CreateWindow) (a_win) ;
+    screen->CreateWindow = ephyrDRICreateWindow ;
+
+    if (is_ok) {
+        a_win->devPrivates[ephyrDRIWindowIndex].ptr = NULL ;
+    }
+    return is_ok ;
+}
+
+static Bool
+ephyrDRIDestroyWindow (WindowPtr a_win)
+{
+    Bool is_ok=FALSE ;
+    ScreenPtr screen=NULL ;
+    EphyrDRIScreenPrivPtr screen_priv =NULL;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+    screen = a_win->drawable.pScreen ;
+    EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+    EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+                              && screen_priv->DestroyWindow,
+                              FALSE) ;
+
+    screen->DestroyWindow = screen_priv->DestroyWindow ;
+    is_ok = (*screen->DestroyWindow) (a_win) ;
+    screen->DestroyWindow = ephyrDRIDestroyWindow ;
+
+    if (is_ok) {
+        EphyrDRIWindowPrivPtr win_priv=GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+        if (win_priv) {
+            destroyHostPeerWindow (a_win) ;
+            xfree (win_priv) ;
+            a_win->devPrivates[ephyrDRIWindowIndex].ptr = NULL ;
+            EPHYR_LOG ("destroyed the remote peer window\n") ;
+        }
+    }
+    return is_ok ;
+}
+
+static void
+ephyrDRIMoveWindow (WindowPtr a_win,
+                    int a_x, int a_y,
+                    WindowPtr a_siblings,
+                    VTKind a_kind)
+{
+    Bool is_ok=FALSE ;
+    ScreenPtr screen=NULL ;
+    EphyrDRIScreenPrivPtr screen_priv =NULL;
+    EphyrDRIWindowPrivPtr win_priv=NULL ;
+    EphyrWindowPair *pair=NULL ;
+    EphyrBox geo;
+    int x=0,y=0;/*coords relative to parent window*/
+
+    EPHYR_RETURN_IF_FAIL (a_win) ;
+
+    EPHYR_LOG ("enter\n") ;
+    screen = a_win->drawable.pScreen ;
+    EPHYR_RETURN_IF_FAIL (screen) ;
+    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+    EPHYR_RETURN_IF_FAIL (screen_priv
+                          && screen_priv->MoveWindow) ;
+
+    screen->MoveWindow = screen_priv->MoveWindow ;
+    (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ;
+    screen->MoveWindow = ephyrDRIMoveWindow ;
+
+    EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
+    if (!a_win->parent) {
+        EPHYR_LOG ("cannot move root window\n") ;
+        is_ok = TRUE ;
+        goto out ;
+    }
+    win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+    if (!win_priv) {
+        EPHYR_LOG ("not a DRI peered window\n") ;
+        is_ok = TRUE ;
+        goto out ;
+    }
+    if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+        EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+        goto out ;
+    }
+    /*compute position relative to parent window*/
+    x = a_win->drawable.x - a_win->parent->drawable.x ;
+    y = a_win->drawable.y - a_win->parent->drawable.y ;
+    /*set the geometry to pass to hostx_set_window_geometry*/
+    memset (&geo, 0, sizeof (geo)) ;
+    geo.x = x ;
+    geo.y = y ;
+    geo.width = a_win->drawable.width ;
+    geo.height = a_win->drawable.height ;
+    hostx_set_window_geometry (pair->remote, &geo) ;
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+    /*do cleanup here*/
+}
+
+static Bool
+ephyrDRIPositionWindow (WindowPtr a_win,
+                        int a_x, int a_y)
+{
+    Bool is_ok=FALSE ;
+    ScreenPtr screen=NULL ;
+    EphyrDRIScreenPrivPtr screen_priv =NULL;
+    EphyrDRIWindowPrivPtr win_priv=NULL ;
+    EphyrWindowPair *pair=NULL ;
+    EphyrBox geo;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+    screen = a_win->drawable.pScreen ;
+    EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+    EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+                              && screen_priv->PositionWindow,
+                              FALSE) ;
+
+    screen->PositionWindow = screen_priv->PositionWindow ;
+    (*screen->PositionWindow) (a_win, a_x, a_y) ;
+    screen->PositionWindow = ephyrDRIPositionWindow ;
+
+    EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
+    win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+    if (!win_priv) {
+        EPHYR_LOG ("not a DRI peered window\n") ;
+        is_ok = TRUE ;
+        goto out ;
+    }
+    if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+        EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+        goto out ;
+    }
+    /*set the geometry to pass to hostx_set_window_geometry*/
+    memset (&geo, 0, sizeof (geo)) ;
+    geo.x = a_x ;
+    geo.y = a_y ;
+    geo.width = a_win->drawable.width ;
+    geo.height = a_win->drawable.height ;
+    hostx_set_window_geometry (pair->remote, &geo) ;
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+    /*do cleanup here*/
+    return is_ok ;
+}
+
+/**
+ * Duplicates a visual of a_screen
+ * In screen a_screen, for depth a_depth, find a visual which
+ * bitsPerRGBValue and colormap size equal
+ * a_bits_per_rgb_values and a_colormap_entries.
+ * The ID of that duplicated visual is set to a_new_id.
+ * That duplicated visual is then added to the list of visuals
+ * of the screen.
+ */
+static Bool
+EphyrDuplicateVisual (unsigned int a_screen,
+                      short a_depth,
+                      short a_class,
+                      short a_bits_per_rgb_values,
+                      short a_colormap_entries,
+                      unsigned int a_red_mask,
+                      unsigned int a_green_mask,
+                      unsigned int a_blue_mask,
+                      unsigned int a_new_id)
+{
+    Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ;
+    ScreenPtr screen=NULL ;
+    VisualRec new_visual, *new_visuals=NULL ;
+    int i=0 ;
+
+    EPHYR_LOG ("enter\n") ; 
+    if (a_screen > screenInfo.numScreens) {
+        EPHYR_LOG_ERROR ("bad screen number\n") ;
+        goto out;
+    }
+    memset (&new_visual, 0, sizeof (VisualRec)) ;
+
+    /*get the screen pointed to by a_screen*/
+    screen = screenInfo.screens[a_screen] ;
+    EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+
+    /*
+     * In that screen, first look for an existing visual that has the
+     * same characteristics as those passed in parameter
+     * to this function and copy it.
+     */
+    for (i=0; i < screen->numVisuals; i++) {
+        if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
+            screen->visuals[i].ColormapEntries == a_colormap_entries ) {
+            /*copy the visual found*/
+            memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
+            new_visual.vid = a_new_id ;
+            new_visual.class = a_class ;
+            new_visual.redMask = a_red_mask ;
+            new_visual.greenMask = a_green_mask ;
+            new_visual.blueMask = a_blue_mask ;
+            found_visual = TRUE ;
+            EPHYR_LOG ("found a visual that matches visual id: %d\n",
+                       a_new_id) ;
+            break;
+        }
+    }
+    if (!found_visual) {
+        EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ;
+        goto out ;
+    }
+    /*
+     * be prepare to extend screen->visuals to add new_visual to it
+     */
+    new_visuals = xcalloc (screen->numVisuals+1, sizeof (VisualRec)) ;
+    memmove (new_visuals,
+             screen->visuals,
+             screen->numVisuals*sizeof (VisualRec)) ;
+    memmove (&new_visuals[screen->numVisuals],
+             &new_visual,
+             sizeof (VisualRec)) ;
+    /*
+     * Now, in that same screen, update the screen->allowedDepths member.
+     * In that array, each element represents the visuals applicable to
+     * a given depth. So we need to add an entry matching the new visual
+     * that we are going to add to screen->visuals
+     */
+    for (i=0; i<screen->numDepths; i++) {
+        VisualID *vids=NULL;
+        DepthPtr cur_depth=NULL ;
+        /*find the entry matching a_depth*/
+        if (screen->allowedDepths[i].depth != a_depth)
+            continue ;
+        cur_depth = &screen->allowedDepths[i];
+        /*
+         * extend the list of visual IDs in that entry,
+         * so to add a_new_id in there.
+         */
+        vids = xrealloc (cur_depth->vids,
+                         (cur_depth->numVids+1)*sizeof (VisualID));
+        if (!vids) {
+            EPHYR_LOG_ERROR ("failed to realloc numids\n") ;
+            goto out ;
+        }
+        vids[cur_depth->numVids] = a_new_id ;
+        /*
+         * Okay now commit our change.
+         * Do really update screen->allowedDepths[i]
+         */
+        cur_depth->numVids++ ;
+        cur_depth->vids = vids ;
+        found_depth=TRUE;
+    }
+    if (!found_depth) {
+        EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n",
+                         a_screen) ;
+        goto out ;
+    }
+    /*
+     * Commit our change to screen->visuals
+     */
+    xfree (screen->visuals) ;
+    screen->visuals = new_visuals ;
+    screen->numVisuals++ ;
+    new_visuals = NULL ;
+
+    is_ok = TRUE ;
+out:
+    if (new_visuals) {
+        xfree (new_visuals) ;
+        new_visuals = NULL ;
     }
+    EPHYR_LOG ("leave\n") ; 
+    return is_ok ;
+}
+
+/**
+ * Duplicates the visuals of the host X server.
+ * This is necessary to have visuals that have the same
+ * ID as those of the host X. It is important to have that for
+ * GLX.
+ */
+static Bool
+EphyrMirrorHostVisuals (void)
+{
+    Bool is_ok=FALSE;
+    EphyrHostVisualInfo  *visuals=NULL;
+    int nb_visuals=0, i=0;
+
+    EPHYR_LOG ("enter\n") ;
+    if (!hostx_get_visuals_info (&visuals, &nb_visuals)) {
+        EPHYR_LOG_ERROR ("failed to get host visuals\n") ;
+        goto out ;
+    }
+    for (i=0; i<nb_visuals; i++) {
+        if (!EphyrDuplicateVisual (visuals[i].screen,
+                                   visuals[i].depth,
+                                   visuals[i].class,
+                                   visuals[i].bits_per_rgb,
+                                   visuals[i].colormap_size,
+                                   visuals[i].red_mask,
+                                   visuals[i].green_mask,
+                                   visuals[i].blue_mask,
+                                   visuals[i].visualid)) {
+            EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
+                             (int)visuals[i].visualid) ;
+        }
+    }
+
+    is_ok = TRUE ;
+out:
     EPHYR_LOG ("leave\n") ;
+    return is_ok;
 }
 
+
 /*ARGSUSED*/
 static void
 XF86DRIResetProc (
@@ -311,7 +758,8 @@ ProcXF86DRICreateContext (register ClientPtr client)
     xXF86DRICreateContextReply	rep;
     ScreenPtr pScreen;
     VisualPtr visual;
-    int i;
+    int i=0;
+    unsigned long context_id=0;
 
     EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRICreateContextReq);
@@ -337,14 +785,13 @@ ProcXF86DRICreateContext (register ClientPtr client)
 	return BadValue;
     }
 
-    /*
-    if (!DRICreateContext( pScreen,
-			   visual,
-			   stuff->context,
-			   (drm_context_t *)&rep.hHWContext)) {
-	return BadValue;
+    context_id = stuff->context ;
+    if (!ephyrDRICreateContext (stuff->screen,
+                                stuff->visual,
+                                &context_id,
+                                (drm_context_t *)&rep.hHWContext)) {
+        return BadValue;
     }
-    */
 
     WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
     EPHYR_LOG ("leave\n") ;
@@ -363,23 +810,146 @@ ProcXF86DRIDestroyContext (register ClientPtr client)
         return BadValue;
     }
 
-    /*
-       if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
-       stuff->context)) {
+   if (!ephyrDRIDestroyContext (stuff->screen, stuff->context)) {
        return BadValue;
-       }
-   */
+   }
 
     EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
+static Bool
+getWindowVisual (const WindowPtr a_win,
+                 VisualPtr *a_visual)
+{
+    int i=0, visual_id=0 ;
+    EPHYR_RETURN_VAL_IF_FAIL (a_win
+                              && a_win->drawable.pScreen
+                              && a_win->drawable.pScreen->visuals,
+                              FALSE) ;
+
+    visual_id = wVisual (a_win) ;
+    for (i=0; i < a_win->drawable.pScreen->numVisuals; i++) {
+        if (a_win->drawable.pScreen->visuals[i].vid == visual_id) {
+            *a_visual = &a_win->drawable.pScreen->visuals[i] ;
+            return TRUE ;
+        }
+    }
+    return FALSE ;
+}
+
+
+#define NUM_WINDOW_PAIRS 256
+static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS] ;
+
+static Bool
+appendWindowPairToList (WindowPtr a_local,
+                        int a_remote)
+{
+    int i=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_local, FALSE) ;
+
+    EPHYR_LOG ("(local,remote):(%#x, %d)\n", (unsigned int)a_local, a_remote) ;
+
+    for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+        if (window_pairs[i].local == NULL) {
+            window_pairs[i].local = a_local ;
+            window_pairs[i].remote = a_remote ;
+            return TRUE ;
+        }
+    }
+    return FALSE ;
+}
+
+static Bool
+findWindowPairFromLocal (WindowPtr a_local,
+                         EphyrWindowPair **a_pair)
+{
+    int i=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_pair && a_local, FALSE) ;
+
+    for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+        if (window_pairs[i].local == a_local) {
+            *a_pair = &window_pairs[i] ;
+            EPHYR_LOG ("found (%#x, %d)\n",
+                       (unsigned int)(*a_pair)->local,
+                       (*a_pair)->remote) ;
+            return TRUE ;
+        }
+    }
+    return FALSE ;
+}
+
+static Bool
+createHostPeerWindow (const WindowPtr a_win,
+                      int *a_peer_win)
+{
+    Bool is_ok=FALSE ;
+    VisualPtr visual=NULL;
+    EphyrBox geo ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_win && a_peer_win, FALSE) ;
+
+    EPHYR_LOG ("enter. a_win '%#x'\n", (unsigned int)a_win) ;
+    if (!getWindowVisual (a_win, &visual)) {
+        EPHYR_LOG_ERROR ("failed to get window visual\n") ;
+        goto out ;
+    }
+    if (!visual) {
+        EPHYR_LOG_ERROR ("failed to create visual\n") ;
+        goto out ;
+    }
+    memset (&geo, 0, sizeof (geo)) ;
+    geo.x = a_win->drawable.x ;
+    geo.y = a_win->drawable.y ;
+    geo.width = a_win->drawable.width ;
+    geo.height = a_win->drawable.height ;
+    if (!hostx_create_window (&geo, visual->vid, a_peer_win)) {
+        EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
+        goto out ;
+    }
+    if (!appendWindowPairToList (a_win, *a_peer_win)) {
+        EPHYR_LOG_ERROR ("failed to append window to pair list\n") ;
+        goto out ;
+    }
+    is_ok = TRUE ;
+out:
+    EPHYR_LOG ("leave:remote win%d\n", *a_peer_win) ;
+    return is_ok ;
+}
+
+static Bool
+destroyHostPeerWindow (const WindowPtr a_win)
+{
+    Bool is_ok = FALSE ;
+    EphyrWindowPair *pair=NULL ;
+    EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+        EPHYR_LOG_ERROR ("failed to find peer to local window\n") ;
+        goto out;
+    }
+    hostx_destroy_window (pair->remote) ;
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok;
+}
+
 static int
 ProcXF86DRICreateDrawable (ClientPtr client)
 {
     xXF86DRICreateDrawableReply	rep;
-    DrawablePtr pDrawable;
-    int rc;
+    DrawablePtr drawable=NULL;
+    WindowPtr window=NULL ;
+    EphyrWindowPair *pair=NULL ;
+    EphyrDRIWindowPrivPtr win_priv=NULL;
+    int rc=0, remote_win=0;
 
     EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRICreateDrawableReq);
@@ -393,21 +963,44 @@ ProcXF86DRICreateDrawable (ClientPtr client)
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
 
-    rc = dixLookupDrawable (&pDrawable, stuff->drawable, client, 0,
+    rc = dixLookupDrawable (&drawable, stuff->drawable, client, 0,
                             DixReadAccess);
     if (rc != Success)
         return rc;
+    if (drawable->type != DRAWABLE_WINDOW) {
+        EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
+        return BadImplementation ;
+    }
+    EPHYR_LOG ("lookedup drawable %#x\n", (unsigned int)drawable) ;
+    window = (WindowPtr)drawable;
+    if (findWindowPairFromLocal (window, &pair) && pair) {
+        remote_win = pair->remote ;
+        EPHYR_LOG ("found window '%#x' paire with remote '%d'\n",
+                   (unsigned int)window, remote_win) ;
+    } else if (!createHostPeerWindow (window, &remote_win)) {
+        EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
+        return BadAlloc ;
+    }
 
-    /*TODO: this cannot work. We must properly
-     * do the mapping between the xephyr drawable and
-     * the host drawable
-     */
     if (!ephyrDRICreateDrawable (stuff->screen,
-                0/*should be host drawableID*/,
-                (drm_drawable_t *)&rep.hHWDrawable)) {
+                                 remote_win,
+                                 (drm_drawable_t *)&rep.hHWDrawable)) {
+        EPHYR_LOG_ERROR ("failed to create dri drawable\n") ;
         return BadValue;
     }
 
+    win_priv = GET_EPHYR_DRI_WINDOW_PRIV (window) ;
+    if (!win_priv) {
+        win_priv = xcalloc (1, sizeof (EphyrDRIWindowPrivRec)) ;
+        if (!win_priv) {
+            EPHYR_LOG_ERROR ("failed to allocate window private\n") ;
+            return BadAlloc ;
+        }
+        window->devPrivates[ephyrDRIWindowIndex].ptr = win_priv ;
+        EPHYR_LOG ("paired window '%#x' with remote '%d'\n",
+                   (unsigned int)window, remote_win) ;
+    }
+
     WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
     EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
@@ -417,9 +1010,11 @@ static int
 ProcXF86DRIDestroyDrawable (register ClientPtr client)
 {
     REQUEST(xXF86DRIDestroyDrawableReq);
-    DrawablePtr pDrawable;
+    DrawablePtr drawable=NULL;
+    WindowPtr window=NULL;
+    EphyrWindowPair *pair=NULL;
     REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
-    int rc;
+    int rc=0;
 
     EPHYR_LOG ("enter\n") ;
     if (stuff->screen >= screenInfo.numScreens) {
@@ -427,18 +1022,30 @@ ProcXF86DRIDestroyDrawable (register ClientPtr client)
         return BadValue;
     }
 
-    rc = dixLookupDrawable(&pDrawable,
+    rc = dixLookupDrawable(&drawable,
                            stuff->drawable,
                            client,
                            0,
                            DixReadAccess);
     if (rc != Success)
         return rc;
-
+    if (drawable->type != DRAWABLE_WINDOW) {
+        EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
+        return BadImplementation ;
+    }
+    window = (WindowPtr)drawable;
+    if (!findWindowPairFromLocal (window, &pair) && pair) {
+        EPHYR_LOG_ERROR ("failed to find pair window\n") ;
+        return BadImplementation;
+    }
     if (!ephyrDRIDestroyDrawable(stuff->screen,
-                                 0/*should be drawable in host x*/)) {
-        return BadValue;
+                                 pair->remote/*drawable in host x*/)) {
+        EPHYR_LOG_ERROR ("failed to destroy dri drawable\n") ;
+        return BadImplementation;
     }
+    pair->local=NULL ;
+    pair->remote=0;
+
     EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
@@ -448,6 +1055,8 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
 {
     xXF86DRIGetDrawableInfoReply rep;
     DrawablePtr drawable;
+    WindowPtr window=NULL;
+    EphyrWindowPair *pair=NULL;
     int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0;
     drm_clip_rect_t *pClipRects=NULL, *pClippedRects=NULL;
     drm_clip_rect_t *pBackClipRects=NULL;
@@ -465,17 +1074,25 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
 
-    /*TODO: this cannot work.
-     * We must properly do the mapping
-     * between xephyr drawable and the host drawable
-     */
     rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
                            DixReadAccess);
-    if (rc != Success)
+    if (rc != Success || !drawable) {
+        EPHYR_LOG_ERROR ("could not get drawable\n") ;
         return rc;
+    }
 
+    if (drawable->type != DRAWABLE_WINDOW) {
+        EPHYR_LOG_ERROR ("non windows type drawables are not yes supported\n") ;
+        return BadImplementation ;
+    }
+    window = (WindowPtr)drawable ;
+    memset (&pair, 0, sizeof (pair)) ;
+    if (!findWindowPairFromLocal (window, &pair) || !pair) {
+        EPHYR_LOG_ERROR ("failed to find remote peer drawable\n") ;
+        return BadMatch ;
+    }
     if (!ephyrDRIGetDrawableInfo (stuff->screen,
-                                  drawable/*should be the drawable in hostx*/,
+                                  pair->remote/*the drawable in hostx*/,
                                   (unsigned int*)&rep.drawableTableIndex,
                                   (unsigned int*)&rep.drawableTableStamp,
                                   (int*)&X,
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index eea426a..521f3a6 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -64,7 +64,9 @@ static Bool DoSimpleClip (BoxPtr a_dst_drw,
 
 static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
 
+/*
 static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
+*/
 
 static EphyrXVPriv* ephyrXVPrivNew (void) ;
 static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 51fda47..7636e25 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -1132,3 +1132,86 @@ hostx_get_resource_id_peer (int a_local_resource_id,
     return FALSE ;
 }
 
+int
+hostx_create_window (EphyrBox *a_geometry,
+                     int a_visual_id,
+                     int *a_host_peer /*out parameter*/)
+{
+    Bool is_ok=FALSE ;
+    Display *dpy=hostx_get_display () ;
+    XVisualInfo *visual_info=NULL, visual_info_templ;
+    int visual_mask=VisualIDMask ;
+    Window win=None ;
+    int nb_visuals=0, winmask=0;
+    XSetWindowAttributes attrs;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy && a_geometry, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+     /*get visual*/
+    memset (&visual_info, 0, sizeof (visual_info)) ;
+    visual_info_templ.visualid = a_visual_id ;
+    visual_info = XGetVisualInfo (dpy, visual_mask,
+                                  &visual_info_templ,
+                                  &nb_visuals) ;
+    if (!visual_info) {
+        EPHYR_LOG_ERROR ("argh, could not find a remote visual with id:%d\n",
+                         a_visual_id) ;
+        goto out ;
+    }
+    memset (&attrs, 0, sizeof (attrs)) ;
+    attrs.colormap = XCreateColormap (dpy,
+                                      RootWindow (dpy,
+                                                  visual_info->screen),
+                                      visual_info->visual,
+                                      AllocNone) ;
+    winmask = CWColormap;
+
+    win = XCreateWindow (dpy, hostx_get_window (),
+                         a_geometry->x, a_geometry->y,
+                         a_geometry->width, a_geometry->height, 0,
+                         visual_info->depth, InputOutput,
+                         visual_info->visual, winmask, &attrs) ;
+    if (win == None) {
+        EPHYR_LOG_ERROR ("failed to create peer window\n") ;
+        goto out ;
+    }
+    XFlush (dpy) ;
+    XMapWindow (dpy, win) ;
+    *a_host_peer = win ;
+    is_ok = TRUE ;
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+int
+hostx_destroy_window (int a_win)
+{
+    Display *dpy=hostx_get_display () ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+    XDestroyWindow (dpy, a_win) ;
+    XFlush (dpy) ;
+    return TRUE ;
+}
+
+int
+hostx_set_window_geometry (int a_win, EphyrBox *a_geo)
+{
+    Display *dpy=hostx_get_display ();
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy && a_geo, FALSE) ;
+
+    EPHYR_LOG ("enter. x,y,w,h:(%d,%d,%d,%d)\n",
+               a_geo->x, a_geo->y,
+               a_geo->width, a_geo->height) ;
+
+    XMoveWindow (dpy, a_win, a_geo->x, a_geo->y) ;
+    XResizeWindow (dpy, a_win, a_geo->width, a_geo->height) ;
+    XFlush (dpy) ;
+    EPHYR_LOG ("leave\n") ;
+    return TRUE;
+}
+
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 51a5f68..3cd27ff 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -110,6 +110,10 @@ typedef struct {
     int visualid ;
 } EphyrHostWindowAttributes;
 
+typedef struct {
+    int x,y,width,height;
+} EphyrBox;
+
 int
 hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
 
@@ -214,4 +218,15 @@ int
 hostx_get_resource_id_peer (int a_local_resource_id,
                             int *a_remote_resource_id) ;
 
+int hostx_create_window (EphyrBox *a_geometry,
+                         int a_visual_id,
+                         int *a_host_win /*out parameter*/) ;
+
+int hostx_destroy_window (int a_win) ;
+
+int hostx_set_window_geometry (int a_win, EphyrBox *a_geo) ;
+
+int hostx_lookup_peer_window (void *a_local_window,
+                              int *a_host_peer /*out parameter*/) ;
+
 #endif
commit 6d1e44d3d53b451d466d43197be589d0ecc4b9f6
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Tue Sep 4 18:28:16 2007 +0200

    Xephyr: fix a host X hang.
    
    	* hw/kdrive/ephyr/ephyrdri.c:
    	  (ephyrDRIGetDrawableInfo): quickly hook
    	  this into getting the drawable info from the host
    	  X server. For the time being, this only gets the drawable info
    	  of the Xephyr main window in the host. It should really get
    	  the info of a the peer drawable in the host X. So there should be a
    	  peer drawable to begin with.
    	* hw/kdrive/ephyr/ephyrdriext.c:
    	  (ProcXF86DRIGetDrawableInfo): some cleanups. Properly get the
              the drawable info otherwise there is a host X hang.
    	* hw/kdrive/ephyr/ephyrhostglx.c: do not
    	  (ephyrHostGLXQueryVersion): do not use C bindings of the glx protocol
    	   calls. Some of those actually access DRI context directly, resulting
    	   in the context having three clients. Instead all XF86DRI proto
    	   fowarding request should be coded by hand and only forward the
    	   protocol requests

diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
index 95ace7c..3f470f8 100644
--- a/hw/kdrive/ephyr/ephyrdri.c
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -216,6 +216,7 @@ ephyrDRIGetDrawableInfo (int a_screen,
                          drm_clip_rect_t **a_back_clip_rects)
 {
     Bool is_ok=FALSE;
+    Display *dpy=hostx_get_display ()  ;
     DrawablePtr drawable = a_drawable ;
     EphyrHostWindowAttributes attrs ;
 
@@ -229,20 +230,29 @@ ephyrDRIGetDrawableInfo (int a_screen,
         EPHYR_LOG_ERROR ("failed to query host window attributes\n") ;
         goto out;
     }
-    *a_x = drawable->x + attrs.x;
-    *a_y = drawable->y + attrs.y;
-    *a_w = drawable->width + attrs.width ;
-    *a_h = drawable->height + attrs.height ;
-    *a_num_clip_rects = 0 ;
-    *a_clip_rects = NULL ;
-    *a_back_x = 0;
-    *a_back_y = 0 ;
-    *a_num_back_clip_rects = 0 ;
-    *a_back_clip_rects = NULL ;
+    if (!XF86DRIGetDrawableInfo (dpy, a_screen, hostx_get_window (),
+                                 a_index, a_stamp,
+                                 a_x, a_y,
+                                 a_w, a_h,
+                                 a_num_clip_rects, a_clip_rects,
+                                 a_back_x, a_back_y,
+                                 a_num_back_clip_rects,
+                                 a_back_clip_rects)) {
+        EPHYR_LOG_ERROR ("XF86DRIGetDrawableInfo ()\n") ;
+        goto out ;
+    }
+    EPHYR_LOG ("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h) ;
+    *a_x += drawable->x ;
+    *a_y += drawable->y ;
+    *a_back_x = *a_x ;
+    *a_back_y = *a_y ;
+    *a_w = drawable->width;
+    *a_h = drawable->height;
 
     is_ok = TRUE ;
 out:
-    EPHYR_LOG ("leave\n") ;
+    EPHYR_LOG ("leave. index:%d, stamp:%d, x,y:(%d,%d), w,y:(%d,%d)\n",
+               *a_index, *a_stamp, *a_x, *a_y, *a_w, *a_h) ;
     return is_ok ;
 }
 
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index d54da21..443fe9d 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -446,13 +446,14 @@ ProcXF86DRIDestroyDrawable (register ClientPtr client)
 static int
 ProcXF86DRIGetDrawableInfo (register ClientPtr client)
 {
-    xXF86DRIGetDrawableInfoReply	rep;
+    xXF86DRIGetDrawableInfoReply rep;
     DrawablePtr drawable;
-    int X, Y, W, H, backX, backY, rc;
-    drm_clip_rect_t * pClipRects, *pClippedRects;
-    drm_clip_rect_t * pBackClipRects;
+    int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0;
+    drm_clip_rect_t *pClipRects=NULL, *pClippedRects=NULL;
+    drm_clip_rect_t *pBackClipRects=NULL;
 
     EPHYR_LOG ("enter\n") ;
+    memset (&rep, 0, sizeof (rep)) ;
     REQUEST(xXF86DRIGetDrawableInfoReq);
     REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
     if (stuff->screen >= screenInfo.numScreens) {
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
index 071a581..21a109e 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -89,10 +89,14 @@ ephyrHostGLXQueryVersion (int *a_major, int *a_minor)
     EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ;
     EPHYR_LOG ("enter\n") ;
 
+    *a_major = 1 ;
+    *a_minor = 2 ;
+    /*
     if (!glXQueryVersion (dpy, a_major, a_minor)) {
         EPHYR_LOG_ERROR ("glxQueryVersion() failed\n") ;
         goto out ;
     }
+    */
 
     is_ok = TRUE ;
 out:
commit a39b57d2f784f14e3198c8506f5eb865bacc2440
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Fri Aug 31 16:53:18 2007 +0200

    Xephyr: add more logging to GLX forwarding
    
    	* hw/kdrive/ephyr/ephyrhostglx.c: added more logging.

diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
index 2bebfdf..071a581 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -143,6 +143,8 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
             break ;
         case EPHYR_HOST_GLX_GetString:
             get_string_op = X_GLsop_GetString;
+            EPHYR_LOG ("Going to glXGetString. strname:%#x, ctxttag:%d\n",
+                       a_string_name, a_screen_number) ;
             break ;
         default:
             EPHYR_LOG_ERROR ("unknown EphyrHostGLXGetStringOp:%d\n", a_op) ;
@@ -172,7 +174,7 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
 
     length = reply.length * 4;
     numbytes = reply.size;
-    EPHYR_LOG ("got a string of size:%d\n", numbytes) ;
+    EPHYR_LOG ("going to get a string of size:%d\n", numbytes) ;
 
     *a_string = (char *) Xmalloc (numbytes +1);
     if (!a_string) {
@@ -191,7 +193,8 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
     _XEatData (dpy, length) ;
     UnlockDisplay (dpy);
     SyncHandle ();
-    EPHYR_LOG ("string:'%s'\n", *a_string) ;
+    EPHYR_LOG ("strname:%#x, strvalue:'%s', strlen:%d\n",
+               a_string_name, *a_string, numbytes) ;
 
     is_ok = TRUE ;
 out:
@@ -531,6 +534,7 @@ ephyrHostGLXMakeCurrent (int a_drawable,
     UnlockDisplay (dpy);
     SyncHandle ();
     *a_ctxt_tag = reply.contextTag ;
+    EPHYR_LOG ("context tag:%d\n", *a_ctxt_tag) ;
     is_ok = TRUE ;
 
 out:
commit 9e192d2118246ad715e23cf5626a038274eb1eaa
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Fri Aug 31 14:43:39 2007 +0200

    Xephyr: better error handling in GLX forwarding
    
    	* hw/kdrive/ephyr/ephyrglxext.c:
    	  fixed various logging functions
    	  (ephyrGLXGetStringReal): make sure all the string is sent to clients
    	  including the ending zero.
    	* hw/kdrive/ephyr/ephyrhostglx.c:
    	  (ephyrHostGLXGetStringFromServer): better error handling.
    	  (ephyrHostGLXSendClientInfo): ditto.
    	  (ephyrHostGLXMakeCurrent): ditto

diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
index fbac6aa..27b2a2d 100644
--- a/hw/kdrive/ephyr/ephyrglxext.c
+++ b/hw/kdrive/ephyr/ephyrglxext.c
@@ -368,7 +368,7 @@ ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
         EPHYR_LOG_ERROR ("failed to query string from host\n") ;
         goto out ;
     }
-    EPHYR_LOG ("string: %s", server_string) ;
+    EPHYR_LOG ("string: %s\n", server_string) ;
     length= strlen (server_string) + 1;
     reply.type = X_Reply ;
     reply.sequenceNumber = client->sequence ;
@@ -577,8 +577,8 @@ ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
         goto out ;
     }
     if (string) {
-        length = strlen (string) ;
-        EPHYR_LOG ("got string: string:%s\n", string) ;
+        length = strlen (string) + 1;
+        EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ;
     } else {
         EPHYR_LOG ("got string: string (null)\n") ;
     }
@@ -593,7 +593,7 @@ ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
 
     res = Success ;
 out:
-    EPHYR_LOG ("enter\n") ;
+    EPHYR_LOG ("leave\n") ;
     return res ;
 }
 
@@ -619,6 +619,8 @@ ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
     GLint answer_buf_room[200];
     GLint *buf=NULL ;
 
+    EPHYR_LOG ("enter\n") ;
+
     a_pc += __GLX_SINGLE_HDR_SIZE;
 
     int_name = *(GLenum*) (a_pc+0) ;
@@ -638,7 +640,9 @@ ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
     }
     __glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ;
     res = Success ;
+
 out:
+    EPHYR_LOG ("leave\n") ;
     return res ;
 }
 
@@ -665,6 +669,8 @@ ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
 
     EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ;
 
+    EPHYR_LOG ("enter\n") ;
+
     memset (&reply, 0, sizeof (reply)) ;
     if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) {
         EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ;
@@ -676,7 +682,9 @@ ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
     reply.sequenceNumber = client->sequence;
     WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
     res = Success ;
+
 out:
+    EPHYR_LOG ("leave\n") ;
     return res ;
 }
 
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
index 843a0e5..2bebfdf 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -172,20 +172,26 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
 
     length = reply.length * 4;
     numbytes = reply.size;
+    EPHYR_LOG ("got a string of size:%d\n", numbytes) ;
 
-    *a_string = (char *) Xmalloc( numbytes );
-    if (*a_string != NULL) {
-        if (_XRead (dpy, *a_string, numbytes)) {
-            UnlockDisplay (dpy);
-            SyncHandle ();
-            EPHYR_LOG_ERROR ("read failed\n") ;
-            goto out ;
-        }
-        length -= numbytes;
+    *a_string = (char *) Xmalloc (numbytes +1);
+    if (!a_string) {
+        EPHYR_LOG_ERROR ("allocation failed\n") ;
+        goto out;
+    }
+
+    memset (*a_string, 0, numbytes+1) ;
+    if (_XRead (dpy, *a_string, numbytes)) {
+        UnlockDisplay (dpy);
+        SyncHandle ();
+        EPHYR_LOG_ERROR ("read failed\n") ;
+        goto out ;
     }
+    length -= numbytes;
     _XEatData (dpy, length) ;
     UnlockDisplay (dpy);
     SyncHandle ();
+    EPHYR_LOG ("string:'%s'\n", *a_string) ;
 
     is_ok = TRUE ;
 out:
@@ -387,11 +393,12 @@ ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
     req->numbytes = size;
     Data (dpy, a_extension_list, size);
 
+    UnlockDisplay(dpy);
+    SyncHandle();
+
     is_ok=TRUE ;
 
 out:
-    UnlockDisplay(dpy);
-    SyncHandle();
     return is_ok ;
 }
 
@@ -433,11 +440,12 @@ ephyrHostGLXCreateContext (int a_screen,
     req->shareList = a_share_list_ctxt_id;
     req->isDirect = a_direct;
 
+    UnlockDisplay (dpy);
+    SyncHandle ();
+
     is_ok = TRUE ;
 
 out:
-    UnlockDisplay (dpy);
-    SyncHandle ();
     EPHYR_LOG ("leave\n") ;
     return is_ok ;
 }
@@ -516,14 +524,16 @@ ephyrHostGLXMakeCurrent (int a_drawable,
     memset (&reply, 0, sizeof (reply)) ;
     if (!_XReply (dpy, (xReply*)&reply, 0, False)) {
         EPHYR_LOG_ERROR ("failed to get reply from host\n") ;
+        UnlockDisplay (dpy);
+        SyncHandle ();
         goto out ;
     }
+    UnlockDisplay (dpy);
+    SyncHandle ();
     *a_ctxt_tag = reply.contextTag ;
     is_ok = TRUE ;
 
 out:
-    UnlockDisplay (dpy);
-    SyncHandle ();
     EPHYR_LOG ("leave\n") ;
     return is_ok ;
 }
commit 4dd4be99df38b70d43b02d9cb19e09e0ed94462b
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Thu Aug 30 23:54:49 2007 +0200

    Xephyr: Make glxinfo work on the ATI R200 free driver.
    
    	* hw/kdrive/ephyr/ephyr.c:
    	  (EphyrDuplicateVisual): when duplicating the
    	  visual, copy the color component masks and the class
    	  from the hostX
    	  (EphyrMirrorHostVisuals): don't mix blue and green mask.
    	* hw/kdrive/ephyr/ephyrdri.c: add more logs.
    	  (ephyrDRICreateDrawable): actually implement this.
    	  for the moment it creates a DRI drawable for the hostX window,
    	  no matter what drawable this call was issued for.
    	  (ephyrDRIGetDrawableInfo): actually implemented this.
    	  for the moment the drawable info queried for its attrs is the
    	  Xephyr main main window.
    	* hw/kdrive/ephyr/ephyrdriext.c:
    	  (ProcXF86DRIGetDrawableInfo): properly hook this dispatch
    	  function to the ephyrDRIGetDrawableInfo() function.
    	* hw/kdrive/ephyr/ephyrglxext.c: add a bunch of GLX implementation hooks
    	  here. Hijack some of the xserver GLX hooks with them. Still need to
    	  properly support byteswapped clients though.
    	* hw/kdrive/ephyr/ephyrhostglx.c,h: actually implemented the protocol
    	  level forwarding functions used by the GLX entr points in
    	  ephyrglxext.c. Here as well, there are a bunch of them, but we are
    	  far from having implemented all the GLX calls.
    	* hw/kdrive/ephyr/hostx.c,h:
    	  (hostx_get_window_attributes): added this new entry point
    	  (hostx_allocate_resource_id_peer): added this to keep track of
    	   resource IDs peers: one member of the peer is in Xephyr, the other
    	   is in host X.
    	  (hostx_get_resource_id_peer): ditto.

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index df91f83..97eac51 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -1095,6 +1095,10 @@ EphyrDuplicateVisual (unsigned int a_screen,
             /*copy the visual found*/
             memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
             new_visual.vid = a_new_id ;
+            new_visual.class = a_class ;
+            new_visual.redMask = a_red_mask ;
+            new_visual.greenMask = a_green_mask ;
+            new_visual.blueMask = a_blue_mask ;
             found_visual = TRUE ;
             EPHYR_LOG ("found a visual that matches visual id: %d\n",
                        a_new_id) ;
@@ -1195,8 +1199,8 @@ EphyrMirrorHostVisuals (void)
                                    visuals[i].bits_per_rgb,
                                    visuals[i].colormap_size,
                                    visuals[i].red_mask,
-                                   visuals[i].blue_mask,
                                    visuals[i].green_mask,
+                                   visuals[i].blue_mask,
                                    visuals[i].visualid)) {
             EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
                              (int)visuals[i].visualid) ;
diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
index 54ad2c0..95ace7c 100644
--- a/hw/kdrive/ephyr/ephyrdri.c
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -40,6 +40,8 @@
 #include "ephyrdri.h"
 #define _HAVE_XALLOC_DECLS
 #include "ephyrlog.h"
+#include "dixstruct.h"
+#include "pixmapstr.h"
 
 #ifndef TRUE
 #define TRUE 1
@@ -55,9 +57,10 @@ ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable)
     Display *dpy=hostx_get_display () ;
     Bool is_ok=FALSE ;
 
+    EPHYR_RETURN_VAL_IF_FAIL (a_is_capable, FALSE) ;
     EPHYR_LOG ("enter\n") ;
     is_ok = XF86DRIQueryDirectRenderingCapable (dpy, a_screen, a_is_capable) ;
-    EPHYR_LOG ("leave\n") ;
+    EPHYR_LOG ("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok) ;
 
     return is_ok ;
 }
@@ -70,9 +73,16 @@ ephyrDRIOpenConnection (int a_screen,
     Display *dpy = hostx_get_display () ;
     Bool is_ok=FALSE ;
 
-    EPHYR_LOG ("enter\n") ;
+    EPHYR_RETURN_VAL_IF_FAIL (a_bus_id_string, FALSE) ;
+    EPHYR_LOG ("enter. screen:%d\n", a_screen) ;
     is_ok = XF86DRIOpenConnection (dpy, a_screen, a_sarea, a_bus_id_string) ;
-    EPHYR_LOG ("leave\n") ;
+    if (*a_bus_id_string) {
+        EPHYR_LOG ("leave. bus_id_string:%s, is_ok:%d\n",
+                   *a_bus_id_string, is_ok) ;
+    } else {
+        EPHYR_LOG ("leave. bus_id_string:null, is_ok:%d\n",
+                   is_ok) ;
+    }
     return is_ok ;
 }
 
@@ -84,7 +94,7 @@ ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic)
 
     EPHYR_LOG ("enter\n") ;
     is_ok = XF86DRIAuthConnection (dpy, a_screen, a_magic) ;
-    EPHYR_LOG ("leave\n") ;
+    EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
     return is_ok ;
 }
 
@@ -140,7 +150,7 @@ ephyrDRICreateContext (int a_screen,
     Bool is_ok=FALSE ;
     Visual v;
 
-    EPHYR_LOG ("enter\n") ;
+    EPHYR_LOG ("enter. screen:%d, visual:%d\n", a_screen, a_visual_id) ;
     memset (&v, 0, sizeof (v)) ;
     v.visualid = a_visual_id ;
     is_ok = XF86DRICreateContext (dpy,
@@ -170,10 +180,14 @@ ephyrDRICreateDrawable (int a_screen,
                         int a_drawable,
                         drm_drawable_t *a_hw_drawable)
 {
+    Bool is_ok=FALSE;
+    Display *dpy=hostx_get_display () ;
+    int host_win=hostx_get_window () ;
+
     EPHYR_LOG ("enter\n") ;
-    EPHYR_LOG_ERROR ("not implemented yet\n") ;
-    EPHYR_LOG ("leave\n") ;
-    return FALSE ;
+    is_ok = XF86DRICreateDrawable (dpy, a_screen, host_win, a_hw_drawable) ;
+    EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+    return is_ok ;
 }
 
 Bool
@@ -187,7 +201,7 @@ ephyrDRIDestroyDrawable (int a_screen, int a_drawable)
 
 Bool
 ephyrDRIGetDrawableInfo (int a_screen,
-                         int a_drawable,
+                         void *a_drawable,
                          unsigned int *a_index,
                          unsigned int *a_stamp,
                          int *a_x,
@@ -198,13 +212,38 @@ ephyrDRIGetDrawableInfo (int a_screen,
                          drm_clip_rect_t **a_clip_rects,
                          int *a_back_x,
                          int *a_back_y,
-                         int *num_back_clip_rects,
+                         int *a_num_back_clip_rects,
                          drm_clip_rect_t **a_back_clip_rects)
 {
+    Bool is_ok=FALSE;
+    DrawablePtr drawable = a_drawable ;
+    EphyrHostWindowAttributes attrs ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (drawable && a_x && a_y && a_w && a_h
+                              && a_num_clip_rects,
+                              FALSE) ;
+
     EPHYR_LOG ("enter\n") ;
-    EPHYR_LOG_ERROR ("not implemented yet\n") ;
+    memset (&attrs, 0, sizeof (attrs)) ;
+    if (!hostx_get_window_attributes (hostx_get_window (), &attrs)) {
+        EPHYR_LOG_ERROR ("failed to query host window attributes\n") ;
+        goto out;
+    }
+    *a_x = drawable->x + attrs.x;
+    *a_y = drawable->y + attrs.y;
+    *a_w = drawable->width + attrs.width ;
+    *a_h = drawable->height + attrs.height ;
+    *a_num_clip_rects = 0 ;
+    *a_clip_rects = NULL ;
+    *a_back_x = 0;
+    *a_back_y = 0 ;
+    *a_num_back_clip_rects = 0 ;
+    *a_back_clip_rects = NULL ;
+
+    is_ok = TRUE ;
+out:
     EPHYR_LOG ("leave\n") ;
-    return FALSE ;
+    return is_ok ;
 }
 
 Bool
diff --git a/hw/kdrive/ephyr/ephyrdri.h b/hw/kdrive/ephyr/ephyrdri.h
index d77467f..ffbbb8e 100644
--- a/hw/kdrive/ephyr/ephyrdri.h
+++ b/hw/kdrive/ephyr/ephyrdri.h
@@ -51,7 +51,7 @@ Bool ephyrDRICreateDrawable (int a_screen,
                              drm_drawable_t *a_hw_drawable) ;
 Bool ephyrDRIDestroyDrawable (int a_screen, int a_drawable) ;
 Bool ephyrDRIGetDrawableInfo (int a_screen,
-                              int a_drawable,
+                              void* /*DrawablePtr*/ a_drawable,
                               unsigned int *a_index,
                               unsigned int *a_stamp,
                               int *a_x,
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index ac68054..d54da21 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -447,11 +447,10 @@ static int
 ProcXF86DRIGetDrawableInfo (register ClientPtr client)
 {
     xXF86DRIGetDrawableInfoReply	rep;
-    DrawablePtr pDrawable;
-    int X, Y, W, H;
+    DrawablePtr drawable;
+    int X, Y, W, H, backX, backY, rc;
     drm_clip_rect_t * pClipRects, *pClippedRects;
     drm_clip_rect_t * pBackClipRects;
-    int backX, backY, rc;
 
     EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRIGetDrawableInfoReq);
@@ -469,25 +468,25 @@ ProcXF86DRIGetDrawableInfo (register ClientPtr client)
      * We must properly do the mapping
      * between xephyr drawable and the host drawable
      */
-    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
-            DixReadAccess);
+    rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
+                           DixReadAccess);
     if (rc != Success)
         return rc;
 
     if (!ephyrDRIGetDrawableInfo (stuff->screen,
-                0 /*should be the drawable in hostx*/,
-                (unsigned int*)&rep.drawableTableIndex,
-                (unsigned int*)&rep.drawableTableStamp,
-                (int*)&X,
-                (int*)&Y,
-                (int*)&W,
-                (int*)&H,
-                (int*)&rep.numClipRects,
-                &pClipRects,
-                &backX,
-                &backY,
-                (int*)&rep.numBackClipRects,
-                &pBackClipRects)) {
+                                  drawable/*should be the drawable in hostx*/,
+                                  (unsigned int*)&rep.drawableTableIndex,
+                                  (unsigned int*)&rep.drawableTableStamp,
+                                  (int*)&X,
+                                  (int*)&Y,
+                                  (int*)&W,
+                                  (int*)&H,
+                                  (int*)&rep.numClipRects,
+                                  &pClipRects,
+                                  &backX,
+                                  &backY,
+                                  (int*)&rep.numBackClipRects,
+                                  &pBackClipRects)) {
         return BadValue;
     }
 
diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
index c4e5ba4..fbac6aa 100644
--- a/hw/kdrive/ephyr/ephyrglxext.c
+++ b/hw/kdrive/ephyr/ephyrglxext.c
@@ -37,7 +37,9 @@
 #include <GL/glxproto.h>
 #include "GL/glx/glxserver.h"
 #include "GL/glx/indirect_table.h"
+#include "GL/glx/indirect_util.h"
 #include "GL/glx/unpack.h"
+#include "hostx.h"
 
 
 #ifdef XEPHYR_DRI
@@ -61,6 +63,18 @@ int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ;
 int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ;
 int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc);
 int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
 
 Bool
 ephyrHijackGLXExtension (void)
@@ -83,7 +97,6 @@ ephyrHijackGLXExtension (void)
 
     dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ;
     dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ;
-
     dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ;
     dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
 
@@ -91,6 +104,24 @@ ephyrHijackGLXExtension (void)
     dispatch_functions[X_GLXQueryServerString][1] =
                                                 ephyrGLXQueryServerStringSwap ;
 
+    dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext ;
+    dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap ;
+
+    dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext ;
+    dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap ;
+
+    dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent ;
+    dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap ;
+
+    dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect ;
+    dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap ;
+
+    dispatch_functions[73][0] = ephyrGLXGetString ;
+    dispatch_functions[73][1] = ephyrGLXGetStringSwap ;
+
+    dispatch_functions[61][0] = ephyrGLXGetIntegerv ;
+    dispatch_functions[61][1] = ephyrGLXGetIntegervSwap ;
+
     /*
      * hijack some vendor priv entry point dispatch functions
      */
@@ -332,6 +363,7 @@ ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
     EPHYR_LOG ("enter\n") ;
     if (!ephyrHostGLXGetStringFromServer (req->screen,
                                           req->name,
+                                          EPHYR_HOST_GLX_QueryServerString,
                                           &server_string)) {
         EPHYR_LOG_ERROR ("failed to query string from host\n") ;
         goto out ;
@@ -377,5 +409,288 @@ ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc)
     return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ;
 }
 
+static int
+ephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap)
+{
+    int res=BadImplementation;
+    EphyrHostWindowAttributes host_w_attrs ;
+    __GLX_DECLARE_SWAP_VARIABLES;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_req, BadValue) ;
+    EPHYR_LOG ("enter\n") ;
+
+    if (a_do_swap) {
+        __GLX_SWAP_SHORT(&a_req->length);
+        __GLX_SWAP_INT(&a_req->context);
+        __GLX_SWAP_INT(&a_req->visual);
+        __GLX_SWAP_INT(&a_req->screen);
+        __GLX_SWAP_INT(&a_req->shareList);
+    }
+
+    EPHYR_LOG ("context creation requested. localid:%d, "
+               "screen:%d, visual:%d, direct:%d\n",
+               (int)a_req->context, (int)a_req->screen,
+               (int)a_req->visual, (int)a_req->isDirect) ;
+
+    memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ;
+    if (!hostx_get_window_attributes (hostx_get_window (), &host_w_attrs)) {
+        EPHYR_LOG_ERROR ("failed to get host window attrs\n") ;
+        goto out ;
+    }
+
+    EPHYR_LOG ("host window visual id: %d\n", host_w_attrs.visualid) ;
+
+    if (!ephyrHostGLXCreateContext (a_req->screen,
+                                    host_w_attrs.visualid,
+                                    a_req->context,
+                                    a_req->shareList,
+                                    a_req->isDirect)) {
+        EPHYR_LOG_ERROR ("ephyrHostGLXCreateContext() failed\n") ;
+        goto out ;
+    }
+    res = Success;
+out:
+    EPHYR_LOG ("leave\n") ;
+    return res ;
+}
+
+int
+ephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc)
+{
+    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+
+    return ephyrGLXCreateContextReal (req, FALSE) ;
+}
+
+int ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc)
+{
+    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+    return ephyrGLXCreateContextReal (req, TRUE) ;
+}
+
+static int
+ephyrGLXDestroyContextReal (__GLXclientState *a_cl,
+                            GLbyte *a_pc,
+                            Bool a_do_swap)
+{
+    int res=BadImplementation;
+    ClientPtr client = a_cl->client;
+    xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc;
+
+    EPHYR_LOG ("enter. id:%d\n", (int)req->context) ;
+    if (!ephyrHostDestroyContext (req->context)) {
+        EPHYR_LOG_ERROR ("ephyrHostDestroyContext() failed\n") ;
+        client->errorValue = req->context ;
+        goto out ;
+    }
+    res = Success ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return res ;
+}
+
+int
+ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+    int res=BadImplementation;
+    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
+    xGLXMakeCurrentReply reply ;
+
+    EPHYR_LOG ("enter\n") ;
+    memset (&reply, 0, sizeof (reply)) ;
+    if (!ephyrHostGLXMakeCurrent (hostx_get_window (),
+                                  req->context,
+                                  req->oldContextTag,
+                                  (int*)&reply.contextTag)) {
+        EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ;
+        goto out;
+    }
+    reply.length = 0;
+    reply.type = X_Reply;
+    reply.sequenceNumber = a_cl->client->sequence;
+    if (a_do_swap) {
+        __GLX_DECLARE_SWAP_VARIABLES;
+        __GLX_SWAP_SHORT(&reply.sequenceNumber);
+        __GLX_SWAP_INT(&reply.length);
+        __GLX_SWAP_INT(&reply.contextTag);
+    }
+    WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply);
+
+    res = Success ;
+out:
+    EPHYR_LOG ("leave\n") ;
+    return res ;
+}
+
+int
+ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+    ClientPtr client=NULL ;
+    int context_tag=0, name=0, res=BadImplementation, length=0 ;
+    char *string=NULL;
+    __GLX_DECLARE_SWAP_VARIABLES;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    client = a_cl->client ;
+
+    if (a_do_swap) {
+        __GLX_SWAP_INT (a_pc + 4);
+        __GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE);
+    }
+    context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ;
+    a_pc += __GLX_SINGLE_HDR_SIZE;
+    name = *(GLenum*)(a_pc + 0);
+    EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ;
+    if (!ephyrHostGLXGetStringFromServer (context_tag,
+                                          name,
+                                          EPHYR_HOST_GLX_GetString,
+                                          &string)) {
+        EPHYR_LOG_ERROR ("failed to get string from server\n") ;
+        goto out ;
+    }
+    if (string) {
+        length = strlen (string) ;
+        EPHYR_LOG ("got string: string:%s\n", string) ;
+    } else {
+        EPHYR_LOG ("got string: string (null)\n") ;
+    }
+    __GLX_BEGIN_REPLY (length);
+    __GLX_PUT_SIZE (length);
+    __GLX_SEND_HEADER ();
+    if (a_do_swap) {
+        __GLX_SWAP_REPLY_SIZE ();
+        __GLX_SWAP_REPLY_HEADER ();
+    }
+    WriteToClient (client, length, (char *)string);
+
+    res = Success ;
+out:
+    EPHYR_LOG ("enter\n") ;
+    return res ;
+}
+
+int
+ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+    int res=BadImplementation;
+    xGLXSingleReq * const req = (xGLXSingleReq *) a_pc;
+    GLenum int_name ;
+    int value=0 ;
+    GLint answer_buf_room[200];
+    GLint *buf=NULL ;
+
+    a_pc += __GLX_SINGLE_HDR_SIZE;
+
+    int_name = *(GLenum*) (a_pc+0) ;
+    if (!ephyrHostGetIntegerValue (req->contextTag, int_name, &value)) {
+        EPHYR_LOG_ERROR ("ephyrHostGetIntegerValue() failed\n") ;
+        goto out ;
+    }
+    buf = __glXGetAnswerBuffer (a_cl, sizeof (value),
+                                answer_buf_room,
+                                sizeof (answer_buf_room),
+                                4) ;
+
+    if (!buf) {
+        EPHYR_LOG_ERROR ("failed to allocate reply buffer\n") ;
+        res = BadAlloc ;
+        goto out ;
+    }
+    __glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ;
+    res = Success ;
+out:
+    return res ;
+}
+
+int
+ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+    int res=BadImplementation;
+    ClientPtr client = a_cl->client;
+    xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc;
+    xGLXIsDirectReply reply;
+    int is_direct=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ;
+
+    memset (&reply, 0, sizeof (reply)) ;
+    if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) {
+        EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ;
+        goto out ;
+    }
+    reply.isDirect = is_direct ;
+    reply.length = 0;
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
+    res = Success ;
+out:
+    return res ;
+}
+
+int
+ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXIsDirectReal (a_cl, a_pc, TRUE) ;
+}
+
 #endif /*XEPHYR_DRI*/
 
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
index 83e06a8..843a0e5 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -36,10 +36,10 @@
 #include <GL/internal/glcore.h>
 #include <GL/glxproto.h>
 #include <GL/glxint.h>
-#include "hostx.h"
 #include "ephyrhostglx.h"
 #define _HAVE_XALLOC_DECLS
 #include "ephyrlog.h"
+#include "hostx.h"
 
 #ifdef XEPHYR_DRI
 enum VisualConfRequestType {
@@ -107,6 +107,7 @@ out:
  * the real protocol packets used to request a string from the server have
  * an identical binary layout.  The only difference between them is the
  * meaning of the \c for_whom field and the value of the \c glxCode.
+ * (this has been copied from the mesa source code)
  */
 typedef struct GLXGenericGetString {
     CARD8 reqType;
@@ -124,20 +125,33 @@ typedef struct GLXGenericGetString {
 Bool
 ephyrHostGLXGetStringFromServer (int a_screen_number,
                                  int a_string_name,
+                                 enum EphyrHostGLXGetStringOps a_op,
                                  char **a_string)
 {
+    Bool is_ok=FALSE ;
     Display *dpy = hostx_get_display () ;
     xGLXGenericGetStringReq *req=NULL;
     xGLXSingleReply reply;
-    int length=0, numbytes=0, major_opcode=0;
+    int length=0, numbytes=0, major_opcode=0, get_string_op=0;
 
     EPHYR_RETURN_VAL_IF_FAIL (dpy && a_string, FALSE) ;
 
     EPHYR_LOG ("enter\n") ;
+    switch (a_op) {
+        case EPHYR_HOST_GLX_QueryServerString:
+            get_string_op = X_GLXQueryServerString;
+            break ;
+        case EPHYR_HOST_GLX_GetString:
+            get_string_op = X_GLsop_GetString;
+            break ;
+        default:
+            EPHYR_LOG_ERROR ("unknown EphyrHostGLXGetStringOp:%d\n", a_op) ;
+            goto out ;
+    }
 
     if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
         EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
-        return FALSE ;
+        goto out ;
     }
     EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
 
@@ -150,7 +164,7 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
      */
     GetReq (GLXGenericGetString, req);
     req->reqType = major_opcode;
-    req->glxCode = X_GLXQueryServerString;
+    req->glxCode = get_string_op;
     req->for_whom = a_screen_number;
     req->name = a_string_name;
 
@@ -162,18 +176,21 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
     *a_string = (char *) Xmalloc( numbytes );
     if (*a_string != NULL) {
         if (_XRead (dpy, *a_string, numbytes)) {
+            UnlockDisplay (dpy);
+            SyncHandle ();
             EPHYR_LOG_ERROR ("read failed\n") ;
+            goto out ;
         }
         length -= numbytes;
     }
-
     _XEatData (dpy, length) ;
-
     UnlockDisplay (dpy);
     SyncHandle ();
 
+    is_ok = TRUE ;
+out:
     EPHYR_LOG ("leave\n") ;
-    return TRUE ;
+    return is_ok ;
 }
 
 static Bool
@@ -378,5 +395,258 @@ out:
     return is_ok ;
 }
 
+Bool
+ephyrHostGLXCreateContext (int a_screen,
+                           int a_visual_id,
+                           int a_context_id,
+                           int a_share_list_ctxt_id,
+                           Bool a_direct)
+{
+    Bool is_ok = FALSE;
+    Display *dpy = hostx_get_display ();
+    int major_opcode=0, remote_context_id=0;
+    xGLXCreateContextReq *req;
+
+    EPHYR_LOG ("enter. screen:%d, visual:%d, contextid:%d, direct:%d\n",
+               a_screen, a_visual_id, a_context_id, a_direct) ;
+
+    if (!hostx_allocate_resource_id_peer (a_context_id, &remote_context_id)) {
+        EPHYR_LOG_ERROR ("failed to peer the context id %d host X",
+                         remote_context_id) ;
+        goto out ;
+    }
+
+    if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+        EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+        goto out ;
+    }
+
+    LockDisplay (dpy) ;
+
+    /* Send the glXCreateContext request */
+    GetReq(GLXCreateContext,req);
+    req->reqType = major_opcode;
+    req->glxCode = X_GLXCreateContext;
+    req->context = remote_context_id;
+    req->visual = a_visual_id;
+    req->screen = a_screen;
+    req->shareList = a_share_list_ctxt_id;
+    req->isDirect = a_direct;
+
+    is_ok = TRUE ;
+
+out:
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+Bool
+ephyrHostDestroyContext (int a_ctxt_id)
+{
+    Bool is_ok=FALSE;
+    Display *dpy=hostx_get_display ();
+    int major_opcode=0, remote_ctxt_id=0 ;
+    xGLXDestroyContextReq *req=NULL;
+
+    EPHYR_LOG ("enter:%d\n", a_ctxt_id) ;
+
+    if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+        EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+        goto out ;
+    }
+    if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_ctxt_id)) {
+        EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
+        goto out ;
+    }
+    EPHYR_LOG ("host context id:%d\n", remote_ctxt_id) ;
+
+    LockDisplay (dpy);
+    GetReq (GLXDestroyContext,req);
+    req->reqType = major_opcode;
+    req->glxCode = X_GLXDestroyContext;
+    req->context = remote_ctxt_id;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+Bool
+ephyrHostGLXMakeCurrent (int a_drawable,
+                         int a_glx_ctxt_id,
+                         int a_old_ctxt_tag,
+                         int *a_ctxt_tag)
+{
+    Bool is_ok=FALSE ;
+    Display *dpy = hostx_get_display () ;
+    int32_t major_opcode=0 ;
+    int remote_glx_ctxt_id=0 ;
+    xGLXMakeCurrentReq *req;
+    xGLXMakeCurrentReply reply;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_ctxt_tag, FALSE) ;
+
+    EPHYR_LOG ("enter. drawable:%d, context:%d, oldtag:%d\n",
+               a_drawable, a_glx_ctxt_id, a_old_ctxt_tag) ;
+
+    if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+        EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+        goto out ;
+    }
+    if (!hostx_get_resource_id_peer (a_glx_ctxt_id, &remote_glx_ctxt_id)) {
+        EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
+        goto out ;
+    }
+
+    LockDisplay (dpy);
+
+    GetReq (GLXMakeCurrent,req);
+    req->reqType = major_opcode;
+    req->glxCode = X_GLXMakeCurrent;
+    req->drawable = a_drawable;
+    req->context = remote_glx_ctxt_id;
+    req->oldContextTag = a_old_ctxt_tag;
+
+    memset (&reply, 0, sizeof (reply)) ;
+    if (!_XReply (dpy, (xReply*)&reply, 0, False)) {
+        EPHYR_LOG_ERROR ("failed to get reply from host\n") ;
+        goto out ;
+    }
+    *a_ctxt_tag = reply.contextTag ;
+    is_ok = TRUE ;
+
+out:
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+#define X_GLXSingle 0
+
+#define __EPHYR_GLX_SINGLE_PUT_CHAR(offset,a) \
+    *((INT8 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_PUT_SHORT(offset,a) \
+    *((INT16 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_PUT_LONG(offset,a) \
+    *((INT32 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_PUT_FLOAT(offset,a) \
+    *((FLOAT32 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_READ_XREPLY()       \
+    (void) _XReply(dpy, (xReply*) &reply, 0, False)
+
+#define EPHYR_GLX_SINGLE_GET_RETVAL(a,cast) \
+    a = (cast) reply.retval
+
+#define EPHYR_GLX_SINGLE_GET_SIZE(a) \
+    a = (GLint) reply.size
+
+#define EPHYR_GLX_SINGLE_GET_CHAR(p) \
+    *p = *(GLbyte *)&reply.pad3;
+
+#define EPHYR_GLX_SINGLE_GET_SHORT(p) \
+    *p = *(GLshort *)&reply.pad3;
+
+#define EPHYR_GLX_SINGLE_GET_LONG(p) \
+    *p = *(GLint *)&reply.pad3;
+
+#define EPHYR_GLX_SINGLE_GET_FLOAT(p) \
+    *p = *(GLfloat *)&reply.pad3;
+
+Bool
+ephyrHostGetIntegerValue (int a_current_context_tag, int a_int, int *a_val)
+{
+    Bool is_ok=FALSE;
+    Display *dpy = hostx_get_display () ;
+    int major_opcode=0, size=0;
+    xGLXSingleReq *req=NULL;
+    xGLXSingleReply reply;
+    unsigned char* pc=NULL ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_val, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+    if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+        EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+        goto out ;
+    }
+    LockDisplay (dpy) ;
+    GetReqExtra (GLXSingle, 4, req) ;
+    req->reqType = major_opcode ;
+    req->glxCode = X_GLsop_GetIntegerv ;
+    req->contextTag = a_current_context_tag;
+    pc = ((unsigned char *)(req) + sz_xGLXSingleReq) ;
+    EPHYR_GLX_SINGLE_PUT_LONG (0, a_int) ;
+    EPHYR_GLX_SINGLE_READ_XREPLY () ;
+    EPHYR_GLX_SINGLE_GET_SIZE (size) ;
+    if (!size) {
+        UnlockDisplay (dpy) ;
+        SyncHandle () ;
+        EPHYR_LOG_ERROR ("X_GLsop_GetIngerv failed\n") ;
+        goto out ;
+    }
+    EPHYR_GLX_SINGLE_GET_LONG (a_val) ;
+    UnlockDisplay (dpy) ;
+    SyncHandle () ;
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+Bool
+ephyrHostIsContextDirect (int a_ctxt_id,
+                          int *a_is_direct)
+{
+    Bool is_ok=FALSE;
+    Display *dpy = hostx_get_display () ;
+    xGLXIsDirectReq *req=NULL;
+    xGLXIsDirectReply reply;
+    int major_opcode=0, remote_glx_ctxt_id=0;
+
+    EPHYR_LOG ("enter\n") ;
+    if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+        EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+        goto out ;
+    }
+    if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_glx_ctxt_id)) {
+        EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
+        goto out ;
+    }
+    memset (&reply, 0, sizeof (reply)) ;
+
+    /* Send the glXIsDirect request */
+    LockDisplay (dpy);
+    GetReq (GLXIsDirect,req);
+    req->reqType = major_opcode;
+    req->glxCode = X_GLXIsDirect;
+    req->context = remote_glx_ctxt_id;
+    if (!_XReply (dpy, (xReply*) &reply, 0, False)) {
+        EPHYR_LOG_ERROR ("fail in reading reply from host\n") ;
+        UnlockDisplay (dpy);
+        SyncHandle ();
+        goto out ;
+    }
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    *a_is_direct = reply.isDirect ;
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
 #endif /*XEPHYR_DRI*/
 
diff --git a/hw/kdrive/ephyr/ephyrhostglx.h b/hw/kdrive/ephyr/ephyrhostglx.h
index 1040f6c..6db362f 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.h
+++ b/hw/kdrive/ephyr/ephyrhostglx.h
@@ -28,9 +28,16 @@
 #ifndef __EPHYRHOSTGLX_H__
 #define __EPHYRHOSTGLX_H__
 
+enum EphyrHostGLXGetStringOps {
+    EPHYR_HOST_GLX_UNDEF,
+    EPHYR_HOST_GLX_QueryServerString,
+    EPHYR_HOST_GLX_GetString,
+};
+
 Bool ephyrHostGLXQueryVersion (int *a_maj, int *a_min) ;
 Bool ephyrHostGLXGetStringFromServer (int a_screen_number,
                                       int a_string_name,
+                                      enum EphyrHostGLXGetStringOps a_op,
                                       char **a_string) ;
 Bool ephyrHostGLXGetVisualConfigs (int a_screen,
                                    int32_t *a_num_visuals,
@@ -46,6 +53,24 @@ ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
 Bool ephyrHostGLXGetMajorOpcode (int32_t *a_opcode) ;
 Bool ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
                                  const char* a_extension_list) ;
+Bool ephyrHostGLXCreateContext (int a_screen,
+                                int a_visual_id,
+                                int a_context_id,
+                                int a_shared_list_ctx_id,
+                                Bool a_direct) ;
+
+Bool ephyrHostDestroyContext (int a_ctxt_id) ;
+
+Bool ephyrHostGLXMakeCurrent (int a_drawable, int a_glx_ctxt_id,
+                              int a_olg_ctxt_tag, int *a_ctxt_tag) ;
+
+Bool ephyrHostGetIntegerValue (int a_current_context_tag,
+                               int a_int,
+                               int *a_val) ;
+
+Bool ephyrHostIsContextDirect (int a_ctxt_id,
+                               int *a_is_direct) ;
+
 
 #endif /*__EPHYRHOSTGLX_H__*/
 
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 17712cd..51fda47 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -970,6 +970,27 @@ hostx_get_window(void)
 }
 
 int
+hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attrs)
+{
+    XWindowAttributes attrs ;
+
+    memset (&attrs, 0, sizeof (attrs)) ;
+
+    if (!XGetWindowAttributes (hostx_get_display (),
+                               a_window,
+                               &attrs)) {
+        return FALSE ;
+    }
+    a_attrs->x = attrs.x ;
+    a_attrs->y = attrs.y ;
+    a_attrs->width = attrs.width ;
+    a_attrs->height = attrs.height ;
+    if (attrs.visual)
+        a_attrs->visualid = attrs.visual->visualid ;
+    return TRUE ;
+}
+
+int
 hostx_get_extension_info (const char *a_ext_name,
                           int *a_major_opcode,
                           int *a_first_event,
@@ -1039,3 +1060,75 @@ out:
 
 }
 
+typedef struct {
+    int is_valid ;
+    int local_id ;
+    int remote_id ;
+} ResourcePair ;
+
+#define RESOURCE_PEERS_SIZE 1024*10
+static ResourcePair resource_peers[RESOURCE_PEERS_SIZE] ;
+
+int
+hostx_allocate_resource_id_peer (int a_local_resource_id,
+                                 int *a_remote_resource_id)
+{
+    int i=0 ;
+    ResourcePair *peer=NULL ;
+    Display *dpy=hostx_get_display ();
+
+    /*
+     * first make sure a resource peer
+     * does not exist already for
+     * a_local_resource_id
+     */
+    for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+        if (resource_peers[i].is_valid
+            && resource_peers[i].local_id == a_local_resource_id) {
+            peer = &resource_peers[i] ;
+            break ;
+        }
+    }
+    /*
+     * find one free peer entry, an feed it with
+     */
+    if (!peer) {
+        for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+            if (!resource_peers[i].is_valid) {
+                peer = &resource_peers[i] ;
+                break ;
+            }
+        }
+        if (peer) {
+            peer->remote_id = XAllocID (dpy);
+            peer->local_id = a_local_resource_id ;
+            peer->is_valid = TRUE ;
+        }
+    }
+    if (peer) {
+        *a_remote_resource_id = peer->remote_id ;
+        return TRUE ;
+    }
+    return FALSE ;
+}
+
+int
+hostx_get_resource_id_peer (int a_local_resource_id,
+                            int *a_remote_resource_id)
+{
+    int i=0 ;
+    ResourcePair *peer=NULL ;
+    for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+        if (resource_peers[i].is_valid
+            && resource_peers[i].local_id == a_local_resource_id) {
+            peer = &resource_peers[i] ;
+            break ;
+        }
+    }
+    if (peer) {
+        *a_remote_resource_id = peer->remote_id ;
+        return TRUE ;
+    }
+    return FALSE ;
+}
+
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index a44b520..51a5f68 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -104,6 +104,12 @@ typedef struct {
   int bits_per_rgb;
 } EphyrHostVisualInfo;
 
+typedef struct {
+    int x, y;
+    int width, height ;
+    int visualid ;
+} EphyrHostWindowAttributes;
+
 int
 hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
 
@@ -191,6 +197,9 @@ int
 hostx_get_window(void) ;
 
 int
+hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attr)  ;
+
+int
 hostx_get_extension_info (const char *a_ext_name,
                           int *a_major_opcode,
                           int *a_first_even,
@@ -198,4 +207,11 @@ hostx_get_extension_info (const char *a_ext_name,
 int
 hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
                         int *a_num_entries) ;
+int
+hostx_allocate_resource_id_peer (int a_local_resource_id,
+                                 int *a_remote_resource_id) ;
+int
+hostx_get_resource_id_peer (int a_local_resource_id,
+                            int *a_remote_resource_id) ;
+
 #endif
commit 8c78df0ea36abc7d46c4f59670289f4280f75507
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Thu Aug 30 22:31:47 2007 +0200

    Xserver: fix potential crash
    
    	* dix/extension.c:
    	  (AddExtensionAlias): don't crash when failed to add
    	  extension alias.

diff --git a/dix/extension.c b/dix/extension.c
index 186574d..4c0c3d2 100644
--- a/dix/extension.c
+++ b/dix/extension.c
@@ -184,6 +184,8 @@ _X_EXPORT Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
     char *name;
     char **aliases;
 
+    if (!ext)
+        return FALSE ;
     aliases = (char **)xrealloc(ext->aliases,
 				(ext->num_aliases + 1) * sizeof(char *));
     if (!aliases)
commit 024abe825cd702334266f6b8da289907bbd05970
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Tue Aug 28 15:59:45 2007 +0200

    Xephyr: add logging in the DRI extension

diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
index 89d9ae7..54ad2c0 100644
--- a/hw/kdrive/ephyr/ephyrdri.c
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -63,7 +63,9 @@ ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable)
 }
 
 Bool
-ephyrDRIOpenConnection (int a_screen, drm_handle_t *a_sarea, char **a_bus_id_string)
+ephyrDRIOpenConnection (int a_screen,
+                        drm_handle_t *a_sarea,
+                        char **a_bus_id_string)
 {
     Display *dpy = hostx_get_display () ;
     Bool is_ok=FALSE ;
@@ -108,13 +110,23 @@ ephyrDRIGetClientDriverName (int a_screen,
     Display *dpy = hostx_get_display () ;
     Bool is_ok=FALSE ;
 
+    EPHYR_RETURN_VAL_IF_FAIL (a_ddx_driver_major_version
+                              && a_ddx_driver_minor_version
+                              && a_ddx_driver_patch_version
+                              && a_client_driver_name,
+                              FALSE);
     EPHYR_LOG ("enter\n") ;
     is_ok = XF86DRIGetClientDriverName (dpy, a_screen,
                                         a_ddx_driver_major_version,
                                         a_ddx_driver_minor_version,
                                         a_ddx_driver_patch_version,
                                         a_client_driver_name) ;
-    EPHYR_LOG ("leave\n") ;
+    EPHYR_LOG ("major:%d, minor:%d, patch:%d, name:%s\n",
+                *a_ddx_driver_major_version,
+                *a_ddx_driver_minor_version,
+                *a_ddx_driver_patch_version,
+                *a_client_driver_name) ;
+    EPHYR_LOG ("leave:%d\n", is_ok) ;
     return is_ok ;
 }
 
@@ -136,7 +148,7 @@ ephyrDRICreateContext (int a_screen,
                                   &v,
                                   a_returned_ctxt_id,
                                   a_hw_ctxt) ;
-    EPHYR_LOG ("leave\n") ;
+    EPHYR_LOG ("leave:%d\n", is_ok) ;
     return is_ok ;
 }
 
@@ -149,7 +161,7 @@ ephyrDRIDestroyContext (int a_screen,
 
     EPHYR_LOG ("enter\n") ;
     is_ok = XF86DRIDestroyContext (dpy, a_screen, a_context_id) ;
-    EPHYR_LOG ("leave\n") ;
+    EPHYR_LOG ("leave:%d\n", is_ok) ;
     return is_ok ;
 }
 
@@ -212,7 +224,7 @@ ephyrDRIGetDeviceInfo (int a_screen,
     is_ok = XF86DRIGetDeviceInfo (dpy, a_screen, a_frame_buffer,
                                   a_fb_origin, a_fb_size, a_fb_stride,
                                   a_dev_private_size, a_dev_private) ;
-    EPHYR_LOG ("leave\n") ;
+    EPHYR_LOG ("leave:%d\n", is_ok) ;
     return is_ok ;
 }
 #endif /*EPHYR_DRI*/
commit 1dd589410c6c5e8b62b4d15ec681b01452ec68c6
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Tue Aug 28 15:58:55 2007 +0200

    mirror the visuals of the host X at startup.
    
    	* hw/kdrive/ephyr/ephyr.c: make Xephyr mirror
    	  the visuals of the host X upon startup. This
    	  is important for GLX client apps.
    	* hw/kdrive/ephyr/hostx.c,h: add a hostx_get_visuals_info()
    	  to get the visuals of the host X.

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 8e12bbb..df91f83 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -54,6 +54,7 @@ Bool   EphyrWantGrayScale = 0;
 
 #ifdef XEPHYR_DRI
 extern void ephyrDRIExtensionInit(void) ;
+static Bool EphyrMirrorHostVisuals (void) ;
 #endif
 
 Bool
@@ -630,6 +631,7 @@ ephyrInitScreen (ScreenPtr pScreen)
     ephyrDRIExtensionInit () ;
     ephyrHijackGLXExtension () ;
     ephyrProxyExtensionInit ("ATIFGLRXDRI") ;
+    EphyrMirrorHostVisuals () ;
 #endif
   return TRUE;
 }
@@ -1046,6 +1048,168 @@ EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
 {
 }
 
+/**
+ * Duplicates a visual of a_screen
+ * In screen a_screen, for depth a_depth, find a visual which
+ * bitsPerRGBValue and colormap size equal
+ * a_bits_per_rgb_values and a_colormap_entries.
+ * The ID of that duplicated visual is set to a_new_id.
+ * That duplicated visual is then added to the list of visuals
+ * of the screen.
+ */
+static Bool
+EphyrDuplicateVisual (unsigned int a_screen,
+                      short a_depth,
+                      short a_class,
+                      short a_bits_per_rgb_values,
+                      short a_colormap_entries,
+                      unsigned int a_red_mask,
+                      unsigned int a_green_mask,
+                      unsigned int a_blue_mask,
+                      unsigned int a_new_id)
+{
+    Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ;
+    ScreenPtr screen=NULL ;
+    VisualRec new_visual, *new_visuals=NULL ;
+    int i=0 ;
+
+    EPHYR_LOG ("enter\n") ; 
+    if (a_screen > screenInfo.numScreens) {
+        EPHYR_LOG_ERROR ("bad screen number\n") ;
+        goto out;
+    }
+    memset (&new_visual, 0, sizeof (VisualRec)) ;
+
+    /*get the screen pointed to by a_screen*/
+    screen = screenInfo.screens[a_screen] ;
+    EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+
+    /*
+     * In that screen, first look for an existing visual that has the
+     * same characteristics as those passed in parameter
+     * to this function and copy it.
+     */
+    for (i=0; i < screen->numVisuals; i++) {
+        if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
+            screen->visuals[i].ColormapEntries == a_colormap_entries ) {
+            /*copy the visual found*/
+            memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
+            new_visual.vid = a_new_id ;
+            found_visual = TRUE ;
+            EPHYR_LOG ("found a visual that matches visual id: %d\n",
+                       a_new_id) ;
+            break;
+        }
+    }
+    if (!found_visual) {
+        EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ;
+        goto out ;
+    }
+    /*
+     * be prepare to extend screen->visuals to add new_visual to it
+     */
+    new_visuals = xcalloc (screen->numVisuals+1, sizeof (VisualRec)) ;
+    memmove (new_visuals,
+             screen->visuals,
+             screen->numVisuals*sizeof (VisualRec)) ;
+    memmove (&new_visuals[screen->numVisuals],
+             &new_visual,
+             sizeof (VisualRec)) ;
+    /*
+     * Now, in that same screen, update the screen->allowedDepths member.
+     * In that array, each element represents the visuals applicable to
+     * a given depth. So we need to add an entry matching the new visual
+     * that we are going to add to screen->visuals
+     */
+    for (i=0; i<screen->numDepths; i++) {
+        VisualID *vids=NULL;
+        DepthPtr cur_depth=NULL ;
+        /*find the entry matching a_depth*/
+        if (screen->allowedDepths[i].depth != a_depth)
+            continue ;
+        cur_depth = &screen->allowedDepths[i];
+        /*
+         * extend the list of visual IDs in that entry,
+         * so to add a_new_id in there.
+         */
+        vids = xrealloc (cur_depth->vids,
+                         (cur_depth->numVids+1)*sizeof (VisualID));
+        if (!vids) {
+            EPHYR_LOG_ERROR ("failed to realloc numids\n") ;
+            goto out ;
+        }
+        vids[cur_depth->numVids] = a_new_id ;
+        /*
+         * Okay now commit our change.
+         * Do really update screen->allowedDepths[i]
+         */
+        cur_depth->numVids++ ;
+        cur_depth->vids = vids ;
+        found_depth=TRUE;
+    }
+    if (!found_depth) {
+        EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n",
+                         a_screen) ;
+        goto out ;
+    }
+    /*
+     * Commit our change to screen->visuals
+     */
+    xfree (screen->visuals) ;
+    screen->visuals = new_visuals ;
+    screen->numVisuals++ ;
+    new_visuals = NULL ;
+
+    is_ok = TRUE ;
+out:
+    if (new_visuals) {
+        xfree (new_visuals) ;
+        new_visuals = NULL ;
+    }
+    EPHYR_LOG ("leave\n") ; 
+    return is_ok ;
+}
+
+/**
+ * Duplicates the visuals of the host X server.
+ * This is necessary to have visuals that have the same
+ * ID as those of the host X. It is important to have that for
+ * GLX.
+ */
+static Bool
+EphyrMirrorHostVisuals (void)
+{
+    Bool is_ok=FALSE;
+    EphyrHostVisualInfo  *visuals=NULL;
+    int nb_visuals=0, i=0;
+
+    EPHYR_LOG ("enter\n") ;
+    if (!hostx_get_visuals_info (&visuals, &nb_visuals)) {
+        EPHYR_LOG_ERROR ("failed to get host visuals\n") ;
+        goto out ;
+    }
+    for (i=0; i<nb_visuals; i++) {
+        if (!EphyrDuplicateVisual (visuals[i].screen,
+                                   visuals[i].depth,
+                                   visuals[i].class,
+                                   visuals[i].bits_per_rgb,
+                                   visuals[i].colormap_size,
+                                   visuals[i].red_mask,
+                                   visuals[i].blue_mask,
+                                   visuals[i].green_mask,
+                                   visuals[i].visualid)) {
+            EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
+                             (int)visuals[i].visualid) ;
+        }
+    }
+
+    is_ok = TRUE ;
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok;
+}
+
+
 KdKeyboardDriver EphyrKeyboardDriver = {
     "ephyr",
     EphyrKeyboardInit,
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 8323c28..17712cd 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -40,6 +40,7 @@
 #include <X11/Xatom.h>
 #include <X11/keysym.h>
 #include <X11/extensions/XShm.h>
+#include "ephyrlog.h"
 
 /*  
  * All xlib calls go here, which gets built as its own .a .
@@ -987,3 +988,54 @@ hostx_get_extension_info (const char *a_ext_name,
    return 1 ;
 }
 
+int
+hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
+                        int *a_num_entries)
+{
+    Display *dpy=hostx_get_display () ;
+    Bool is_ok=False ;
+    XVisualInfo templ, *visuals=NULL;
+    EphyrHostVisualInfo *host_visuals=NULL ;
+    int nb_items=0, i=0;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_visuals && a_num_entries && dpy,
+                              False) ;
+    EPHYR_LOG ("enter\n") ;
+    memset (&templ, 0, sizeof (templ)) ;
+    visuals = XGetVisualInfo (dpy, VisualNoMask, &templ, &nb_items) ;
+    if (!visuals) {
+        EPHYR_LOG_ERROR ("host does not advertise any visual\n") ;
+        goto out ;
+    }
+    EPHYR_LOG ("host advertises %d visuals\n", nb_items) ;
+    host_visuals = calloc (nb_items, sizeof (EphyrHostVisualInfo)) ;
+    for (i=0; i<nb_items; i++) {
+        host_visuals[i].visualid = visuals[i].visualid ;
+        host_visuals[i].screen = visuals[i].screen ;
+        host_visuals[i].depth = visuals[i].depth ;
+        host_visuals[i].class = visuals[i].class ;
+        host_visuals[i].red_mask = visuals[i].red_mask ;
+        host_visuals[i].green_mask = visuals[i].green_mask ;
+        host_visuals[i].blue_mask = visuals[i].blue_mask ;
+        host_visuals[i].colormap_size = visuals[i].colormap_size ;
+        host_visuals[i].bits_per_rgb = visuals[i].bits_per_rgb ;
+    }
+    *a_visuals = host_visuals ;
+    *a_num_entries = nb_items;
+    host_visuals=NULL;
+
+    is_ok = TRUE;
+out:
+    if (visuals) {
+        XFree (visuals) ;
+        visuals = NULL;
+    }
+    if (host_visuals) {
+        free (host_visuals) ;
+        host_visuals = NULL;
+    }
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+
+}
+
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 7babd34..a44b520 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -92,6 +92,18 @@ struct EphyrHostXEvent
   int key_state;
 };
 
+typedef struct {
+  VisualID visualid;
+  int screen;
+  int depth;
+  int class;
+  unsigned long red_mask;
+  unsigned long green_mask;
+  unsigned long blue_mask;
+  int colormap_size;
+  int bits_per_rgb;
+} EphyrHostVisualInfo;
+
 int
 hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
 
@@ -183,5 +195,7 @@ hostx_get_extension_info (const char *a_ext_name,
                           int *a_major_opcode,
                           int *a_first_even,
                           int *a_first_error) ;
-
+int
+hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
+                        int *a_num_entries) ;
 #endif
commit 26da625055a3876c93a7a005520657b971748c4e
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Tue Aug 28 15:55:05 2007 +0200

    proxy the glXGetFBConfigSGIX call
    
    	* hw/kdrive/ephyr/ephyrglxext.c:
    	  (ephyrGLXGetFBConfigsSGIX): proxy the GLXGetFBConfigsSGIX call.
    	  It is a vendor extension to get the visual configs as a list of
    	  name/value pairs.
    	  (ephyrHijackGLXExtension): hijack the VendorPriv_dispatch_info
    	  dispatch table to register our implementation of GLXGetFBConfigsSGIX
    	  (ephyrGLXGetFBConfigsSGIXReal): added this where the real
    	   implementation of GLXGetFBConfigsSGIX is. It support bytes swapping.
    	  (ephyrGLXGetFBConfigsSGIX,ephyrGLXGetFBConfigsSGIXSwap): these are
    	  the dispatch entry points. They just call
    	  ephyrGLXGetFBConfigsSGIXReal.
    	* hw/kdrive/ephyr/ephyrhostglx.c,h: reorganize the proxies to get
    	  visual params from the host so that they clearly support the different
    	  methods of doing so.

diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
index d0380f1..c4e5ba4 100644
--- a/hw/kdrive/ephyr/ephyrglxext.c
+++ b/hw/kdrive/ephyr/ephyrglxext.c
@@ -59,17 +59,22 @@ int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ;
 int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ;
 int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ;
 int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc);
 
 Bool
 ephyrHijackGLXExtension (void)
 {
     const void *(*dispatch_functions)[2];
 
-    EPHYR_LOG ("Got GLX extension\n") ;
+    EPHYR_LOG ("going to hijack some glx entry points ...\n") ;
     if (!Single_dispatch_info.dispatch_functions) {
         EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ;
         return FALSE ;
     }
+    /*
+     * hijack some single entry point dispatch functions
+     */
     dispatch_functions = Single_dispatch_info.dispatch_functions ;
     EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ;
 
@@ -83,9 +88,16 @@ ephyrHijackGLXExtension (void)
     dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
 
     dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ;
-    dispatch_functions[X_GLXQueryServerString][1] = ephyrGLXQueryServerStringSwap ;
+    dispatch_functions[X_GLXQueryServerString][1] =
+                                                ephyrGLXQueryServerStringSwap ;
 
-    EPHYR_LOG ("hijacked mesa GL to forward requests to host X\n") ;
+    /*
+     * hijack some vendor priv entry point dispatch functions
+     */
+    dispatch_functions = VendorPriv_dispatch_info.dispatch_functions ;
+    dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX;
+    dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap;
+    EPHYR_LOG ("hijacked glx entry points to forward requests to host X\n") ;
 
     return TRUE ;
 }
@@ -114,6 +126,8 @@ ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc)
         EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ;
         goto out ;
     }
+    EPHYR_LOG ("major:%d, minor:%d\n",
+                major, minor);
     reply.majorVersion = major ;
     reply.minorVersion = minor ;
     reply.length = 0 ;
@@ -145,7 +159,9 @@ ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc)
 }
 
 static int
-ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl,
+                              GLbyte *a_pc,
+                              Bool a_do_swap)
 {
     xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
     ClientPtr client = a_cl->client;
@@ -200,6 +216,64 @@ out:
     return res ;
 }
 
+static int
+ephyrGLXGetFBConfigsSGIXReal (__GLXclientState *a_cl,
+                              GLbyte *a_pc,
+                              Bool a_do_swap)
+{
+    xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)a_pc;
+    ClientPtr client = a_cl->client;
+    xGLXGetVisualConfigsReply reply;
+    int32_t *props_buf=NULL, num_visuals=0,
+            num_props=0, res=BadImplementation, i=0,
+            props_per_visual_size=0,
+            props_buf_size=0;
+    __GLX_DECLARE_SWAP_VARIABLES;
+    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+    EPHYR_LOG ("enter\n") ;
+
+    if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX (req->screen,
+                                                 &num_visuals,
+                                                 &num_props,
+                                                 &props_buf_size,
+                                                 &props_buf)) {
+        EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
+        goto out ;
+    }
+    EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
+
+    reply.numVisuals = num_visuals;
+    reply.numProps = num_props;
+    reply.length = props_buf_size >> 2;
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+
+    if (a_do_swap) {
+        __GLX_SWAP_SHORT(&reply.sequenceNumber);
+        __GLX_SWAP_INT(&reply.length);
+        __GLX_SWAP_INT(&reply.numVisuals);
+        __GLX_SWAP_INT(&reply.numProps);
+        __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
+    }
+    WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
+    props_per_visual_size = props_buf_size/num_visuals ;
+    for (i=0; i < num_visuals; i++) {
+        WriteToClient (client,
+                       props_per_visual_size,
+                       &((char*)props_buf)[i*props_per_visual_size]);
+    }
+    res = Success ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    if (props_buf) {
+        xfree (props_buf) ;
+        props_buf = NULL ;
+    }
+    return res ;
+}
+
 int
 ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc)
 {
@@ -256,10 +330,13 @@ ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
     int length=0 ;
 
     EPHYR_LOG ("enter\n") ;
-    if (!ephyrHostGLXGetStringFromServer (req->screen, req->name, &server_string)) {
+    if (!ephyrHostGLXGetStringFromServer (req->screen,
+                                          req->name,
+                                          &server_string)) {
         EPHYR_LOG_ERROR ("failed to query string from host\n") ;
         goto out ;
     }
+    EPHYR_LOG ("string: %s", server_string) ;
     length= strlen (server_string) + 1;
     reply.type = X_Reply ;
     reply.sequenceNumber = client->sequence ;
@@ -287,5 +364,18 @@ ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc)
     return BadImplementation ;
 }
 
+
+int
+ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ;
+}
+
 #endif /*XEPHYR_DRI*/
 
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
index 693fbc1..83e06a8 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -42,7 +42,20 @@
 #include "ephyrlog.h"
 
 #ifdef XEPHYR_DRI
-
+enum VisualConfRequestType {
+    EPHYR_GET_FB_CONFIG,
+    EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
+    EPHYR_GET_VISUAL_CONFIGS
+
+};
+
+static Bool ephyrHostGLXGetVisualConfigsInternal
+                                        (enum VisualConfRequestType a_type,
+                                         int32_t a_screen,
+                                         int32_t *a_num_visuals,
+                                         int32_t *a_num_props,
+                                         int32_t *a_props_buf_size,
+                                         int32_t **a_props_buf);
 Bool
 ephyrHostGLXGetMajorOpcode (int *a_opcode)
 {
@@ -163,12 +176,13 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
     return TRUE ;
 }
 
-Bool
-ephyrHostGLXGetVisualConfigs (int32_t a_screen,
-                              int32_t *a_num_visuals,
-                              int32_t *a_num_props,
-                              int32_t *a_props_buf_size,
-                              int32_t **a_props_buf)
+static Bool
+ephyrHostGLXGetVisualConfigsInternal (enum VisualConfRequestType a_type,
+                                      int32_t a_screen,
+                                      int32_t *a_num_visuals,
+                                      int32_t *a_num_props,
+                                      int32_t *a_props_buf_size,
+                                      int32_t **a_props_buf)
 {
     Bool is_ok = FALSE ;
     Display *dpy = hostx_get_display () ;
@@ -177,7 +191,6 @@ ephyrHostGLXGetVisualConfigs (int32_t a_screen,
     xGLXVendorPrivateWithReplyReq *vpreq;
     xGLXGetFBConfigsSGIXReq *sgi_req;
     xGLXGetVisualConfigsReply reply;
-    unsigned supported_request=0;
     char *server_glx_version=NULL,
          *server_glx_extensions=NULL ;
     int j=0,
@@ -196,44 +209,22 @@ ephyrHostGLXGetVisualConfigs (int32_t a_screen,
         EPHYR_LOG_ERROR ("failed to get opcode\n") ;
         goto out ;
     }
-    if (!ephyrHostGLXGetStringFromServer (0, GLX_VERSION,
-                                          &server_glx_version)
-        || !server_glx_version) {
-        EPHYR_LOG_ERROR ("failed to get glx version from server\n") ;
-        goto out ;
-    }
-
-    if (atof (server_glx_version) >= 1.3 ) {
-        supported_request = 1;
-    }
-
-    if (!ephyrHostGLXGetStringFromServer (a_screen, GLX_EXTENSIONS,
-                                          &server_glx_extensions)) {
-        EPHYR_LOG_ERROR ("failed to get glx extensions from server for screen: %d\n",
-                         a_screen) ;
-        goto out ;
-    }
-    if (supported_request != 1) {
-        if (server_glx_extensions
-            && strstr (server_glx_extensions, "GLX_SGIX_fbconfig" ) != NULL ) {
-            supported_request = 2;
-        } else {
-            supported_request = 3;
-        }
-    }
 
     LockDisplay(dpy);
-    switch (supported_request) {
-        case 1:
+    switch (a_type) {
+        case EPHYR_GET_FB_CONFIG:
         GetReq(GLXGetFBConfigs,fb_req);
         fb_req->reqType = major_opcode;
         fb_req->glxCode = X_GLXGetFBConfigs;
         fb_req->screen = a_screen;
         break;
 
-        case 2:
+        case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX:
         GetReqExtra(GLXVendorPrivateWithReply,
-                sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
+                    sz_xGLXGetFBConfigsSGIXReq
+                         -
+                    sz_xGLXVendorPrivateWithReplyReq,
+                    vpreq);
         sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
         sgi_req->reqType = major_opcode;
         sgi_req->glxCode = X_GLXVendorPrivateWithReply;
@@ -241,7 +232,7 @@ ephyrHostGLXGetVisualConfigs (int32_t a_screen,
         sgi_req->screen = a_screen;
         break;
 
-        case 3:
+        case EPHYR_GET_VISUAL_CONFIGS:
         GetReq(GLXGetVisualConfigs,req);
         req->reqType = major_opcode;
         req->glxCode = X_GLXGetVisualConfigs;
@@ -274,7 +265,7 @@ ephyrHostGLXGetVisualConfigs (int32_t a_screen,
         goto out ;
     }
 
-    if (supported_request != 3) {
+    if (a_type != EPHYR_GET_VISUAL_CONFIGS) {
         num_props *= 2;
     }
     props_per_visual_size = num_props * __GLX_SIZE_INT32;
@@ -282,7 +273,7 @@ ephyrHostGLXGetVisualConfigs (int32_t a_screen,
     props_buf = malloc (props_buf_size) ;
     for (j = 0; j < reply.numVisuals; j++) {
         if (_XRead (dpy,
-                    (char*)props_buf + j*props_per_visual_size,
+                    &((char*)props_buf)[j*props_per_visual_size],
                     props_per_visual_size) != Success) {
             EPHYR_LOG_ERROR ("read failed\n") ;
         }
@@ -290,7 +281,7 @@ ephyrHostGLXGetVisualConfigs (int32_t a_screen,
     UnlockDisplay(dpy);
 
     *a_num_visuals = num_visuals ;
-    *a_num_props = num_props ;
+    *a_num_props = reply.numProps ;
     *a_props_buf_size = props_buf_size ;
     *a_props_buf = props_buf ;
     is_ok = TRUE ;
@@ -309,6 +300,47 @@ out:
 }
 
 Bool
+ephyrHostGLXGetVisualConfigs (int32_t a_screen,
+                              int32_t *a_num_visuals,
+                              int32_t *a_num_props,
+                              int32_t *a_props_buf_size,
+                              int32_t **a_props_buf)
+{
+    Bool is_ok = FALSE;
+
+    EPHYR_LOG ("enter\n") ;
+    is_ok = ephyrHostGLXGetVisualConfigsInternal (EPHYR_GET_VISUAL_CONFIGS,
+                                                  a_screen,
+                                                  a_num_visuals,
+                                                  a_num_props,
+                                                  a_props_buf_size,
+                                                  a_props_buf) ;
+
+    EPHYR_LOG ("leave:%d\n", is_ok) ;
+    return is_ok;
+}
+
+Bool
+ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
+                                        int32_t *a_num_visuals,
+                                        int32_t *a_num_props,
+                                        int32_t *a_props_buf_size,
+                                        int32_t **a_props_buf)
+{
+    Bool is_ok=FALSE ;
+    EPHYR_LOG ("enter\n") ;
+    is_ok = ephyrHostGLXGetVisualConfigsInternal
+                                        (EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
+                                         a_screen,
+                                         a_num_visuals,
+                                         a_num_props,
+                                         a_props_buf_size,
+                                         a_props_buf) ;
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+Bool
 ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
                             const char* a_extension_list)
 {
diff --git a/hw/kdrive/ephyr/ephyrhostglx.h b/hw/kdrive/ephyr/ephyrhostglx.h
index 7a158f3..1040f6c 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.h
+++ b/hw/kdrive/ephyr/ephyrhostglx.h
@@ -37,9 +37,13 @@ Bool ephyrHostGLXGetVisualConfigs (int a_screen,
                                    int32_t *a_num_props,
                                    int32_t *a_props_buf_size,
                                    int32_t **a_props_buf) ;
-
+Bool
+ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
+                                        int32_t *a_num_visuals,
+                                        int32_t *a_num_props,
+                                        int32_t *a_props_buf_size,
+                                        int32_t **a_props_buf);
 Bool ephyrHostGLXGetMajorOpcode (int32_t *a_opcode) ;
-
 Bool ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
                                  const char* a_extension_list) ;
 
commit 5af73f98c46dfe5640185ca90feb20c39c6e06fa
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Fri Aug 24 16:30:50 2007 +0200

    EPHYR: Add an experiment proto proxy extension.
    
    	* hw/kdrive/ephyr/Makefile.am: add the proxy extension to
    	  ephyr. The proxy extension is an experimental extension that
    	  forwards protocol packets targeted at a given extension to the
    	  host X.
    	* hw/kdrive/ephyr/ephyr.c: init proxy ext.
    	* hw/kdrive/ephyr/ephyrhostproxy.c,h: added this new file as part of the
    	  proxy extension.
    	* hw/kdrive/ephyr/ephyrproxyext.c,h: ditto
    	* hw/kdrive/ephyr/hostx.c: add the hostx_get_get_extension_info() entry
    	  point.

diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 5e33163..604e22e 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -30,6 +30,11 @@ libxephyr_a_SOURCES =	\
 	ephyrglxext.h	\
 	ephyrhostglx.c	\
 	ephyrhostglx.h	\
+	ephyrhostproxy.c \
+	ephyrhostproxy.h \
+	ephyrhostproxy.c \
+	ephyrproxyext.c	\
+	ephyrproxyext.h	\
 	os.c		\
 	hostx.h         \
 	ephyr.h		\
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index b460b96..8e12bbb 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -31,8 +31,12 @@
 #include "inputstr.h"
 #include "scrnintstr.h"
 #include "ephyrlog.h"
+
+#ifdef XEPHYR_DRI
 #include "ephyrdri.h"
 #include "ephyrglxext.h"
+#include "ephyrproxyext.h"
+#endif /*XEPHYR_DRI*/
 
 extern int KdTsPhyScreen;
 KdKeyboardInfo *ephyrKbd;
@@ -625,6 +629,7 @@ ephyrInitScreen (ScreenPtr pScreen)
 #ifdef XEPHYR_DRI
     ephyrDRIExtensionInit () ;
     ephyrHijackGLXExtension () ;
+    ephyrProxyExtensionInit ("ATIFGLRXDRI") ;
 #endif
   return TRUE;
 }
diff --git a/hw/kdrive/ephyr/ephyrhostproxy.c b/hw/kdrive/ephyr/ephyrhostproxy.c
new file mode 100644
index 0000000..ce3f018
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostproxy.c
@@ -0,0 +1,94 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include <X11/Xlibint.h>
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "ephyrhostproxy.h"
+#include "hostx.h"
+
+/* byte swap a short */
+#define swaps(x, n) { \
+    n = ((char *) (x))[0];\
+    ((char *) (x))[0] = ((char *) (x))[1];\
+    ((char *) (x))[1] = n; }
+
+#define GetXReq(req) \
+    WORD64ALIGN ;\
+    if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\
+            _XFlush(dpy);\
+    req = (xReq *)(dpy->last_req = dpy->bufptr);\
+    dpy->bufptr += SIZEOF(xReq);\
+    dpy->request++
+
+
+Bool
+ephyrHostProxyDoForward (pointer a_request_buffer,
+                         struct XReply *a_reply,
+                         Bool a_do_swap)
+{
+    Bool is_ok = FALSE ;
+    int n=0 ;
+    Display *dpy=hostx_get_display () ;
+    xReq *in_req = (xReq*) a_request_buffer ;
+    xReq *forward_req=NULL ;
+    struct XReply reply ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (in_req && dpy, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    if (a_do_swap) {
+        swaps (&in_req->length, n) ;
+    }
+    EPHYR_LOG ("Req {type:%d, data:%d, length:%d}\n",
+               in_req->reqType, in_req->data, in_req->length) ;
+    GetXReq (forward_req) ;
+    memmove (forward_req, in_req, 4) ;
+
+    if (!_XReply (dpy, (xReply*) &reply, 0, FALSE)) {
+        EPHYR_LOG_ERROR ("failed to get reply\n") ;
+        goto out;
+    }
+    EPHYR_LOG ("XReply{type:%d, foo:%d, seqnum:%d, length:%d}\n",
+               reply.type, reply.foo, reply.sequence_number, reply.length) ;
+
+    if (a_reply) {
+        memmove (a_reply, &reply, sizeof (reply)) ;
+    }
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
diff --git a/hw/kdrive/ephyr/ephyrhostproxy.h b/hw/kdrive/ephyr/ephyrhostproxy.h
new file mode 100644
index 0000000..720c986
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostproxy.h
@@ -0,0 +1,51 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+
+#ifndef __EPHYRHOSTPROXY_H__
+#define __EPHYRHOSTPROXY_H__
+
+struct XReply {
+    int8_t type ;/*X_Reply*/
+    int8_t foo;
+    int16_t sequence_number ;
+    int32_t length ;
+    /*following is some data up to 32 bytes lenght*/
+    int32_t pad0 ;
+    int32_t pad1 ;
+    int32_t pad2 ;
+    int32_t pad3 ;
+    int32_t pad4 ;
+    int32_t pad5 ;
+};
+
+Bool
+ephyrHostProxyDoForward (pointer a_request_buffer,
+                         struct XReply *a_reply,
+                         Bool a_do_swap) ;
+
+#endif /*__EPHYRHOSTPROXY_H__*/
diff --git a/hw/kdrive/ephyr/ephyrproxyext.c b/hw/kdrive/ephyr/ephyrproxyext.c
new file mode 100644
index 0000000..0c070f4
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrproxyext.c
@@ -0,0 +1,119 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+
+/*
+ * \file
+ * This file defines a proxy extension that forwards requests.
+ * When a request to extension FOO is sent to Xephyr, that request is forwared
+ * to the host X, without even trying to know what the request means.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "ephyrproxyext.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "ephyrhostproxy.h"
+#include "hostx.h"
+
+static Bool ephyrProxyGetHostExtensionInfo (const char *a_ext_name,
+                                            int *a_major_opcode,
+                                            int *a_first_event,
+                                            int *a_first_error) ;
+
+static int ephyrProxyProcDispatch (ClientPtr client) ;
+
+static Bool
+ephyrProxyGetHostExtensionInfo (const char *a_ext_name,
+                                int *a_major_opcode,
+                                int *a_first_event,
+                                int *a_first_error)
+{
+    return hostx_get_extension_info (a_ext_name, a_major_opcode,
+                                     a_first_event, a_first_error) ;
+}
+
+static int
+ephyrProxyProcDispatch (ClientPtr a_client)
+{
+    int res=BadImplementation ;
+    struct XReply reply ;
+
+    if (!ephyrHostProxyDoForward (a_client->requestBuffer, &reply, FALSE)) {
+        EPHYR_LOG_ERROR ("forwarding failed\n") ;
+        goto out ;
+    }
+    reply.sequence_number = a_client->sequence;
+    res = Success ;
+
+    WriteToClient(a_client, 32, (char *)&reply);
+
+out:
+    return res ;
+}
+
+static void
+ephyrProxyProcReset (ExtensionEntry *a_entry)
+{
+}
+
+Bool
+ephyrProxyExtensionInit (const char *a_extension_name)
+{
+    Bool is_ok = FALSE ;
+    int major_opcode=0, first_event=0, first_error=0;
+    ExtensionEntry *ext=NULL ;
+
+    if (!ephyrProxyGetHostExtensionInfo (a_extension_name,
+                                         &major_opcode,
+                                         &first_event,
+                                         &first_error)) {
+        EPHYR_LOG ("failed to query extension %s from host\n", a_extension_name) ;
+        goto out;
+    }
+    ext = AddExtension ((char*)a_extension_name, 0, 0,
+                        ephyrProxyProcDispatch,
+                        ephyrProxyProcDispatch,
+                        ephyrProxyProcReset,
+                        StandardMinorOpcode) ;
+    if (!ext) {
+        EPHYR_LOG_ERROR ("failed to add the extension\n") ;
+        goto out ;
+    }
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
diff --git a/hw/kdrive/ephyr/ephyrproxyext.h b/hw/kdrive/ephyr/ephyrproxyext.h
new file mode 100644
index 0000000..e52f8d8
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrproxyext.h
@@ -0,0 +1,34 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifndef __EPHYRPROXYEXT_H__
+#define __EPHYRPROXYEXT_H__
+
+Bool ephyrProxyExtensionInit (const char *a_extension_name) ;
+
+#endif /*__EPHYRPROXYEXT_H__*/
+
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 8a2762f..8323c28 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -967,3 +967,23 @@ hostx_get_window(void)
 {
     return HostX.win ;
 }
+
+int
+hostx_get_extension_info (const char *a_ext_name,
+                          int *a_major_opcode,
+                          int *a_first_event,
+                          int *a_first_error)
+{
+    if (!a_ext_name || !a_major_opcode || !a_first_event || !a_first_error)
+      return 0 ;
+   if (!XQueryExtension (HostX.dpy,
+                         a_ext_name,
+                         a_major_opcode,
+                         a_first_event,
+                         a_first_error))
+     {
+       return 0 ;
+     }
+   return 1 ;
+}
+
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 1d8cd70..7babd34 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -178,4 +178,10 @@ hostx_get_display(void) ;
 int
 hostx_get_window(void) ;
 
+int
+hostx_get_extension_info (const char *a_ext_name,
+                          int *a_major_opcode,
+                          int *a_first_even,
+                          int *a_first_error) ;
+
 #endif
commit c06fa924b4781a35b86e4a78d95ff3e9d95b02d1
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Thu Aug 23 11:53:02 2007 +0200

    XEPHYR: more GLX/DRI proxying work.
    
    	* hw/kdrive/ephyr/XF86dri.c: re format this correctly.
    	  Make function decls honour the Ansi-C standard.
    	* hw/kdrive/ephyr/ephyr.c: protect glx/dri related
    	  extension initialisation with the XEPHYR_DRI
    	  macro. Initialize the GLX ext hijacking
    	  at startup.
    	* hw/kdrive/ephyr/ephyrdri.c: add more logging to ease debugging
    	* hw/kdrive/ephyr/ephyrdriext.c: ditto. reformat.
    	* hw/kdrive/ephyr/ephyrglxext.c,h: add this extension to
    	  proxy GLX requests to the host X. started to proxy those nedded to
    	  make glxinfo work with fglrx. Not yet finished.
    	* hw/kdrive/ephyr/ephyrhostglx.c,h: put here the actual
    	  Xlib code used to hit the host X server because Xlib stuff cannot be
    	  mixed with xserver internal code, otherwise compilation erros due to
    	  type clashes happen. So no Xlib type should be exported by the
    	  entrypoints defined here.

diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index cc9c910..5e33163 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -26,12 +26,19 @@ libxephyr_a_SOURCES =	\
 	ephyrdriext.c	\
 	ephyrdri.c	\
 	ephyrdri.h	\
+	ephyrglxext.c	\
+	ephyrglxext.h	\
+	ephyrhostglx.c	\
+	ephyrhostglx.h	\
 	os.c		\
 	hostx.h         \
 	ephyr.h		\
 	ephyrlog.h
 
-libxephyr_a_CFLAGS = @LIBDRM_CFLAGS@ @DRIPROTO_CFLAGS@
+libxephyr_a_CFLAGS = \
+ at LIBDRM_CFLAGS@ \
+-I$(top_srcdir) \
+ at DRIPROTO_CFLAGS@
 
 Xephyr_SOURCES = \
 	ephyrinit.c
diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c
index bed65e5..fc35ce2 100644
--- a/hw/kdrive/ephyr/XF86dri.c
+++ b/hw/kdrive/ephyr/XF86dri.c
@@ -158,10 +158,8 @@ Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
     return True;
 }
 
-Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
-    Display* dpy;
-    int screen;
-    Bool* isCapable;
+Bool
+XF86DRIQueryDirectRenderingCapable (Display *dpy, int screen, Bool *isCapable)
 {
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRIQueryDirectRenderingCapableReply rep;
@@ -176,10 +174,10 @@ Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
     req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
     req->screen = screen;
     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-	UnlockDisplay(dpy);
-	SyncHandle();
+        UnlockDisplay(dpy);
+        SyncHandle();
         TRACE("QueryDirectRenderingCapable... return False");
-	return False;
+        return False;
     }
     *isCapable = rep.isCapable;
     UnlockDisplay(dpy);
@@ -188,11 +186,10 @@ Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
     return True;
 }
 
-Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
-    Display* dpy;
-    int screen;
-    drm_handle_t * hSAREA;
-    char **busIdString;
+Bool
+XF86DRIOpenConnection (Display *dpy, int screen,
+                       drm_handle_t *hSAREA,
+                       char **busIdString)
 {
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRIOpenConnectionReply rep;
@@ -207,16 +204,16 @@ Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
     req->driReqType = X_XF86DRIOpenConnection;
     req->screen = screen;
     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-	UnlockDisplay(dpy);
-	SyncHandle();
+        UnlockDisplay(dpy);
+        SyncHandle();
         TRACE("OpenConnection... return False");
-	return False;
+        return False;
     }
 
     *hSAREA = rep.hSAREALow;
     if (sizeof(drm_handle_t) == 8) {
-       int shift = 32; /* var to prevent warning on next line */
-       *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
+        int shift = 32; /* var to prevent warning on next line */
+        *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
     }
 
     if (rep.length) {
@@ -227,7 +224,7 @@ Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
             TRACE("OpenConnection... return False");
             return False;
         }
-	_XReadPad(dpy, *busIdString, rep.busIdStringLength);
+        _XReadPad(dpy, *busIdString, rep.busIdStringLength);
     } else {
         *busIdString = NULL;
     }
@@ -546,16 +543,10 @@ Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
     return True;
 }
 
-Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer, 
-	fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
-    Display* dpy;
-    int screen;
-    drm_handle_t * hFrameBuffer;
-    int* fbOrigin;
-    int* fbSize;
-    int* fbStride;
-    int* devPrivateSize;
-    void** pDevPrivate;
+Bool
+XF86DRIGetDeviceInfo (Display *dpy, int screen, drm_handle_t *hFrameBuffer,
+                      int *fbOrigin, int *fbSize, int *fbStride,
+                      int *devPrivateSize, void **pDevPrivate)
 {
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRIGetDeviceInfoReply rep;
@@ -606,10 +597,8 @@ Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer,
     return True;
 }
 
-Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
-    Display* dpy;
-    int screen;
-    Drawable drawable;
+Bool
+XF86DRIOpenFullScreen(Display *dpy, int screen, Drawable drawable)
 {
     /* This function and the underlying X protocol are deprecated.
      */
@@ -619,10 +608,8 @@ Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
     return False;
 }
 
-Bool XF86DRICloseFullScreen(dpy, screen, drawable)
-    Display* dpy;
-    int screen;
-    Drawable drawable;
+Bool
+XF86DRICloseFullScreen(Display *dpy, int screen, Drawable drawable)
 {
     /* This function and the underlying X protocol are deprecated.
      */
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 330158a..b460b96 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -31,6 +31,8 @@
 #include "inputstr.h"
 #include "scrnintstr.h"
 #include "ephyrlog.h"
+#include "ephyrdri.h"
+#include "ephyrglxext.h"
 
 extern int KdTsPhyScreen;
 KdKeyboardInfo *ephyrKbd;
@@ -45,6 +47,11 @@ typedef struct _EphyrInputPrivate {
 
 Bool   EphyrWantGrayScale = 0;
 
+
+#ifdef XEPHYR_DRI
+extern void ephyrDRIExtensionInit(void) ;
+#endif
+
 Bool
 ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
 {
@@ -617,6 +624,7 @@ ephyrInitScreen (ScreenPtr pScreen)
 
 #ifdef XEPHYR_DRI
     ephyrDRIExtensionInit () ;
+    ephyrHijackGLXExtension () ;
 #endif
   return TRUE;
 }
diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
index 5201082..89d9ae7 100644
--- a/hw/kdrive/ephyr/ephyrdri.c
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -159,16 +159,18 @@ ephyrDRICreateDrawable (int a_screen,
                         drm_drawable_t *a_hw_drawable)
 {
     EPHYR_LOG ("enter\n") ;
-    return FALSE ;
+    EPHYR_LOG_ERROR ("not implemented yet\n") ;
     EPHYR_LOG ("leave\n") ;
+    return FALSE ;
 }
 
 Bool
 ephyrDRIDestroyDrawable (int a_screen, int a_drawable)
 {
     EPHYR_LOG ("enter\n") ;
-    return FALSE ;
+    EPHYR_LOG_ERROR ("not implemented yet\n") ;
     EPHYR_LOG ("leave\n") ;
+    return FALSE ;
 }
 
 Bool
@@ -188,8 +190,9 @@ ephyrDRIGetDrawableInfo (int a_screen,
                          drm_clip_rect_t **a_back_clip_rects)
 {
     EPHYR_LOG ("enter\n") ;
-    return FALSE ;
+    EPHYR_LOG_ERROR ("not implemented yet\n") ;
     EPHYR_LOG ("leave\n") ;
+    return FALSE ;
 }
 
 Bool
@@ -201,9 +204,16 @@ ephyrDRIGetDeviceInfo (int a_screen,
                        int *a_dev_private_size,
                        void **a_dev_private)
 {
+    Bool is_ok = FALSE ;
+    Display *dpy = hostx_get_display () ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
     EPHYR_LOG ("enter\n") ;
-    return FALSE ;
+    is_ok = XF86DRIGetDeviceInfo (dpy, a_screen, a_frame_buffer,
+                                  a_fb_origin, a_fb_size, a_fb_stride,
+                                  a_dev_private_size, a_dev_private) ;
     EPHYR_LOG ("leave\n") ;
+    return is_ok ;
 }
 #endif /*EPHYR_DRI*/
 
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index 437d8c4..ac68054 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -79,7 +79,7 @@ static void XF86DRIResetProc(ExtensionEntry* extEntry);
 
 static unsigned char DRIReqCode = 0;
 
-extern void XFree86DRIExtensionInit(void);
+extern void ephyrDRIExtensionInit(void);
 
 void
 ephyrDRIExtensionInit(void)
@@ -113,13 +113,13 @@ XF86DRIResetProc (
 }
 
 static int
-ProcXF86DRIQueryVersion(
-    register ClientPtr client
-)
+ProcXF86DRIQueryVersion (register ClientPtr client)
 {
     xXF86DRIQueryVersionReply rep;
     register int n;
 
+    EPHYR_LOG ("enter\n") ;
+
     REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
     rep.type = X_Reply;
     rep.length = 0;
@@ -135,18 +135,18 @@ ProcXF86DRIQueryVersion(
 	swapl(&rep.patchVersion, n);
     }
     WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
+    EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRIQueryDirectRenderingCapable(
-    register ClientPtr client
-)
+ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
 {
     xXF86DRIQueryDirectRenderingCapableReply	rep;
     Bool isCapable;
     register int n;
 
+    EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
     REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
     if (stuff->screen >= screenInfo.numScreens) {
@@ -171,20 +171,20 @@ ProcXF86DRIQueryDirectRenderingCapable(
     	swapl(&rep.length, n);
     }
 
-    WriteToClient(client, 
-	sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
+    WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
+    EPHYR_LOG ("leave\n") ;
+
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRIOpenConnection(
-    register ClientPtr client
-)
+ProcXF86DRIOpenConnection (register ClientPtr client)
 {
     xXF86DRIOpenConnectionReply rep;
     drm_handle_t			hSAREA;
     char*			busIdString;
 
+    EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRIOpenConnectionReq);
     REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
     if (stuff->screen >= screenInfo.numScreens) {
@@ -215,17 +215,17 @@ ProcXF86DRIOpenConnection(
 
     WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
     if (rep.busIdStringLength)
-	WriteToClient(client, rep.busIdStringLength, busIdString);
+        WriteToClient(client, rep.busIdStringLength, busIdString);
+    EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRIAuthConnection(
-    register ClientPtr client
-)
+ProcXF86DRIAuthConnection  (register ClientPtr client)
 {
     xXF86DRIAuthConnectionReply rep;
-    
+
+    EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRIAuthConnectionReq);
     REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
     if (stuff->screen >= screenInfo.numScreens) {
@@ -243,36 +243,36 @@ ProcXF86DRIAuthConnection(
         rep.authenticated = 0;
     }
     WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
+    EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRICloseConnection(
-    register ClientPtr client
-)
+ProcXF86DRICloseConnection (register ClientPtr client)
 {
+    EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRICloseConnectionReq);
     REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
     if (stuff->screen >= screenInfo.numScreens) {
-	client->errorValue = stuff->screen;
-	return BadValue;
+        client->errorValue = stuff->screen;
+        return BadValue;
     }
 
     /*
     DRICloseConnection( screenInfo.screens[stuff->screen]);
     */
 
+    EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRIGetClientDriverName(
-    register ClientPtr client
-)
+ProcXF86DRIGetClientDriverName (register ClientPtr client)
 {
     xXF86DRIGetClientDriverNameReply	rep;
     char* clientDriverName;
 
+    EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRIGetClientDriverNameReq);
     REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
     if (stuff->screen >= screenInfo.numScreens) {
@@ -301,19 +301,19 @@ ProcXF86DRIGetClientDriverName(
 	WriteToClient(client, 
                       rep.clientDriverNameLength, 
                       clientDriverName);
+    EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRICreateContext(
-    register ClientPtr client
-)
+ProcXF86DRICreateContext (register ClientPtr client)
 {
     xXF86DRICreateContextReply	rep;
     ScreenPtr pScreen;
     VisualPtr visual;
     int i;
 
+    EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRICreateContextReq);
     REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
     if (stuff->screen >= screenInfo.numScreens) {
@@ -347,101 +347,104 @@ ProcXF86DRICreateContext(
     */
 
     WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
+    EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRIDestroyContext(
-    register ClientPtr client
-)
+ProcXF86DRIDestroyContext (register ClientPtr client)
 {
+    EPHYR_LOG ("enter\n") ;
+
     REQUEST(xXF86DRIDestroyContextReq);
     REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
     if (stuff->screen >= screenInfo.numScreens) {
-	client->errorValue = stuff->screen;
-	return BadValue;
+        client->errorValue = stuff->screen;
+        return BadValue;
     }
 
     /*
-    if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
-			    stuff->context)) {
-	return BadValue;
-    }
-    */
+       if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
+       stuff->context)) {
+       return BadValue;
+       }
+   */
 
+    EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRICreateDrawable(
-    ClientPtr client
-)
+ProcXF86DRICreateDrawable (ClientPtr client)
 {
     xXF86DRICreateDrawableReply	rep;
     DrawablePtr pDrawable;
     int rc;
 
+    EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRICreateDrawableReq);
     REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
     if (stuff->screen >= screenInfo.numScreens) {
-	client->errorValue = stuff->screen;
-	return BadValue;
+        client->errorValue = stuff->screen;
+        return BadValue;
     }
 
     rep.type = X_Reply;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
 
-    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
-			   DixReadAccess);
+    rc = dixLookupDrawable (&pDrawable, stuff->drawable, client, 0,
+                            DixReadAccess);
     if (rc != Success)
-	return rc;
+        return rc;
 
     /*TODO: this cannot work. We must properly
      * do the mapping between the xephyr drawable and
      * the host drawable
      */
     if (!ephyrDRICreateDrawable (stuff->screen,
-                                 0/*should be host drawableID*/,
-                                 (drm_drawable_t *)&rep.hHWDrawable)) {
+                0/*should be host drawableID*/,
+                (drm_drawable_t *)&rep.hHWDrawable)) {
         return BadValue;
     }
 
     WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
+    EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRIDestroyDrawable(
-    register ClientPtr client
-)
+ProcXF86DRIDestroyDrawable (register ClientPtr client)
 {
     REQUEST(xXF86DRIDestroyDrawableReq);
     DrawablePtr pDrawable;
     REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
     int rc;
 
+    EPHYR_LOG ("enter\n") ;
     if (stuff->screen >= screenInfo.numScreens) {
-	client->errorValue = stuff->screen;
-	return BadValue;
+        client->errorValue = stuff->screen;
+        return BadValue;
     }
 
-    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
-			   DixReadAccess);
+    rc = dixLookupDrawable(&pDrawable,
+                           stuff->drawable,
+                           client,
+                           0,
+                           DixReadAccess);
     if (rc != Success)
-	return rc;
+        return rc;
 
     if (!ephyrDRIDestroyDrawable(stuff->screen,
                                  0/*should be drawable in host x*/)) {
-	return BadValue;
+        return BadValue;
     }
+    EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRIGetDrawableInfo(
-    register ClientPtr client
-)
+ProcXF86DRIGetDrawableInfo (register ClientPtr client)
 {
     xXF86DRIGetDrawableInfoReply	rep;
     DrawablePtr pDrawable;
@@ -450,11 +453,12 @@ ProcXF86DRIGetDrawableInfo(
     drm_clip_rect_t * pBackClipRects;
     int backX, backY, rc;
 
+    EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRIGetDrawableInfoReq);
     REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
     if (stuff->screen >= screenInfo.numScreens) {
-	client->errorValue = stuff->screen;
-	return BadValue;
+        client->errorValue = stuff->screen;
+        return BadValue;
     }
 
     rep.type = X_Reply;
@@ -466,25 +470,25 @@ ProcXF86DRIGetDrawableInfo(
      * between xephyr drawable and the host drawable
      */
     rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
-			   DixReadAccess);
+            DixReadAccess);
     if (rc != Success)
-	return rc;
+        return rc;
 
     if (!ephyrDRIGetDrawableInfo (stuff->screen,
-                                  0 /*should be the drawable in hostx*/,
-                                  (unsigned int*)&rep.drawableTableIndex,
-                                  (unsigned int*)&rep.drawableTableStamp,
-                                  (int*)&X,
-                                  (int*)&Y,
-                                  (int*)&W,
-                                  (int*)&H,
-                                  (int*)&rep.numClipRects,
-                                  &pClipRects,
-                                  &backX,
-                                  &backY,
-                                  (int*)&rep.numBackClipRects,
-                                  &pBackClipRects)) {
-	return BadValue;
+                0 /*should be the drawable in hostx*/,
+                (unsigned int*)&rep.drawableTableIndex,
+                (unsigned int*)&rep.drawableTableStamp,
+                (int*)&X,
+                (int*)&Y,
+                (int*)&W,
+                (int*)&H,
+                (int*)&rep.numClipRects,
+                &pClipRects,
+                &backX,
+                &backY,
+                (int*)&rep.numBackClipRects,
+                &pBackClipRects)) {
+        return BadValue;
     }
 
     rep.drawableX = X;
@@ -492,78 +496,78 @@ ProcXF86DRIGetDrawableInfo(
     rep.drawableWidth = W;
     rep.drawableHeight = H;
     rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - 
-		  SIZEOF(xGenericReply));
+                  SIZEOF(xGenericReply));
 
     rep.backX = backX;
     rep.backY = backY;
-        
+
     if (rep.numBackClipRects) 
-       rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;    
+        rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;    
 
     pClippedRects = pClipRects;
 
     if (rep.numClipRects) {
-       /* Clip cliprects to screen dimensions (redirected windows) */
-       pClippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t));
-
-       if (pClippedRects) {
-	    ScreenPtr pScreen = screenInfo.screens[stuff->screen];
-	    int i, j;
-
-	    for (i = 0, j = 0; i < rep.numClipRects; i++) {
-		pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
-		pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
-		pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
-		pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
-
-		if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
-		    pClippedRects[j].y1 < pClippedRects[j].y2) {
-		    j++;
-		}
-	    }
-
-	    rep.numClipRects = j;
-       } else {
-	    rep.numClipRects = 0;
-       }
+        /* Clip cliprects to screen dimensions (redirected windows) */
+        pClippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t));
+
+        if (pClippedRects) {
+            ScreenPtr pScreen = screenInfo.screens[stuff->screen];
+            int i, j;
+
+            for (i = 0, j = 0; i < rep.numClipRects; i++) {
+                pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
+                pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
+                pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
+                pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
+
+                if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
+                        pClippedRects[j].y1 < pClippedRects[j].y2) {
+                    j++;
+                }
+            }
 
-       rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+            rep.numClipRects = j;
+        } else {
+            rep.numClipRects = 0;
+        }
+
+        rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
     }
-    
+
     rep.length = ((rep.length + 3) & ~3) >> 2;
 
     WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
 
     if (rep.numClipRects) {
-	WriteToClient(client,  
-		      sizeof(drm_clip_rect_t) * rep.numClipRects,
-		      (char *)pClippedRects);
-	xfree(pClippedRects);
+        WriteToClient(client,  
+                sizeof(drm_clip_rect_t) * rep.numClipRects,
+                (char *)pClippedRects);
+        xfree(pClippedRects);
     }
 
     if (rep.numBackClipRects) {
-       WriteToClient(client, 
-		     sizeof(drm_clip_rect_t) * rep.numBackClipRects,
-		     (char *)pBackClipRects);
+        WriteToClient(client, 
+                sizeof(drm_clip_rect_t) * rep.numBackClipRects,
+                (char *)pBackClipRects);
     }
+    EPHYR_LOG ("leave\n") ;
 
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRIGetDeviceInfo(
-    register ClientPtr client
-)
+ProcXF86DRIGetDeviceInfo (register ClientPtr client)
 {
     xXF86DRIGetDeviceInfoReply	rep;
     drm_handle_t hFrameBuffer;
     void *pDevPrivate;
 
+    EPHYR_LOG ("enter\n") ;
     REQUEST(xXF86DRIGetDeviceInfoReq);
     REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
     if (stuff->screen >= screenInfo.numScreens) {
-	client->errorValue = stuff->screen;
-	return BadValue;
+        client->errorValue = stuff->screen;
+        return BadValue;
     }
 
     rep.type = X_Reply;
@@ -571,12 +575,12 @@ ProcXF86DRIGetDeviceInfo(
     rep.sequenceNumber = client->sequence;
 
     if (!ephyrDRIGetDeviceInfo (stuff->screen,
-                                &hFrameBuffer,
-                                (int*)&rep.framebufferOrigin,
-                                (int*)&rep.framebufferSize,
-                                (int*)&rep.framebufferStride,
-                                (int*)&rep.devPrivateSize,
-                                &pDevPrivate)) {
+                &hFrameBuffer,
+                (int*)&rep.framebufferOrigin,
+                (int*)&rep.framebufferSize,
+                (int*)&rep.framebufferStride,
+                (int*)&rep.devPrivateSize,
+                &pDevPrivate)) {
         return BadValue;
     }
 
@@ -590,30 +594,34 @@ ProcXF86DRIGetDeviceInfo(
     rep.length = 0;
     if (rep.devPrivateSize) {
         rep.length = (SIZEOF(xXF86DRIGetDeviceInfoReply) - 
-                      SIZEOF(xGenericReply) +
-                      ((rep.devPrivateSize + 3) & ~3)) >> 2;
+                SIZEOF(xGenericReply) +
+                ((rep.devPrivateSize + 3) & ~3)) >> 2;
     }
 
     WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
     if (rep.length) {
         WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
     }
+    EPHYR_LOG ("leave\n") ;
     return (client->noClientException);
 }
 
 static int
-ProcXF86DRIDispatch (
-    register ClientPtr	client
-)
+ProcXF86DRIDispatch (register ClientPtr	client)
 {
     REQUEST(xReq);
+    EPHYR_LOG ("enter\n") ;
 
     switch (stuff->data)
     {
-    case X_XF86DRIQueryVersion:
-        return ProcXF86DRIQueryVersion(client);
-    case X_XF86DRIQueryDirectRenderingCapable:
-        return ProcXF86DRIQueryDirectRenderingCapable(client);
+        case X_XF86DRIQueryVersion: {
+                EPHYR_LOG ("leave\n") ;
+                return ProcXF86DRIQueryVersion(client);
+        }
+        case X_XF86DRIQueryDirectRenderingCapable: {
+                EPHYR_LOG ("leave\n") ;
+                return ProcXF86DRIQueryDirectRenderingCapable(client);
+        }
     }
 
     if (!LocalClient(client))
@@ -621,36 +629,56 @@ ProcXF86DRIDispatch (
 
     switch (stuff->data)
     {
-    case X_XF86DRIOpenConnection:
-        return ProcXF86DRIOpenConnection(client);
-    case X_XF86DRICloseConnection:
-        return ProcXF86DRICloseConnection(client);
-    case X_XF86DRIGetClientDriverName:
-        return ProcXF86DRIGetClientDriverName(client);
-    case X_XF86DRICreateContext:
-        return ProcXF86DRICreateContext(client);
-    case X_XF86DRIDestroyContext:
-        return ProcXF86DRIDestroyContext(client);
-    case X_XF86DRICreateDrawable:
-        return ProcXF86DRICreateDrawable(client);
-    case X_XF86DRIDestroyDrawable:
-        return ProcXF86DRIDestroyDrawable(client);
-    case X_XF86DRIGetDrawableInfo:
-        return ProcXF86DRIGetDrawableInfo(client);
-    case X_XF86DRIGetDeviceInfo:
-        return ProcXF86DRIGetDeviceInfo(client);
-    case X_XF86DRIAuthConnection:
-        return ProcXF86DRIAuthConnection(client);
-    /* {Open,Close}FullScreen are deprecated now */
-    default:
-        return BadRequest;
+        case X_XF86DRIOpenConnection: {
+            EPHYR_LOG ("leave\n") ;
+            return ProcXF86DRIOpenConnection(client);
+        }
+        case X_XF86DRICloseConnection: {
+            EPHYR_LOG ("leave\n") ;
+            return ProcXF86DRICloseConnection(client);
+        }
+        case X_XF86DRIGetClientDriverName: {
+            EPHYR_LOG ("leave\n") ;
+            return ProcXF86DRIGetClientDriverName(client);
+        }
+        case X_XF86DRICreateContext: {
+            EPHYR_LOG ("leave\n") ;
+            return ProcXF86DRICreateContext(client);
+        }
+        case X_XF86DRIDestroyContext: {
+            EPHYR_LOG ("leave\n") ;
+            return ProcXF86DRIDestroyContext(client);
+        }
+        case X_XF86DRICreateDrawable: {
+            EPHYR_LOG ("leave\n") ;
+            return ProcXF86DRICreateDrawable(client);
+        }
+        case X_XF86DRIDestroyDrawable: {
+            EPHYR_LOG ("leave\n") ;
+            return ProcXF86DRIDestroyDrawable(client);
+        }
+        case X_XF86DRIGetDrawableInfo: {
+            EPHYR_LOG ("leave\n") ;
+            return ProcXF86DRIGetDrawableInfo(client);
+        }
+        case X_XF86DRIGetDeviceInfo: {
+            EPHYR_LOG ("leave\n") ;
+            return ProcXF86DRIGetDeviceInfo(client);
+        }
+        case X_XF86DRIAuthConnection: {
+            EPHYR_LOG ("leave\n") ;
+            return ProcXF86DRIAuthConnection(client);
+        }
+            /* {Open,Close}FullScreen are deprecated now */
+        default: {
+            EPHYR_LOG ("leave\n") ;
+            return BadRequest;
+        }
     }
 }
 
 static int
-SProcXF86DRIQueryVersion(
-    register ClientPtr	client
-)
+SProcXF86DRIQueryVersion (register ClientPtr	client)
 {
     register int n;
     REQUEST(xXF86DRIQueryVersionReq);
@@ -659,9 +687,7 @@ SProcXF86DRIQueryVersion(
 }
 
 static int
-SProcXF86DRIQueryDirectRenderingCapable(
-    register ClientPtr client
-)
+SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
 {
     register int n;
     REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
@@ -671,24 +697,29 @@ SProcXF86DRIQueryDirectRenderingCapable(
 }
 
 static int
-SProcXF86DRIDispatch (
-    register ClientPtr	client
-)
+SProcXF86DRIDispatch (register ClientPtr client)
 {
     REQUEST(xReq);
 
+    EPHYR_LOG ("enter\n") ;
     /*
      * Only local clients are allowed DRI access, but remote clients still need
      * these requests to find out cleanly.
      */
     switch (stuff->data)
     {
-    case X_XF86DRIQueryVersion:
-	return SProcXF86DRIQueryVersion(client);
-    case X_XF86DRIQueryDirectRenderingCapable:
-	return SProcXF86DRIQueryDirectRenderingCapable(client);
-    default:
-	return DRIErrorBase + XF86DRIClientNotLocal;
+        case X_XF86DRIQueryVersion: {
+            EPHYR_LOG ("leave\n") ;
+            return SProcXF86DRIQueryVersion(client);
+        }
+        case X_XF86DRIQueryDirectRenderingCapable: {
+            EPHYR_LOG ("leave\n") ;
+            return SProcXF86DRIQueryDirectRenderingCapable(client);
+        }
+        default: {
+            EPHYR_LOG ("leave\n") ;
+            return DRIErrorBase + XF86DRIClientNotLocal;
+        }
     }
 }
 
diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
new file mode 100644
index 0000000..d0380f1
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrglxext.c
@@ -0,0 +1,291 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include "extnsionst.h"
+#include "ephyrglxext.h"
+#include "ephyrhostglx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include <GL/glxproto.h>
+#include "GL/glx/glxserver.h"
+#include "GL/glx/indirect_table.h"
+#include "GL/glx/unpack.h"
+
+
+#ifdef XEPHYR_DRI
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+
+int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ;
+
+Bool
+ephyrHijackGLXExtension (void)
+{
+    const void *(*dispatch_functions)[2];
+
+    EPHYR_LOG ("Got GLX extension\n") ;
+    if (!Single_dispatch_info.dispatch_functions) {
+        EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ;
+        return FALSE ;
+    }
+    dispatch_functions = Single_dispatch_info.dispatch_functions ;
+    EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ;
+
+    dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ;
+    dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ;
+
+    dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ;
+    dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ;
+
+    dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ;
+    dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
+
+    dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ;
+    dispatch_functions[X_GLXQueryServerString][1] = ephyrGLXQueryServerStringSwap ;
+
+    EPHYR_LOG ("hijacked mesa GL to forward requests to host X\n") ;
+
+    return TRUE ;
+}
+
+/*********************
+ * implementation of
+ * hijacked GLX entry
+ * points
+ ********************/
+
+int
+ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    ClientPtr client = a_cl->client;
+    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
+    xGLXQueryVersionReply reply;
+    int major, minor;
+    int res = BadImplementation ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    major = req->majorVersion ;
+    minor = req->minorVersion ;
+
+    if (!ephyrHostGLXQueryVersion (&major, &minor)) {
+        EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ;
+        goto out ;
+    }
+    reply.majorVersion = major ;
+    reply.minorVersion = minor ;
+    reply.length = 0 ;
+    reply.type = X_Reply ;
+    reply.sequenceNumber = client->sequence ;
+
+    if (client->swapped) {
+        __glXSwapQueryVersionReply(client, &reply);
+    } else {
+        WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
+    }
+
+    res = Success ;
+out:
+    EPHYR_LOG ("leave\n") ;
+    return res;
+}
+
+int
+ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
+    __GLX_DECLARE_SWAP_VARIABLES;
+
+    __GLX_SWAP_SHORT (&req->length);
+    __GLX_SWAP_INT (&req->majorVersion);
+    __GLX_SWAP_INT (&req->minorVersion);
+    return ephyrGLXQueryVersion (a_cl, a_pc) ;
+}
+
+static int
+ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
+    ClientPtr client = a_cl->client;
+    xGLXGetVisualConfigsReply reply;
+    int32_t *props_buf=NULL, num_visuals=0,
+            num_props=0, res=BadImplementation, i=0,
+            props_per_visual_size=0,
+            props_buf_size=0;
+    __GLX_DECLARE_SWAP_VARIABLES;
+    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+    EPHYR_LOG ("enter\n") ;
+
+    if (!ephyrHostGLXGetVisualConfigs (req->screen,
+                                       &num_visuals,
+                                       &num_props,
+                                       &props_buf_size,
+                                       &props_buf)) {
+        EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
+        goto out ;
+    }
+    EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
+
+    reply.numVisuals = num_visuals;
+    reply.numProps = num_props;
+    reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2;
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+
+    if (a_do_swap) {
+        __GLX_SWAP_SHORT(&reply.sequenceNumber);
+        __GLX_SWAP_INT(&reply.length);
+        __GLX_SWAP_INT(&reply.numVisuals);
+        __GLX_SWAP_INT(&reply.numProps);
+        __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
+    }
+    WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
+    props_per_visual_size = props_buf_size/num_visuals ;
+    for (i=0; i < num_visuals; i++) {
+        WriteToClient (client,
+                       props_per_visual_size,
+                       (char*)props_buf +i*props_per_visual_size);
+    }
+    res = Success ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    if (props_buf) {
+        xfree (props_buf) ;
+        props_buf = NULL ;
+    }
+    return res ;
+}
+
+int
+ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ;
+}
+
+
+int
+ephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    int res=BadImplementation ;
+    xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
+
+    EPHYR_LOG ("enter\n") ;
+    if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) {
+        EPHYR_LOG_ERROR ("failed to send client info to host\n") ;
+        goto out ;
+    }
+    res = Success ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return res ;
+}
+
+int
+ephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc;
+    __GLX_DECLARE_SWAP_VARIABLES;
+
+    __GLX_SWAP_SHORT (&req->length);
+    __GLX_SWAP_INT (&req->major);
+    __GLX_SWAP_INT (&req->minor);
+    __GLX_SWAP_INT (&req->numbytes);
+
+    return ephyrGLXClientInfo (a_cl, a_pc) ;
+}
+
+int
+ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    int res = BadImplementation ;
+    ClientPtr client = a_cl->client;
+    xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
+    xGLXQueryServerStringReply reply;
+    char *server_string=NULL ;
+    int length=0 ;
+
+    EPHYR_LOG ("enter\n") ;
+    if (!ephyrHostGLXGetStringFromServer (req->screen, req->name, &server_string)) {
+        EPHYR_LOG_ERROR ("failed to query string from host\n") ;
+        goto out ;
+    }
+    length= strlen (server_string) + 1;
+    reply.type = X_Reply ;
+    reply.sequenceNumber = client->sequence ;
+    reply.length = __GLX_PAD (length) >> 2 ;
+    reply.n = length ;
+
+    WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply);
+    WriteToClient(client, (int)length, server_string);
+
+    res = Success ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    if (server_string) {
+        xfree (server_string) ;
+        server_string = NULL;
+    }
+    return res ;
+}
+
+int
+ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+    EPHYR_LOG_ERROR ("not yet implemented\n") ;
+    return BadImplementation ;
+}
+
+#endif /*XEPHYR_DRI*/
+
diff --git a/hw/kdrive/ephyr/ephyrglxext.h b/hw/kdrive/ephyr/ephyrglxext.h
new file mode 100644
index 0000000..22ea605
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrglxext.h
@@ -0,0 +1,35 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifndef __EPHYR_GLXEXT_H__
+#define __EPHYR_GLXEXT_H__
+
+#include <X11/Xdefs.h>
+Bool ephyrHijackGLXExtension (void) ;
+
+#endif /*__EPHYR_GLXEXT_H__*/
+
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
new file mode 100644
index 0000000..693fbc1
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -0,0 +1,350 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * a lots of the content of this file has been adapted from the mesa source
+ * code.
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include <X11/Xlibint.h>
+#include <GL/glx.h>
+#include <GL/internal/glcore.h>
+#include <GL/glxproto.h>
+#include <GL/glxint.h>
+#include "hostx.h"
+#include "ephyrhostglx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+
+#ifdef XEPHYR_DRI
+
+Bool
+ephyrHostGLXGetMajorOpcode (int *a_opcode)
+{
+    Bool is_ok=FALSE ;
+    Display *dpy=hostx_get_display () ;
+    static int opcode ;
+    int first_event_return=0, first_error_return=0;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+    EPHYR_LOG ("enter\n") ;
+    if (!opcode) {
+        if (!XQueryExtension (dpy, GLX_EXTENSION_NAME, &opcode,
+                              &first_event_return, &first_error_return)) {
+            EPHYR_LOG_ERROR ("XQueryExtension() failed\n") ;
+            goto out ;
+        }
+    }
+    *a_opcode = opcode ;
+    is_ok = TRUE ;
+out:
+    EPHYR_LOG ("release\n") ;
+    return is_ok ;
+}
+
+Bool
+ephyrHostGLXQueryVersion (int *a_major, int *a_minor)
+{
+    Bool is_ok = FALSE ;
+    Display *dpy = hostx_get_display () ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ;
+    EPHYR_LOG ("enter\n") ;
+
+    if (!glXQueryVersion (dpy, a_major, a_minor)) {
+        EPHYR_LOG_ERROR ("glxQueryVersion() failed\n") ;
+        goto out ;
+    }
+
+    is_ok = TRUE ;
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+/**
+ * GLX protocol structure for the ficticious "GXLGenericGetString" request.
+ * 
+ * This is a non-existant protocol packet.  It just so happens that all of
+ * the real protocol packets used to request a string from the server have
+ * an identical binary layout.  The only difference between them is the
+ * meaning of the \c for_whom field and the value of the \c glxCode.
+ */
+typedef struct GLXGenericGetString {
+    CARD8 reqType;
+    CARD8 glxCode;
+    CARD16 length B16;
+    CARD32 for_whom B32;
+    CARD32 name B32;
+} xGLXGenericGetStringReq;
+
+/* These defines are only needed to make the GetReq macro happy.
+ */
+#define sz_xGLXGenericGetStringReq 12
+#define X_GLXGenericGetString 0
+
+Bool
+ephyrHostGLXGetStringFromServer (int a_screen_number,
+                                 int a_string_name,
+                                 char **a_string)
+{
+    Display *dpy = hostx_get_display () ;
+    xGLXGenericGetStringReq *req=NULL;
+    xGLXSingleReply reply;
+    int length=0, numbytes=0, major_opcode=0;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy && a_string, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+        EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+        return FALSE ;
+    }
+    EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
+
+    LockDisplay (dpy);
+
+    /* All of the GLX protocol requests for getting a string from the server
+     * look the same.  The exact meaning of the a_for_whom field is usually
+     * either the screen number (for glXQueryServerString) or the context tag
+     * (for GLXSingle).
+     */
+    GetReq (GLXGenericGetString, req);
+    req->reqType = major_opcode;
+    req->glxCode = X_GLXQueryServerString;
+    req->for_whom = a_screen_number;
+    req->name = a_string_name;
+
+    _XReply (dpy, (xReply *)&reply, 0, False);
+
+    length = reply.length * 4;
+    numbytes = reply.size;
+
+    *a_string = (char *) Xmalloc( numbytes );
+    if (*a_string != NULL) {
+        if (_XRead (dpy, *a_string, numbytes)) {
+            EPHYR_LOG_ERROR ("read failed\n") ;
+        }
+        length -= numbytes;
+    }
+
+    _XEatData (dpy, length) ;
+
+    UnlockDisplay (dpy);
+    SyncHandle ();
+
+    EPHYR_LOG ("leave\n") ;
+    return TRUE ;
+}
+
+Bool
+ephyrHostGLXGetVisualConfigs (int32_t a_screen,
+                              int32_t *a_num_visuals,
+                              int32_t *a_num_props,
+                              int32_t *a_props_buf_size,
+                              int32_t **a_props_buf)
+{
+    Bool is_ok = FALSE ;
+    Display *dpy = hostx_get_display () ;
+    xGLXGetVisualConfigsReq *req;
+    xGLXGetFBConfigsReq *fb_req;
+    xGLXVendorPrivateWithReplyReq *vpreq;
+    xGLXGetFBConfigsSGIXReq *sgi_req;
+    xGLXGetVisualConfigsReply reply;
+    unsigned supported_request=0;
+    char *server_glx_version=NULL,
+         *server_glx_extensions=NULL ;
+    int j=0,
+        screens=0,
+        major_opcode=0,
+        num_props=0,
+        num_visuals=0,
+        props_buf_size=0,
+        props_per_visual_size=0;
+    int32_t *props_buf=NULL;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+    screens = ScreenCount (dpy);
+    if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+        EPHYR_LOG_ERROR ("failed to get opcode\n") ;
+        goto out ;
+    }
+    if (!ephyrHostGLXGetStringFromServer (0, GLX_VERSION,
+                                          &server_glx_version)
+        || !server_glx_version) {
+        EPHYR_LOG_ERROR ("failed to get glx version from server\n") ;
+        goto out ;
+    }
+
+    if (atof (server_glx_version) >= 1.3 ) {
+        supported_request = 1;
+    }
+
+    if (!ephyrHostGLXGetStringFromServer (a_screen, GLX_EXTENSIONS,
+                                          &server_glx_extensions)) {
+        EPHYR_LOG_ERROR ("failed to get glx extensions from server for screen: %d\n",
+                         a_screen) ;
+        goto out ;
+    }
+    if (supported_request != 1) {
+        if (server_glx_extensions
+            && strstr (server_glx_extensions, "GLX_SGIX_fbconfig" ) != NULL ) {
+            supported_request = 2;
+        } else {
+            supported_request = 3;
+        }
+    }
+
+    LockDisplay(dpy);
+    switch (supported_request) {
+        case 1:
+        GetReq(GLXGetFBConfigs,fb_req);
+        fb_req->reqType = major_opcode;
+        fb_req->glxCode = X_GLXGetFBConfigs;
+        fb_req->screen = a_screen;
+        break;
+
+        case 2:
+        GetReqExtra(GLXVendorPrivateWithReply,
+                sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
+        sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
+        sgi_req->reqType = major_opcode;
+        sgi_req->glxCode = X_GLXVendorPrivateWithReply;
+        sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
+        sgi_req->screen = a_screen;
+        break;
+
+        case 3:
+        GetReq(GLXGetVisualConfigs,req);
+        req->reqType = major_opcode;
+        req->glxCode = X_GLXGetVisualConfigs;
+        req->screen = a_screen;
+        break;
+    }
+
+    if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
+        EPHYR_LOG_ERROR ("unknown error\n") ;
+        UnlockDisplay(dpy);
+        goto out ;
+    }
+   if (!reply.numVisuals) {
+        EPHYR_LOG_ERROR ("screen does not support GL rendering\n") ;
+        UnlockDisplay(dpy);
+        goto out ;
+    }
+   num_visuals = reply.numVisuals ;
+
+    /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
+     * FIXME: FBconfigs? 
+     */
+    /* Check number of properties */
+    num_props = reply.numProps;
+    if ((num_props < __GLX_MIN_CONFIG_PROPS) ||
+        (num_props > __GLX_MAX_CONFIG_PROPS)) {
+        /* Huh?  Not in protocol defined limits.  Punt */
+        EPHYR_LOG_ERROR ("got a bad reply to request\n") ;
+        UnlockDisplay(dpy);
+        goto out ;
+    }
+
+    if (supported_request != 3) {
+        num_props *= 2;
+    }
+    props_per_visual_size = num_props * __GLX_SIZE_INT32;
+    props_buf_size = props_per_visual_size * reply.numVisuals;
+    props_buf = malloc (props_buf_size) ;
+    for (j = 0; j < reply.numVisuals; j++) {
+        if (_XRead (dpy,
+                    (char*)props_buf + j*props_per_visual_size,
+                    props_per_visual_size) != Success) {
+            EPHYR_LOG_ERROR ("read failed\n") ;
+        }
+    }
+    UnlockDisplay(dpy);
+
+    *a_num_visuals = num_visuals ;
+    *a_num_props = num_props ;
+    *a_props_buf_size = props_buf_size ;
+    *a_props_buf = props_buf ;
+    is_ok = TRUE ;
+
+out:
+    if (server_glx_version) {
+        XFree (server_glx_version) ;
+        server_glx_version = NULL ;
+    }
+    if (server_glx_extensions) {
+        XFree (server_glx_extensions) ;
+        server_glx_extensions = NULL ;
+    }
+    SyncHandle () ;
+    return is_ok;
+}
+
+Bool
+ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
+                            const char* a_extension_list)
+{
+    Bool is_ok = FALSE ;
+    Display *dpy = hostx_get_display () ;
+    xGLXClientInfoReq *req;
+    int size;
+    int32_t major_opcode=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy && a_extension_list, FALSE) ;
+
+    if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+        EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+        goto out ;
+    }
+
+    LockDisplay (dpy);
+
+    GetReq (GLXClientInfo,req);
+    req->reqType = major_opcode;
+    req->glxCode = X_GLXClientInfo;
+    req->major = a_major;
+    req->minor = a_minor;
+
+    size = strlen (a_extension_list) + 1;
+    req->length += (size + 3) >> 2;
+    req->numbytes = size;
+    Data (dpy, a_extension_list, size);
+
+    is_ok=TRUE ;
+
+out:
+    UnlockDisplay(dpy);
+    SyncHandle();
+    return is_ok ;
+}
+
+#endif /*XEPHYR_DRI*/
+
diff --git a/hw/kdrive/ephyr/ephyrhostglx.h b/hw/kdrive/ephyr/ephyrhostglx.h
new file mode 100644
index 0000000..7a158f3
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostglx.h
@@ -0,0 +1,47 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifndef __EPHYRHOSTGLX_H__
+#define __EPHYRHOSTGLX_H__
+
+Bool ephyrHostGLXQueryVersion (int *a_maj, int *a_min) ;
+Bool ephyrHostGLXGetStringFromServer (int a_screen_number,
+                                      int a_string_name,
+                                      char **a_string) ;
+Bool ephyrHostGLXGetVisualConfigs (int a_screen,
+                                   int32_t *a_num_visuals,
+                                   int32_t *a_num_props,
+                                   int32_t *a_props_buf_size,
+                                   int32_t **a_props_buf) ;
+
+Bool ephyrHostGLXGetMajorOpcode (int32_t *a_opcode) ;
+
+Bool ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
+                                 const char* a_extension_list) ;
+
+#endif /*__EPHYRHOSTGLX_H__*/
+
commit 0b8545144975bf7ed43c2564d01c697144eb1244
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Thu Aug 16 17:30:13 2007 +0200

    Implement ReputImage and StopVideo
    
    	* hw/kdrive/ephyr/ephyrhostvideo.c/h:
    	  (ephyrHostXVStopVideo): add this entry point.
    	* hw/kdrive/ephyr/ephyrvideo.c:
    	  Basically add ReputImage and StopVideo implementations.
    	  Now, when other windows obscur the video window, the reclipping
    	  seems to be well handled using StopVideo and ReputImage.
    	  To do this, I was obliged to save the frame in PutImage, so
    	  that I could resend it un ReputImage.

diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index 85fc7bd..6509274 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -976,3 +976,26 @@ out:
     return is_ok ;
 }
 
+Bool
+ephyrHostXVStopVideo (int a_port_id)
+{
+    int ret=0 ;
+    Bool is_ok=FALSE ;
+    Display *dpy = hostx_get_display () ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    ret = XvStopVideo (dpy, a_port_id, hostx_get_window ()) ;
+    if (ret != Success) {
+        EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
+        goto out ;
+    }
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
index 661792b..64b224f 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.h
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -223,5 +223,11 @@ Bool ephyrHostXVPutStill (int a_port_id,
 Bool ephyrHostXVGetStill (int a_port_id,
                           int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
                           int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
+
+/*
+ * StopVideo
+ */
+Bool ephyrHostXVStopVideo (int a_port_id) ;
+
 #endif /*__EPHYRHOSTVIDEO_H__*/
 
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 3c28f0d..eea426a 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -49,6 +49,12 @@ struct _EphyrPortPriv {
     int port_number ;
     KdVideoAdaptorPtr current_adaptor ;
     EphyrXVPriv *xv_priv;
+    unsigned char *image_buf ;
+    int image_buf_size ;
+    int image_id ;
+    int drw_x, drw_y, drw_w, drw_h ;
+    int src_x, src_y, src_w, src_h ;
+    int image_width, image_height ;
 };
 typedef struct _EphyrPortPriv EphyrPortPriv ;
 
@@ -73,6 +79,16 @@ static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
                                          int a_attr_value,
                                          Bool *a_is_valid) ;
 
+static Bool ephyrXVPrivGetImageBufSize (int a_port_id,
+                                        int a_image_id,
+                                        unsigned short a_width,
+                                        unsigned short a_height,
+                                        int *a_size) ;
+
+static Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
+                                            const unsigned char *a_image,
+                                            int a_image_len) ;
+
 static void ephyrStopVideo (KdScreenInfo *a_info,
                             pointer a_xv_priv,
                             Bool a_exit);
@@ -115,6 +131,13 @@ static int ephyrPutImage (KdScreenInfo *a_info,
                           RegionPtr a_clipping_region,
                           pointer a_port_priv);
 
+static int ephyrReputImage (KdScreenInfo *a_info,
+                            DrawablePtr a_drawable,
+                            short a_drw_x,
+                            short a_drw_y,
+                            RegionPtr a_clipping_region,
+                            pointer a_port_priv) ;
+
 static int ephyrPutVideo (KdScreenInfo *a_info,
                           DrawablePtr a_drawable,
                           short a_vid_x, short a_vid_y,
@@ -233,6 +256,8 @@ ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
     return TRUE ;
 }
 
+/*
+ Not used yed.
 static Bool
 ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
 {
@@ -259,6 +284,7 @@ out:
     }
     return is_ok ;
 }
+*/
 
 /**************
  *</helpers>
@@ -553,6 +579,7 @@ ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
     EPHYR_LOG ("enter\n") ;
 
     for (i=0; i < a_this->num_adaptors; i++) {
+        a_this->adaptors[i].ReputImage = ephyrReputImage ;
         a_this->adaptors[i].StopVideo = ephyrStopVideo ;
         a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
         a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
@@ -569,36 +596,41 @@ ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
         if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
             EPHYR_LOG_ERROR ("error\n") ;
         }
-        if (has_it)
+        if (has_it) {
             a_this->adaptors[i].PutImage = ephyrPutImage;
+        }
 
         has_it = FALSE ;
         if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
             EPHYR_LOG_ERROR ("error\n") ;
         }
-        if (has_it)
+        if (has_it) {
             a_this->adaptors[i].PutVideo = ephyrPutVideo;
+        }
 
         has_it = FALSE ;
         if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
             EPHYR_LOG_ERROR ("error\n") ;
         }
-        if (has_it)
+        if (has_it) {
             a_this->adaptors[i].GetVideo = ephyrGetVideo;
+        }
 
         has_it = FALSE ;
         if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
             EPHYR_LOG_ERROR ("error\n") ;
         }
-        if (has_it)
+        if (has_it) {
             a_this->adaptors[i].PutStill = ephyrPutStill;
+        }
 
         has_it = FALSE ;
         if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
             EPHYR_LOG_ERROR ("error\n") ;
         }
-        if (has_it)
+        if (has_it) {
             a_this->adaptors[i].GetStill = ephyrGetStill;
+        }
     }
     EPHYR_LOG ("leave\n") ;
     return TRUE ;
@@ -679,10 +711,70 @@ ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
     return FALSE ;
 }
 
+static Bool
+ephyrXVPrivGetImageBufSize (int a_port_id,
+                            int a_image_id,
+                            unsigned short a_width,
+                            unsigned short a_height,
+                            int *a_size)
+{
+    Bool is_ok=FALSE ;
+    unsigned short width=a_width, height=a_height ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_size, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    if (!ephyrHostXVQueryImageAttributes (a_port_id, a_image_id,
+                                          &width, &height, a_size, NULL, NULL)) {
+        EPHYR_LOG_ERROR ("failed to get image attributes\n") ;
+        goto out ;
+    }
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+static Bool
+ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
+                                const unsigned char *a_image_buf,
+                                int a_image_len)
+{
+    Bool is_ok=FALSE ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    if (a_port_priv->image_buf_size < a_image_len) {
+        unsigned char *buf=NULL ;
+        buf = realloc (a_port_priv->image_buf, a_image_len) ;
+        if (!buf) {
+            EPHYR_LOG_ERROR ("failed to realloc image buffer\n") ;
+            goto out ;
+        }
+        a_port_priv->image_buf = buf ;
+        a_port_priv->image_buf_size = a_image_len;
+    }
+    memmove (a_port_priv->image_buf, a_image_buf, a_image_len) ;
+    is_ok = TRUE ;
+
+out:
+    return is_ok ;
+    EPHYR_LOG ("leave\n") ;
+}
+
 static void
 ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
 {
+    EphyrPortPriv *port_priv = a_port_priv ;
+
+    EPHYR_RETURN_IF_FAIL (port_priv) ;
+
     EPHYR_LOG ("enter\n") ;
+    if (!ephyrHostXVStopVideo (port_priv->port_number)) {
+        EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ;
+    }
     EPHYR_LOG ("leave\n") ;
 }
 
@@ -832,7 +924,8 @@ ephyrPutImage (KdScreenInfo *a_info,
                pointer a_port_priv)
 {
     EphyrPortPriv *port_priv = a_port_priv ;
-    int result=BadImplementation ;
+    Bool is_ok=FALSE ;
+    int result=BadImplementation, image_size=0 ;
 
     EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
 
@@ -849,6 +942,82 @@ ephyrPutImage (KdScreenInfo *a_info,
         goto out ;
     }
 
+    /*
+     * Now save the image so that we can resend it to host it
+     * later, in ReputImage.
+     */
+    if (!ephyrXVPrivGetImageBufSize (port_priv->port_number,
+                                     a_id, a_width, a_height, &image_size)) {
+        EPHYR_LOG_ERROR ("failed to get image size\n") ;
+        /*this is a minor error so we won't get bail out abruptly*/
+        is_ok = FALSE ;
+    } else {
+        is_ok = TRUE ;
+    }
+    if (is_ok) {
+        if (!ephyrXVPrivSaveImageToPortPriv (port_priv, a_buf, image_size)) {
+            is_ok=FALSE ;
+        } else {
+            port_priv->image_id = a_id;
+            port_priv->drw_x = a_drw_x;
+            port_priv->drw_y = a_drw_y;
+            port_priv->drw_w = a_drw_w ;
+            port_priv->drw_h = a_drw_h ;
+            port_priv->src_x = a_src_x;
+            port_priv->src_y = a_src_y ;
+            port_priv->src_w = a_src_w ;
+            port_priv->src_h = a_src_h ;
+            port_priv->image_width = a_width ;
+            port_priv->image_height = a_height ;
+        }
+    }
+    if (!is_ok) {
+        if (port_priv->image_buf) {
+            free (port_priv->image_buf) ;
+            port_priv->image_buf = NULL ;
+            port_priv->image_buf_size = 0 ;
+        }
+    }
+
+    result = Success ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return result ;
+}
+
+static int
+ephyrReputImage (KdScreenInfo *a_info,
+                 DrawablePtr a_drawable,
+                 short a_drw_x,
+                 short a_drw_y,
+                 RegionPtr a_clipping_region,
+                 pointer a_port_priv)
+{
+    EphyrPortPriv *port_priv = a_port_priv ;
+    int result=BadImplementation ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    if (!port_priv->image_buf_size || !port_priv->image_buf) {
+        EPHYR_LOG_ERROR ("has null image buf in cache\n") ;
+        goto out ;
+    }
+    if (!ephyrHostXVPutImage (port_priv->port_number, port_priv->image_id,
+                              a_drw_x, a_drw_y,
+                              port_priv->drw_w, port_priv->drw_h,
+                              port_priv->src_x, port_priv->src_y,
+                              port_priv->src_w, port_priv->src_h,
+                              port_priv->image_width, port_priv->image_height,
+                              port_priv->image_buf,
+                              (EphyrHostBox*)REGION_RECTS (a_clipping_region),
+                              REGION_NUM_RECTS (a_clipping_region))) {
+        EPHYR_LOG_ERROR ("ephyrHostXVPutImage() failed\n") ;
+        goto out ;
+    }
+
     result = Success ;
 
 out:
commit 810dc55866d1c2343512354646c7ab309ea1fad2
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Thu Aug 16 17:11:22 2007 +0200

    Ephyr-Xv: add a new line to a log
    
    	* hw/kdrive/ephyr/ephyrvideo.c:
    	  (ephyrQueryImageAttributes): add newline to log.

diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 0c00351..3c28f0d 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -1075,7 +1075,7 @@ ephyrQueryImageAttributes (KdScreenInfo *a_info,
        EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ;
        goto out ;
    }
-   EPHYR_LOG ("image size: %d, dim (%dx%d)", image_size, *a_w, *a_h) ;
+   EPHYR_LOG ("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h) ;
 
 out:
     EPHYR_LOG ("leave\n") ;
commit 47e6dff89e48249828e828502e98951eee7f85bc
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Thu Aug 16 17:07:36 2007 +0200

    Xephyr-Xv: fix a crash when host X support several ports
    
    	* hw/kdrive/ephyr/ephyrvideo.c:
    	  (ephyrXVPrivQueryHostAdaptors): properly set
    	  port private luke. This fixes a crash when
    	  the host Xv supports multiple ports.
    	  Make sure number of ports cannot be zero.

diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index e2f00c8..0c00351 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -404,7 +404,8 @@ ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
     EphyrHostAttribute *attributes=NULL ;
     EphyrHostImageFormat *image_formats=NULL ;
     int num_video_formats=0, base_port_id=0,
-        num_attributes=0, num_formats=0, i=0;
+        num_attributes=0, num_formats=0, i=0,
+        port_priv_offset=0;
     unsigned num_encodings=0 ;
     Bool is_ok = FALSE ;
 
@@ -441,6 +442,12 @@ ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
                    ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
         if (!cur_host_adaptor)
             continue ;
+        a_this->adaptors[i].nPorts =
+                            ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+        if (a_this->adaptors[i].nPorts <=0) {
+            EPHYR_LOG_ERROR ("Could not find any port of adaptor %d\n", i) ;
+            continue ;
+        }
         a_this->adaptors[i].type =
                         ephyrHostXVAdaptorGetType (cur_host_adaptor) ;
         a_this->adaptors[i].type |= XvWindowMask ;
@@ -475,16 +482,18 @@ ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
                                                &num_video_formats);
         a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
         a_this->adaptors[i].nFormats = num_video_formats ;
+        /* got a_this->adaptors[i].nPorts already
         a_this->adaptors[i].nPorts =
                             ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+        */
         a_this->adaptors[i].pPortPrivates =
                 xcalloc (a_this->adaptors[i].nPorts,
                          sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
+        port_priv_offset = a_this->adaptors[i].nPorts;
         for (j=0; j < a_this->adaptors[i].nPorts; j++) {
-            int port_priv_offset = a_this->adaptors[i].nPorts ;
-            EphyrPortPriv *port_priv =
-                (EphyrPortPriv*)
-                    &a_this->adaptors[i].pPortPrivates[port_priv_offset + j];
+            EphyrPortPriv *port_privs_base =
+                    (EphyrPortPriv*)&a_this->adaptors[i].pPortPrivates[port_priv_offset];
+            EphyrPortPriv *port_priv = &port_privs_base[j] ;
             port_priv->port_number = base_port_id + j;
             port_priv->current_adaptor = &a_this->adaptors[i] ;
             port_priv->xv_priv = a_this ;
commit a38ad562a6f50e9d76a37917b936035215ea460e
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Wed Aug 15 19:40:10 2007 +0200

    make xephyr talk DRI protocol with hostX
    
    	* configure.ac,include/dix-config.h.in: define the XEPHYR_DRI macro.
    	  define it when --enable-xephyr and --enable-dri are both turned on.
    	* hw/kdrive/ephyr/XF86dri.c: copy this from mesa source to enable
    	  Xephyr to talk DRI protocol the host X. In mesa, this is used by libGL.so to
    	  talk DRI protocol with the server.
    	* hw/kdrive/ephyr/ephyr.c: finally initialise the DRI extension
    	  in the ephyrInitScreen() function.
    	* hw/kdrive/ephyr/ephyrdri.c,ephyrdriext.c: safeguard the compilation
    	  using the XEPHYR_DRI macro.

diff --git a/configure.ac b/configure.ac
index a7f1e84..125ee47 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1842,6 +1842,13 @@ if test "$KDRIVE" = yes; then
     if test "x$XEPHYR" = xauto; then
         XEPHYR=$xephyr
     fi
+    XEPHYR_DRI=no
+    if test x$XEPHYR = xyes -a x$DRI = xyes; then
+        XEPHYR_DRI=yes
+    fi
+    if test x$XEPHYR_DRI = xyes ; then
+        AC_DEFINE(XEPHYR_DRI,1,[enable DRI extension in xephyr])
+    fi
 
     # Xephyr needs nanosleep() which is in librt on Solaris
     AC_CHECK_FUNC([nanosleep], [],
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 290aa34..cc9c910 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -22,7 +22,8 @@ libxephyr_a_SOURCES =	\
 	ephyr.c		\
 	ephyr_draw.c	\
 	ephyrvideo.c	\
-	ephyrdriext.c \
+	XF86dri.c	\
+	ephyrdriext.c	\
 	ephyrdri.c	\
 	ephyrdri.h	\
 	os.c		\
@@ -41,8 +42,9 @@ Xephyr_LDADD = 						\
 	libxephyr-hostxv.a			        \
 	../../../exa/libexa.la				\
 	@KDRIVE_LIBS@					\
-        @XEPHYR_LIBS@ \
-	@LIBDRM_LIBS@
+        @XEPHYR_LIBS@ 					\
+	@LIBDRM_LIBS@					\
+	-lGL
 
 Xephyr_DEPENDENCIES =	\
 	libxephyr.a					\
diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c
new file mode 100644
index 0000000..bed65e5
--- /dev/null
+++ b/hw/kdrive/ephyr/XF86dri.c
@@ -0,0 +1,635 @@
+/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <martin at valinux.com>
+ *   Jens Owen <jens at tungstengraphics.com>
+ *   Rickard E. (Rik) Faith <faith at valinux.com>
+ *
+ */
+
+/*
+ * This file has been copied from the mesa source tree and a little bit
+ * modified by:
+ *
+ * Dodji Seketeli <dodji at openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#ifdef XEPHYR_DRI
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD */
+
+#define NEED_REPLIES
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <GL/glx.h>
+#include <X11/dri/xf86dri.h>
+#include <X11/dri/xf86dristr.h>
+
+static XExtensionInfo _xf86dri_info_data;
+static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
+static char xf86dri_extension_name[] = XF86DRINAME;
+
+#define XF86DRICheckExtension(dpy,i,val) \
+  XextCheckExtension (dpy, i, xf86dri_extension_name, val)
+
+/*****************************************************************************
+ *                                                                           *
+ *			   private utility routines                          *
+ *                                                                           *
+ *****************************************************************************/
+
+static int close_display(Display *dpy, XExtCodes *extCodes);
+static /* const */ XExtensionHooks xf86dri_extension_hooks = {
+    NULL,				/* create_gc */
+    NULL,				/* copy_gc */
+    NULL,				/* flush_gc */
+    NULL,				/* free_gc */
+    NULL,				/* create_font */
+    NULL,				/* free_font */
+    close_display,			/* close_display */
+    NULL,				/* wire_to_event */
+    NULL,				/* event_to_wire */
+    NULL,				/* error */
+    NULL,				/* error_string */
+};
+
+static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info, 
+				   xf86dri_extension_name, 
+				   &xf86dri_extension_hooks, 
+				   0, NULL)
+
+static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
+
+
+/*****************************************************************************
+ *                                                                           *
+ *		    public XFree86-DRI Extension routines                    *
+ *                                                                           *
+ *****************************************************************************/
+
+#if 0
+#include <stdio.h>
+#define TRACE(msg)  fprintf(stderr,"XF86DRI%s\n", msg);
+#else
+#define TRACE(msg)
+#endif
+
+
+Bool XF86DRIQueryExtension (dpy, event_basep, error_basep)
+    Display *dpy;
+    int *event_basep, *error_basep;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+
+    TRACE("QueryExtension...");
+    if (XextHasExtension(info)) {
+	*event_basep = info->codes->first_event;
+	*error_basep = info->codes->first_error;
+        TRACE("QueryExtension... return True");
+	return True;
+    } else {
+        TRACE("QueryExtension... return False");
+	return False;
+    }
+}
+
+Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
+    Display* dpy;
+    int* majorVersion; 
+    int* minorVersion;
+    int* patchVersion;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIQueryVersionReply rep;
+    xXF86DRIQueryVersionReq *req;
+
+    TRACE("QueryVersion...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIQueryVersion, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIQueryVersion;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+        TRACE("QueryVersion... return False");
+	return False;
+    }
+    *majorVersion = rep.majorVersion;
+    *minorVersion = rep.minorVersion;
+    *patchVersion = rep.patchVersion;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("QueryVersion... return True");
+    return True;
+}
+
+Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
+    Display* dpy;
+    int screen;
+    Bool* isCapable;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIQueryDirectRenderingCapableReply rep;
+    xXF86DRIQueryDirectRenderingCapableReq *req;
+
+    TRACE("QueryDirectRenderingCapable...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIQueryDirectRenderingCapable, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+        TRACE("QueryDirectRenderingCapable... return False");
+	return False;
+    }
+    *isCapable = rep.isCapable;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("QueryDirectRenderingCapable... return True");
+    return True;
+}
+
+Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
+    Display* dpy;
+    int screen;
+    drm_handle_t * hSAREA;
+    char **busIdString;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIOpenConnectionReply rep;
+    xXF86DRIOpenConnectionReq *req;
+
+    TRACE("OpenConnection...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIOpenConnection, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIOpenConnection;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+        TRACE("OpenConnection... return False");
+	return False;
+    }
+
+    *hSAREA = rep.hSAREALow;
+    if (sizeof(drm_handle_t) == 8) {
+       int shift = 32; /* var to prevent warning on next line */
+       *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
+    }
+
+    if (rep.length) {
+        if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
+            _XEatData(dpy, ((rep.busIdStringLength+3) & ~3));
+            UnlockDisplay(dpy);
+            SyncHandle();
+            TRACE("OpenConnection... return False");
+            return False;
+        }
+	_XReadPad(dpy, *busIdString, rep.busIdStringLength);
+    } else {
+        *busIdString = NULL;
+    }
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("OpenConnection... return True");
+    return True;
+}
+
+Bool XF86DRIAuthConnection(dpy, screen, magic)
+    Display* dpy;
+    int screen;
+    drm_magic_t magic;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIAuthConnectionReq *req;
+    xXF86DRIAuthConnectionReply rep;
+
+    TRACE("AuthConnection...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIAuthConnection, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIAuthConnection;
+    req->screen = screen;
+    req->magic = magic;
+    rep.authenticated = 0;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+        TRACE("AuthConnection... return False");
+	return False;
+    }
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("AuthConnection... return True");
+    return True;
+}
+
+Bool XF86DRICloseConnection(dpy, screen)
+    Display* dpy;
+    int screen;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRICloseConnectionReq *req;
+
+    TRACE("CloseConnection...");
+
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRICloseConnection, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRICloseConnection;
+    req->screen = screen;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("CloseConnection... return True");
+    return True;
+}
+
+Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, 
+	ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
+    Display* dpy;
+    int screen;
+    int* ddxDriverMajorVersion;
+    int* ddxDriverMinorVersion;
+    int* ddxDriverPatchVersion;
+    char** clientDriverName;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIGetClientDriverNameReply rep;
+    xXF86DRIGetClientDriverNameReq *req;
+
+    TRACE("GetClientDriverName...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIGetClientDriverName, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIGetClientDriverName;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+        TRACE("GetClientDriverName... return False");
+	return False;
+    }
+
+    *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
+    *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
+    *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
+
+    if (rep.length) {
+        if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
+            _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
+            UnlockDisplay(dpy);
+            SyncHandle();
+            TRACE("GetClientDriverName... return False");
+            return False;
+        }
+	_XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
+    } else {
+        *clientDriverName = NULL;
+    }
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("GetClientDriverName... return True");
+    return True;
+}
+
+Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context,
+	hHWContext)
+    Display* dpy;
+    int screen;
+    int configID;
+    XID* context;
+    drm_context_t * hHWContext;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRICreateContextReply rep;
+    xXF86DRICreateContextReq *req;
+
+    TRACE("CreateContext...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRICreateContext, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRICreateContext;
+    req->visual = configID;
+    req->screen = screen;
+    *context = XAllocID(dpy);
+    req->context = *context;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+        TRACE("CreateContext... return False");
+	return False;
+    }
+    *hHWContext = rep.hHWContext;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("CreateContext... return True");
+    return True;
+}
+
+Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
+    Display* dpy;
+    int screen;
+    Visual* visual;
+    XID* context;
+    drm_context_t * hHWContext;
+{
+    return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid,
+					   context, hHWContext );
+}
+
+GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, 
+    __DRIid context )
+{
+    Display * const dpy = (Display *) ndpy;
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIDestroyContextReq *req;
+
+    TRACE("DestroyContext...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIDestroyContext, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIDestroyContext;
+    req->screen = screen;
+    req->context = context;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("DestroyContext... return True");
+    return True;
+}
+
+GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, 
+    __DRIid drawable, drm_drawable_t * hHWDrawable )
+{
+    Display * const dpy = (Display *) ndpy;
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRICreateDrawableReply rep;
+    xXF86DRICreateDrawableReq *req;
+
+    TRACE("CreateDrawable...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRICreateDrawable, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRICreateDrawable;
+    req->screen = screen;
+    req->drawable = drawable;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+        TRACE("CreateDrawable... return False");
+	return False;
+    }
+    *hHWDrawable = rep.hHWDrawable;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("CreateDrawable... return True");
+    return True;
+}
+
+GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
+    __DRIid drawable )
+{
+    Display * const dpy = (Display *) ndpy;
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIDestroyDrawableReq *req;
+
+    TRACE("DestroyDrawable...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIDestroyDrawable, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIDestroyDrawable;
+    req->screen = screen;
+    req->drawable = drawable;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("DestroyDrawable... return True");
+    return True;
+}
+
+Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
+    unsigned int* index, unsigned int* stamp,
+    int* X, int* Y, int* W, int* H,
+    int* numClipRects, drm_clip_rect_t ** pClipRects,
+    int* backX, int* backY,
+    int* numBackClipRects, drm_clip_rect_t ** pBackClipRects )
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIGetDrawableInfoReply rep;
+    xXF86DRIGetDrawableInfoReq *req;
+    int total_rects;
+
+    TRACE("GetDrawableInfo...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIGetDrawableInfo, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIGetDrawableInfo;
+    req->screen = screen;
+    req->drawable = drawable;
+
+    if (!_XReply(dpy, (xReply *)&rep, 1, xFalse)) 
+    {
+	UnlockDisplay(dpy);
+	SyncHandle();
+        TRACE("GetDrawableInfo... return False");
+	return False;
+    }
+    *index = rep.drawableTableIndex;
+    *stamp = rep.drawableTableStamp;
+    *X = (int)rep.drawableX;
+    *Y = (int)rep.drawableY;
+    *W = (int)rep.drawableWidth;
+    *H = (int)rep.drawableHeight;
+    *numClipRects = rep.numClipRects;
+    total_rects = *numClipRects;
+
+    *backX = rep.backX;
+    *backY = rep.backY;
+    *numBackClipRects = rep.numBackClipRects;
+    total_rects += *numBackClipRects;
+
+#if 0
+    /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
+     * backwards compatibility (Because of the >> 2 shift) but the fix
+     * enables multi-threaded apps to work.
+     */
+    if (rep.length !=  ((((SIZEOF(xXF86DRIGetDrawableInfoReply) - 
+		       SIZEOF(xGenericReply) + 
+		       total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) {
+        _XEatData(dpy, rep.length);
+	UnlockDisplay(dpy);
+	SyncHandle();
+        TRACE("GetDrawableInfo... return False");
+        return False;
+    }
+#endif
+
+    if (*numClipRects) {
+       int len = sizeof(drm_clip_rect_t) * (*numClipRects);
+
+       *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
+       if (*pClipRects) 
+	  _XRead(dpy, (char*)*pClipRects, len);
+    } else {
+        *pClipRects = NULL;
+    }
+
+    if (*numBackClipRects) {
+       int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
+
+       *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
+       if (*pBackClipRects) 
+	  _XRead(dpy, (char*)*pBackClipRects, len);
+    } else {
+        *pBackClipRects = NULL;
+    }
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("GetDrawableInfo... return True");
+    return True;
+}
+
+Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer, 
+	fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
+    Display* dpy;
+    int screen;
+    drm_handle_t * hFrameBuffer;
+    int* fbOrigin;
+    int* fbSize;
+    int* fbStride;
+    int* devPrivateSize;
+    void** pDevPrivate;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIGetDeviceInfoReply rep;
+    xXF86DRIGetDeviceInfoReq *req;
+
+    TRACE("GetDeviceInfo...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIGetDeviceInfo, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIGetDeviceInfo;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+        TRACE("GetDeviceInfo... return False");
+	return False;
+    }
+
+    *hFrameBuffer = rep.hFrameBufferLow;
+    if (sizeof(drm_handle_t) == 8) {
+       int shift = 32; /* var to prevent warning on next line */
+       *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
+    }
+
+    *fbOrigin = rep.framebufferOrigin;
+    *fbSize = rep.framebufferSize;
+    *fbStride = rep.framebufferStride;
+    *devPrivateSize = rep.devPrivateSize;
+
+    if (rep.length) {
+        if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
+            _XEatData(dpy, ((rep.devPrivateSize+3) & ~3));
+            UnlockDisplay(dpy);
+            SyncHandle();
+            TRACE("GetDeviceInfo... return False");
+            return False;
+        }
+	_XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize);
+    } else {
+        *pDevPrivate = NULL;
+    }
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("GetDeviceInfo... return True");
+    return True;
+}
+
+Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
+    Display* dpy;
+    int screen;
+    Drawable drawable;
+{
+    /* This function and the underlying X protocol are deprecated.
+     */
+    (void) dpy;
+    (void) screen;
+    (void) drawable;
+    return False;
+}
+
+Bool XF86DRICloseFullScreen(dpy, screen, drawable)
+    Display* dpy;
+    int screen;
+    Drawable drawable;
+{
+    /* This function and the underlying X protocol are deprecated.
+     */
+    (void) dpy;
+    (void) screen;
+    (void) drawable;
+    return True;
+}
+#endif /*EPHYR_DRI*/
+
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 2febb65..330158a 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -606,6 +606,7 @@ ephyrInitScreen (ScreenPtr pScreen)
   hostx_set_screen_number (screen, pScreen->myNum);
   hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
   pScreen->CreateColormap = ephyrCreateColormap;
+
 #ifdef XV
   if (!ephyrInitVideo (pScreen)) {
       EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
@@ -613,6 +614,10 @@ ephyrInitScreen (ScreenPtr pScreen)
       EPHYR_LOG ("initialized xvideo okay\n") ;
   }
 #endif /*XV*/
+
+#ifdef XEPHYR_DRI
+    ephyrDRIExtensionInit () ;
+#endif
   return TRUE;
 }
 
diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
index c54e876..5201082 100644
--- a/hw/kdrive/ephyr/ephyrdri.c
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -25,10 +25,12 @@
  * Authors:
  *    Dodji Seketeli <dodji at openedhand.com>
  */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
 #endif
 
+#ifdef XEPHYR_DRI
+
 #include <X11/Xutil.h>
 #include <X11/Xlibint.h>
 /*#define _XF86DRI_SERVER_*/
@@ -203,4 +205,5 @@ ephyrDRIGetDeviceInfo (int a_screen,
     return FALSE ;
     EPHYR_LOG ("leave\n") ;
 }
+#endif /*EPHYR_DRI*/
 
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index 926fa4c..437d8c4 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -27,10 +27,13 @@
  * Authors:
  *    Dodji Seketeli <dodji at openedhand.com>
  */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
 #endif
 
+#ifdef XEPHYR_DRI
+
 #include <string.h>
 
 #define NEED_REPLIES
@@ -79,7 +82,7 @@ static unsigned char DRIReqCode = 0;
 extern void XFree86DRIExtensionInit(void);
 
 void
-XFree86DRIExtensionInit(void)
+ephyrDRIExtensionInit(void)
 {
     ExtensionEntry* extEntry;
     EPHYR_LOG ("enter\n") ;
@@ -689,3 +692,4 @@ SProcXF86DRIDispatch (
     }
 }
 
+#endif /*XEPHYR_DRI*/
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 563d343..3b9f15c 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -425,6 +425,8 @@
 /* Support DRI extension */
 #undef XF86DRI
 
+#undef XEPHYR_DRI
+
 /* Build DBE support */
 #undef DBE
 
commit e4239a48075c77e6a8d2d5cb21f58dd67687482f
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Tue Aug 14 22:48:41 2007 +0200

    Initial dri forwarding big bricks.
    
    	* hw/kdrive/ephyr/ephyrdriext.c: added this to implement a DRI extension
    	  into Xephyr. Normally the DRI extension is only present in the
    	  xfree86 server, but I have ported it to Xephyr. The extension calls
    	  functions that declared/defined in ephyrdri.h ephyrdri.c that
    	  forwards the DRI calls to the host X. It does not work yet, as this
    	  entry is just to put the big bricks in place.
    	* hw/kdrive/ephyr/ephyrdri.c,h: declaration & definition of the
    	  DRI client API that would hit the hostX server.
    	* hw/kdrive/ephyr/GL/internal/dri_interface.h: added this, otherwise
    	  inclusion of /usr/include/X11/dri/xf86dri.h won't compile

diff --git a/hw/kdrive/ephyr/GL/internal/dri_interface.h b/hw/kdrive/ephyr/GL/internal/dri_interface.h
new file mode 100644
index 0000000..8d24e31
--- /dev/null
+++ b/hw/kdrive/ephyr/GL/internal/dri_interface.h
@@ -0,0 +1,517 @@
+/*
+ * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+ * (C) Copyright IBM Corporation 2004
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file dri_interface.h
+ *
+ * This file contains all the types and functions that define the interface
+ * between a DRI driver and driver loader.  Currently, the most common driver
+ * loader is the XFree86 libGL.so.  However, other loaders do exist, and in
+ * the future the server-side libglx.a will also be a loader.
+ * 
+ * \author Kevin E. Martin <kevin at precisioninsight.com>
+ * \author Ian Romanick <idr at us.ibm.com>
+ */
+
+#ifndef DRI_INTERFACE_H
+#define DRI_INTERFACE_H
+
+#include <GL/internal/glcore.h>
+#include <drm.h>
+
+/**
+ * \name DRI interface structures
+ *
+ * The following structures define the interface between the GLX client
+ * side library and the DRI (direct rendering infrastructure).
+ */
+/*@{*/
+typedef struct __DRIdisplayRec  __DRIdisplay;
+typedef struct __DRIscreenRec   __DRIscreen;
+typedef struct __DRIcontextRec  __DRIcontext;
+typedef struct __DRIdrawableRec __DRIdrawable;
+typedef struct __DRIdriverRec   __DRIdriver;
+typedef struct __DRIframebufferRec __DRIframebuffer;
+typedef struct __DRIversionRec     __DRIversion;
+typedef struct __DRIinterfaceMethodsRec  __DRIinterfaceMethods;
+typedef unsigned long __DRIid;
+typedef void __DRInativeDisplay;
+/*@}*/
+
+
+/**
+ * \name Functions provided by the driver loader.
+ */
+/*@{*/
+/**
+ * Type of a pointer to \c glXGetScreenDriver, as returned by
+ * \c glXGetProcAddress.  This function is used to get the name of the DRI
+ * driver for the specified screen of the specified display.  The driver
+ * name is typically used with \c glXGetDriverConfig.
+ *
+ * \sa glXGetScreenDriver, glXGetProcAddress, glXGetDriverConfig
+ */
+typedef const char * (* PFNGLXGETSCREENDRIVERPROC) (__DRInativeDisplay *dpy, int scrNum);
+
+/**
+ * Type of a pointer to \c glXGetDriverConfig, as returned by
+ * \c glXGetProcAddress.  This function is used to get the XML document
+ * describing the configuration options available for the specified driver.
+ *
+ * \sa glXGetDriverConfig, glXGetProcAddress, glXGetScreenDriver
+ */
+typedef const char * (* PFNGLXGETDRIVERCONFIGPROC) (const char *driverName);
+
+/**
+ * Type of a pointer to \c glxEnableExtension, as returned by
+ * \c __DRIinterfaceMethods::getProcAddress.  This function is used to enable
+ * a GLX extension on the specified screen.
+ */
+typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name );
+/*@}*/
+
+
+/**
+ * \name Functions and data provided by the driver.
+ */
+/*@{*/
+
+typedef void *(CREATENEWSCREENFUNC)(__DRInativeDisplay *dpy, int scrn,
+    __DRIscreen *psc, const __GLcontextModes * modes,
+    const __DRIversion * ddx_version, const __DRIversion * dri_version,
+    const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer,
+    void * pSAREA, int fd, int internal_api_version,
+    const __DRIinterfaceMethods * interface,
+    __GLcontextModes ** driver_modes);
+typedef CREATENEWSCREENFUNC* PFNCREATENEWSCREENFUNC;
+extern CREATENEWSCREENFUNC __driCreateNewScreen_20050727;
+
+
+/**
+ * XML document describing the configuration options supported by the
+ * driver.
+ */
+extern const char __driConfigOptions[];
+
+/*@}*/
+
+
+/**
+ * Stored version of some component (i.e., server-side DRI module, kernel-side
+ * DRM, etc.).
+ * 
+ * \todo
+ * There are several data structures that explicitly store a major version,
+ * minor version, and patch level.  These structures should be modified to
+ * have a \c __DRIversionRec instead.
+ */
+struct __DRIversionRec {
+    int    major;        /**< Major version number. */
+    int    minor;        /**< Minor version number. */
+    int    patch;        /**< Patch-level. */
+};
+
+
+typedef void (*__DRIfuncPtr)(void);
+
+struct __DRIinterfaceMethodsRec {
+    /**
+     * Get pointer to named function.
+     */
+    __DRIfuncPtr (*getProcAddress)( const char * proc_name );
+
+    /**
+     * Create a list of \c __GLcontextModes structures.
+     */
+    __GLcontextModes * (*createContextModes)(unsigned count,
+        size_t minimum_bytes_per_struct);
+
+    /**
+     * Destroy a list of \c __GLcontextModes structures.
+     *
+     * \todo
+     * Determine if the drivers actually need to call this.
+     */
+    void (*destroyContextModes)( __GLcontextModes * modes );
+
+    /**
+     * Get the \c __DRIscreen for a given display and screen number.
+     */
+    __DRIscreen *(*getScreen)(__DRInativeDisplay *dpy, int screenNum);
+
+
+    /**
+     * \name Client/server protocol functions.
+     *
+     * These functions implement the DRI client/server protocol for
+     * context and drawable operations.  Platforms that do not implement
+     * the wire protocol (e.g., EGL) will implement glorified no-op functions.
+     */
+    /*@{*/
+    /**
+     * Determine if the specified window ID still exists.
+     * 
+     * \note
+     * Implementations may assume that the driver will only pass an ID into
+     * this function that actually corresponds to a window.  On
+     * implementations where windows can only be destroyed by the DRI driver
+     * (e.g., EGL), this function is allowed to always return \c GL_TRUE.
+     */
+    GLboolean (*windowExists)(__DRInativeDisplay *dpy, __DRIid draw);
+
+    /**
+     * Create the server-side portion of the GL context.
+     */
+    GLboolean (* createContext)( __DRInativeDisplay *dpy, int screenNum,
+        int configID, void * contextID, drm_context_t * hw_context );
+
+    /**
+     * Destroy the server-side portion of the GL context.
+     */
+    GLboolean (* destroyContext)( __DRInativeDisplay *dpy, int screenNum,
+        __DRIid context );
+
+    /**
+     * Create the server-side portion of the drawable.
+     */
+    GLboolean (*createDrawable)( __DRInativeDisplay * ndpy, int screen,
+        __DRIid drawable, drm_drawable_t * hHWDrawable );
+
+    /**
+     * Destroy the server-side portion of the drawable.
+     */
+    GLboolean (*destroyDrawable)( __DRInativeDisplay * ndpy, int screen,
+        __DRIid drawable );
+
+    /**
+     * This function is used to get information about the position, size, and
+     * clip rects of a drawable.
+     */
+    GLboolean (* getDrawableInfo) ( __DRInativeDisplay *dpy, int scrn,
+        __DRIid draw, unsigned int * index, unsigned int * stamp,
+        int * x, int * y, int * width, int * height,
+        int * numClipRects, drm_clip_rect_t ** pClipRects,
+        int * backX, int * backY,
+        int * numBackClipRects, drm_clip_rect_t ** pBackClipRects );
+    /*@}*/
+
+
+    /**
+     * \name Timing related functions.
+     */
+    /*@{*/
+    /**
+     * Get the 64-bit unadjusted system time (UST).
+     */
+    int (*getUST)(int64_t * ust);
+
+    /**
+     * Get the media stream counter (MSC) rate.
+     * 
+     * Matching the definition in GLX_OML_sync_control, this function returns
+     * the rate of the "media stream counter".  In practical terms, this is
+     * the frame refresh rate of the display.
+     */
+    GLboolean (*getMSCRate)(__DRInativeDisplay * dpy, __DRIid drawable,
+        int32_t * numerator, int32_t * denominator);
+    /*@}*/
+
+    /**
+     * Reports areas of the given drawable which have been modified by the
+     * driver.
+     *
+     * \param drawable which the drawing was done to.
+     * \param rects rectangles affected, with the drawable origin as the
+     *	      origin.
+     * \param x X offset of the drawable within the screen (used in the
+     *	      front_buffer case)
+     * \param y Y offset of the drawable within the screen.
+     * \param front_buffer boolean flag for whether the drawing to the
+     * 	      drawable was actually done directly to the front buffer (instead
+     *	      of backing storage, for example)
+     */
+    void (*reportDamage)(__DRInativeDisplay * dpy, int screen,
+			 __DRIid drawable,
+			 int x, int y,
+			 drm_clip_rect_t *rects, int num_rects,
+			 int front_buffer);
+};
+
+   
+/**
+ * Framebuffer information record.  Used by libGL to communicate information
+ * about the framebuffer to the driver's \c __driCreateNewScreen function.
+ * 
+ * In XFree86, most of this information is derrived from data returned by
+ * calling \c XF86DRIGetDeviceInfo.
+ *
+ * \sa XF86DRIGetDeviceInfo __DRIdisplayRec::createNewScreen
+ *     __driUtilCreateNewScreen CallCreateNewScreen
+ *
+ * \bug This structure could be better named.
+ */
+struct __DRIframebufferRec {
+    unsigned char *base;    /**< Framebuffer base address in the CPU's
+			     * address space.  This value is calculated by
+			     * calling \c drmMap on the framebuffer handle
+			     * returned by \c XF86DRIGetDeviceInfo (or a
+			     * similar function).
+			     */
+    int size;               /**< Framebuffer size, in bytes. */
+    int stride;             /**< Number of bytes from one line to the next. */
+    int width;              /**< Pixel width of the framebuffer. */
+    int height;             /**< Pixel height of the framebuffer. */
+    int dev_priv_size;      /**< Size of the driver's dev-priv structure. */
+    void *dev_priv;         /**< Pointer to the driver's dev-priv structure. */
+};
+
+
+/**
+ * Screen dependent methods.  This structure is initialized during the
+ * \c __DRIdisplayRec::createScreen call.
+ */
+struct __DRIscreenRec {
+    /**
+     * Method to destroy the private DRI screen data.
+     */
+    void (*destroyScreen)(__DRInativeDisplay *dpy, int scrn, void *screenPrivate);
+
+    /**
+     * Method to create the private DRI drawable data and initialize the
+     * drawable dependent methods.
+     */
+    void *(*createNewDrawable)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
+			       __DRIid draw, __DRIdrawable *pdraw,
+			       int renderType, const int *attrs);
+
+    /**
+     * Method to return a pointer to the DRI drawable data.
+     */
+    __DRIdrawable *(*getDrawable)(__DRInativeDisplay *dpy, __DRIid draw,
+				  void *drawablePrivate);
+
+    /**
+     * Opaque pointer to private per screen direct rendering data.  \c NULL
+     * if direct rendering is not supported on this screen.  Never
+     * dereferenced in libGL.
+     */
+    void *private;
+
+    /**
+     * Get the number of vertical refreshes since some point in time before
+     * this function was first called (i.e., system start up).
+     * 
+     * \since Internal API version 20030317.
+     */
+    int (*getMSC)( void *screenPrivate, int64_t *msc );
+
+    /**
+     * Opaque pointer that points back to the containing 
+     * \c __GLXscreenConfigs.  This data structure is shared with DRI drivers
+     * but \c __GLXscreenConfigs is not. However, they are needed by some GLX
+     * functions called by DRI drivers.
+     *
+     * \since Internal API version 20030813.
+     */
+    void *screenConfigs;
+
+    /**
+     * Functions associated with MESA_allocate_memory.
+     *
+     * \since Internal API version 20030815.
+     */
+    /*@{*/
+    void *(*allocateMemory)(__DRInativeDisplay *dpy, int scrn, GLsizei size,
+			    GLfloat readfreq, GLfloat writefreq,
+			    GLfloat priority);
+   
+    void (*freeMemory)(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer);
+   
+    GLuint (*memoryOffset)(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer);
+    /*@}*/
+
+    /**
+     * Method to create the private DRI context data and initialize the
+     * context dependent methods.
+     *
+     * \since Internal API version 20031201.
+     */
+    void * (*createNewContext)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
+			       int render_type,
+			       void *sharedPrivate, __DRIcontext *pctx);
+
+    /**
+     * Method to override base texture image with a driver specific 'offset'.
+     * The depth passed in allows e.g. to ignore the alpha channel of texture
+     * images where the non-alpha components don't occupy a whole texel.
+     *
+     * For GLX_EXT_texture_from_pixmap with AIGLX.
+     *
+     * \since Internal API version 20070121.
+     */
+    void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
+			 unsigned long long offset, GLint depth, GLuint pitch);
+};
+
+/**
+ * Context dependent methods.  This structure is initialized during the
+ * \c __DRIscreenRec::createContext call.
+ */
+struct __DRIcontextRec {
+    /**
+     * Method to destroy the private DRI context data.
+     */
+    void (*destroyContext)(__DRInativeDisplay *dpy, int scrn, void *contextPrivate);
+
+    /**
+     * Opaque pointer to private per context direct rendering data.
+     * \c NULL if direct rendering is not supported on the display or
+     * screen used to create this context.  Never dereferenced in libGL.
+     */
+    void *private;
+
+    /**
+     * Pointer to the mode used to create this context.
+     *
+     * \since Internal API version 20040317.
+     */
+    const __GLcontextModes * mode;
+
+    /**
+     * Method to bind a DRI drawable to a DRI graphics context.
+     *
+     * \since Internal API version 20050727.
+     */
+    GLboolean (*bindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
+			 __DRIid read, __DRIcontext *ctx);
+
+    /**
+     * Method to unbind a DRI drawable from a DRI graphics context.
+     *
+     * \since Internal API version 20050727.
+     */
+    GLboolean (*unbindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
+			   __DRIid read, __DRIcontext *ctx);
+};
+
+/**
+ * Drawable dependent methods.  This structure is initialized during the
+ * \c __DRIscreenRec::createDrawable call.  \c createDrawable is not called
+ * by libGL at this time.  It's currently used via the dri_util.c utility code
+ * instead.
+ */
+struct __DRIdrawableRec {
+    /**
+     * Method to destroy the private DRI drawable data.
+     */
+    void (*destroyDrawable)(__DRInativeDisplay *dpy, void *drawablePrivate);
+
+    /**
+     * Method to swap the front and back buffers.
+     */
+    void (*swapBuffers)(__DRInativeDisplay *dpy, void *drawablePrivate);
+
+    /**
+     * Opaque pointer to private per drawable direct rendering data.
+     * \c NULL if direct rendering is not supported on the display or
+     * screen used to create this drawable.  Never dereferenced in libGL.
+     */
+    void *private;
+
+    /**
+     * Get the number of completed swap buffers for this drawable.
+     *
+     * \since Internal API version 20030317.
+     */
+    int (*getSBC)(__DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc );
+
+    /**
+     * Wait for the SBC to be greater than or equal target_sbc.
+     *
+     * \since Internal API version 20030317.
+     */
+    int (*waitForSBC)( __DRInativeDisplay * dpy, void *drawablePriv,
+		       int64_t target_sbc,
+		       int64_t * msc, int64_t * sbc );
+
+    /**
+     * Wait for the MSC to equal target_msc, or, if that has already passed,
+     * the next time (MSC % divisor) is equal to remainder.  If divisor is
+     * zero, the function will return as soon as MSC is greater than or equal
+     * to target_msc.
+     * 
+     * \since Internal API version 20030317.
+     */
+    int (*waitForMSC)( __DRInativeDisplay * dpy, void *drawablePriv,
+		       int64_t target_msc, int64_t divisor, int64_t remainder,
+		       int64_t * msc, int64_t * sbc );
+
+    /**
+     * Like \c swapBuffers, but does NOT have an implicit \c glFlush.  Once
+     * rendering is complete, waits until MSC is equal to target_msc, or
+     * if that has already passed, waits until (MSC % divisor) is equal
+     * to remainder.  If divisor is zero, the swap will happen as soon as
+     * MSC is greater than or equal to target_msc.
+     * 
+     * \since Internal API version 20030317.
+     */
+    int64_t (*swapBuffersMSC)(__DRInativeDisplay *dpy, void *drawablePrivate,
+			      int64_t target_msc,
+			      int64_t divisor, int64_t remainder);
+
+    /**
+     * Enable or disable frame usage tracking.
+     * 
+     * \since Internal API version 20030317.
+     */
+    int (*frameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate, GLboolean enable);
+
+    /**
+     * Retrieve frame usage information.
+     * 
+     * \since Internal API version 20030317.
+     */
+    int (*queryFrameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate,
+			      int64_t * sbc, int64_t * missedFrames,
+			      float * lastMissedUsage, float * usage );
+
+    /**
+     * Used by drivers that implement the GLX_SGI_swap_control or
+     * GLX_MESA_swap_control extension.
+     *
+     * \since Internal API version 20030317.
+     */
+    unsigned swap_interval;
+
+    /**
+     * Used by drivers that implement the GLX_MESA_copy_sub_buffer extension.
+     *
+     * \since Internal API version 20060314.
+     */
+    void (*copySubBuffer)(__DRInativeDisplay *dpy, void *drawablePrivate,
+			  int x, int y, int w, int h);
+};
+
+#endif
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 193c26b..290aa34 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -3,7 +3,7 @@ INCLUDES = 					\
 	@KDRIVE_CFLAGS@				\
 	-I$(srcdir)/../../../exa
 
-noinst_LIBRARIES = libxephyr-hostx.a libxephyr-hostxv.a libxephyr.a 
+noinst_LIBRARIES = libxephyr-hostx.a libxephyr-hostxv.a libxephyr.a
 
 bin_PROGRAMS = Xephyr
 
@@ -22,11 +22,16 @@ libxephyr_a_SOURCES =	\
 	ephyr.c		\
 	ephyr_draw.c	\
 	ephyrvideo.c	\
+	ephyrdriext.c \
+	ephyrdri.c	\
+	ephyrdri.h	\
 	os.c		\
 	hostx.h         \
 	ephyr.h		\
 	ephyrlog.h
 
+libxephyr_a_CFLAGS = @LIBDRM_CFLAGS@ @DRIPROTO_CFLAGS@
+
 Xephyr_SOURCES = \
 	ephyrinit.c
 
@@ -36,7 +41,8 @@ Xephyr_LDADD = 						\
 	libxephyr-hostxv.a			        \
 	../../../exa/libexa.la				\
 	@KDRIVE_LIBS@					\
-        @XEPHYR_LIBS@
+        @XEPHYR_LIBS@ \
+	@LIBDRM_LIBS@
 
 Xephyr_DEPENDENCIES =	\
 	libxephyr.a					\
diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
new file mode 100644
index 0000000..c54e876
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdri.c
@@ -0,0 +1,206 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/Xutil.h>
+#include <X11/Xlibint.h>
+/*#define _XF86DRI_SERVER_*/
+#include <GL/glx.h>
+#include <X11/dri/xf86dri.h>
+#include "hostx.h"
+#include "ephyrdri.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif /*TRUE*/
+
+#ifndef FALSE
+#define FALSE 0
+#endif /*FALSE*/
+
+Bool
+ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable)
+{
+    Display *dpy=hostx_get_display () ;
+    Bool is_ok=FALSE ;
+
+    EPHYR_LOG ("enter\n") ;
+    is_ok = XF86DRIQueryDirectRenderingCapable (dpy, a_screen, a_is_capable) ;
+    EPHYR_LOG ("leave\n") ;
+
+    return is_ok ;
+}
+
+Bool
+ephyrDRIOpenConnection (int a_screen, drm_handle_t *a_sarea, char **a_bus_id_string)
+{
+    Display *dpy = hostx_get_display () ;
+    Bool is_ok=FALSE ;
+
+    EPHYR_LOG ("enter\n") ;
+    is_ok = XF86DRIOpenConnection (dpy, a_screen, a_sarea, a_bus_id_string) ;
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+Bool
+ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic)
+{
+    Display *dpy = hostx_get_display () ;
+    Bool is_ok=FALSE ;
+
+    EPHYR_LOG ("enter\n") ;
+    is_ok = XF86DRIAuthConnection (dpy, a_screen, a_magic) ;
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+Bool
+ephyrDRICloseConnection (int a_screen)
+{
+    Display *dpy = hostx_get_display () ;
+    Bool is_ok=FALSE ;
+
+    EPHYR_LOG ("enter\n") ;
+    is_ok = XF86DRICloseConnection (dpy, a_screen) ;
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+Bool
+ephyrDRIGetClientDriverName (int a_screen,
+                             int *a_ddx_driver_major_version,
+                             int *a_ddx_driver_minor_version,
+                             int *a_ddx_driver_patch_version,
+                             char ** a_client_driver_name)
+{
+    Display *dpy = hostx_get_display () ;
+    Bool is_ok=FALSE ;
+
+    EPHYR_LOG ("enter\n") ;
+    is_ok = XF86DRIGetClientDriverName (dpy, a_screen,
+                                        a_ddx_driver_major_version,
+                                        a_ddx_driver_minor_version,
+                                        a_ddx_driver_patch_version,
+                                        a_client_driver_name) ;
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+Bool
+ephyrDRICreateContext (int a_screen,
+                       int a_visual_id,
+                       unsigned long int *a_returned_ctxt_id,
+                       drm_context_t *a_hw_ctxt)
+{
+    Display *dpy = hostx_get_display () ;
+    Bool is_ok=FALSE ;
+    Visual v;
+
+    EPHYR_LOG ("enter\n") ;
+    memset (&v, 0, sizeof (v)) ;
+    v.visualid = a_visual_id ;
+    is_ok = XF86DRICreateContext (dpy,
+                                  a_screen,
+                                  &v,
+                                  a_returned_ctxt_id,
+                                  a_hw_ctxt) ;
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+Bool
+ephyrDRIDestroyContext (int a_screen,
+                        int a_context_id)
+{
+    Display *dpy = hostx_get_display () ;
+    Bool is_ok=FALSE ;
+
+    EPHYR_LOG ("enter\n") ;
+    is_ok = XF86DRIDestroyContext (dpy, a_screen, a_context_id) ;
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+Bool
+ephyrDRICreateDrawable (int a_screen,
+                        int a_drawable,
+                        drm_drawable_t *a_hw_drawable)
+{
+    EPHYR_LOG ("enter\n") ;
+    return FALSE ;
+    EPHYR_LOG ("leave\n") ;
+}
+
+Bool
+ephyrDRIDestroyDrawable (int a_screen, int a_drawable)
+{
+    EPHYR_LOG ("enter\n") ;
+    return FALSE ;
+    EPHYR_LOG ("leave\n") ;
+}
+
+Bool
+ephyrDRIGetDrawableInfo (int a_screen,
+                         int a_drawable,
+                         unsigned int *a_index,
+                         unsigned int *a_stamp,
+                         int *a_x,
+                         int *a_y,
+                         int *a_w,
+                         int *a_h,
+                         int *a_num_clip_rects,
+                         drm_clip_rect_t **a_clip_rects,
+                         int *a_back_x,
+                         int *a_back_y,
+                         int *num_back_clip_rects,
+                         drm_clip_rect_t **a_back_clip_rects)
+{
+    EPHYR_LOG ("enter\n") ;
+    return FALSE ;
+    EPHYR_LOG ("leave\n") ;
+}
+
+Bool
+ephyrDRIGetDeviceInfo (int a_screen,
+                       drm_handle_t *a_frame_buffer,
+                       int *a_fb_origin,
+                       int *a_fb_size,
+                       int *a_fb_stride,
+                       int *a_dev_private_size,
+                       void **a_dev_private)
+{
+    EPHYR_LOG ("enter\n") ;
+    return FALSE ;
+    EPHYR_LOG ("leave\n") ;
+}
+
diff --git a/hw/kdrive/ephyr/ephyrdri.h b/hw/kdrive/ephyr/ephyrdri.h
new file mode 100644
index 0000000..d77467f
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdri.h
@@ -0,0 +1,75 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+
+#ifndef __EPHYRDRI_H__
+#define __EPHYRDRI_H__
+
+#include <xf86drm.h>
+
+Bool ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable) ;
+Bool ephyrDRIOpenConnection (int screen, drm_handle_t *a_sarea, char **a_bus_id_string) ;
+Bool ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic) ;
+Bool ephyrDRICloseConnection (int a_screen) ;
+Bool ephyrDRIGetClientDriverName (int a_screen,
+                                  int *a_ddx_driver_major_version,
+                                  int *a_ddx_driver_minor_version,
+                                  int *a_ddx_driver_patch_version,
+                                  char ** a_client_driver_name) ;
+Bool ephyrDRICreateContext (int a_screen,
+                            int a_visual_id,
+                            unsigned long int *a_returned_ctx_id,
+                            drm_context_t *a_hw_ctx) ;
+Bool ephyrDRIDestroyContext (int a_screen,
+                             int a_context_id) ;
+Bool ephyrDRICreateDrawable (int a_screen,
+                             int a_drawable,
+                             drm_drawable_t *a_hw_drawable) ;
+Bool ephyrDRIDestroyDrawable (int a_screen, int a_drawable) ;
+Bool ephyrDRIGetDrawableInfo (int a_screen,
+                              int a_drawable,
+                              unsigned int *a_index,
+                              unsigned int *a_stamp,
+                              int *a_x,
+                              int *a_y,
+                              int *a_w,
+                              int *a_h,
+                              int *a_num_clip_rects,
+                              drm_clip_rect_t **a_clip_rects,
+                              int *a_back_x,
+                              int *a_back_y,
+                              int *num_back_clip_rects,
+                              drm_clip_rect_t **a_back_clip_rects) ;
+Bool ephyrDRIGetDeviceInfo (int a_screen,
+                            drm_handle_t *a_frame_buffer,
+                            int *a_fb_origin,
+                            int *a_fb_size,
+                            int *a_fb_stride,
+                            int *a_dev_private_size,
+                            void **a_dev_private) ;
+#endif /*__EPHYRDRI_H__*/
+
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
new file mode 100644
index 0000000..926fa4c
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -0,0 +1,691 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * This file is heavily copied from hw/xfree86/dri/xf86dri.c
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#define _XF86DRI_SERVER_
+#include <X11/dri/xf86dri.h>
+#include <X11/dri/xf86dristr.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "swaprep.h"
+#include "ephyrdri.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+
+static int DRIErrorBase;
+
+static DISPATCH_PROC(ProcXF86DRIQueryVersion);
+static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(ProcXF86DRIOpenConnection);
+static DISPATCH_PROC(ProcXF86DRICloseConnection);
+static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
+static DISPATCH_PROC(ProcXF86DRICreateContext);
+static DISPATCH_PROC(ProcXF86DRIDestroyContext);
+static DISPATCH_PROC(ProcXF86DRICreateDrawable);
+static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
+static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
+static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
+static DISPATCH_PROC(ProcXF86DRIDispatch);
+static DISPATCH_PROC(ProcXF86DRIAuthConnection);
+
+static DISPATCH_PROC(SProcXF86DRIQueryVersion);
+static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(SProcXF86DRIDispatch);
+
+static void XF86DRIResetProc(ExtensionEntry* extEntry);
+
+static unsigned char DRIReqCode = 0;
+
+extern void XFree86DRIExtensionInit(void);
+
+void
+XFree86DRIExtensionInit(void)
+{
+    ExtensionEntry* extEntry;
+    EPHYR_LOG ("enter\n") ;
+
+#ifdef XF86DRI_EVENTS
+    EventType = CreateNewResourceType(XF86DRIFreeEvents);
+#endif
+
+    if ((extEntry = AddExtension(XF86DRINAME,
+				 XF86DRINumberEvents,
+				 XF86DRINumberErrors,
+				 ProcXF86DRIDispatch,
+				 SProcXF86DRIDispatch,
+				 XF86DRIResetProc,
+				 StandardMinorOpcode))) {
+	DRIReqCode = (unsigned char)extEntry->base;
+	DRIErrorBase = extEntry->errorBase;
+    }
+    EPHYR_LOG ("leave\n") ;
+}
+
+/*ARGSUSED*/
+static void
+XF86DRIResetProc (
+    ExtensionEntry* extEntry
+)
+{
+}
+
+static int
+ProcXF86DRIQueryVersion(
+    register ClientPtr client
+)
+{
+    xXF86DRIQueryVersionReply rep;
+    register int n;
+
+    REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.majorVersion = XF86DRI_MAJOR_VERSION;
+    rep.minorVersion = XF86DRI_MINOR_VERSION;
+    rep.patchVersion = XF86DRI_PATCH_VERSION;
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swaps(&rep.majorVersion, n);
+	swaps(&rep.minorVersion, n);
+	swapl(&rep.patchVersion, n);
+    }
+    WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRIQueryDirectRenderingCapable(
+    register ClientPtr client
+)
+{
+    xXF86DRIQueryDirectRenderingCapableReply	rep;
+    Bool isCapable;
+    register int n;
+
+    REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+    REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+
+    if (!ephyrDRIQueryDirectRenderingCapable (stuff->screen, &isCapable)) {
+        return BadValue;
+    }
+    rep.isCapable = isCapable;
+
+    if (!LocalClient(client) || client->swapped)
+	rep.isCapable = 0;
+
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+    }
+
+    WriteToClient(client, 
+	sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRIOpenConnection(
+    register ClientPtr client
+)
+{
+    xXF86DRIOpenConnectionReply rep;
+    drm_handle_t			hSAREA;
+    char*			busIdString;
+
+    REQUEST(xXF86DRIOpenConnectionReq);
+    REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    if (!ephyrDRIOpenConnection(stuff->screen,
+                                &hSAREA,
+                                &busIdString)) {
+        return BadValue;
+    }
+
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.busIdStringLength = 0;
+    if (busIdString)
+	rep.busIdStringLength = strlen(busIdString);
+    rep.length = (SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
+                  ((rep.busIdStringLength + 3) & ~3)) >> 2;
+
+    rep.hSAREALow  = (CARD32)(hSAREA & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+    rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
+#else
+    rep.hSAREAHigh = 0;
+#endif
+
+    WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
+    if (rep.busIdStringLength)
+	WriteToClient(client, rep.busIdStringLength, busIdString);
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRIAuthConnection(
+    register ClientPtr client
+)
+{
+    xXF86DRIAuthConnectionReply rep;
+    
+    REQUEST(xXF86DRIAuthConnectionReq);
+    REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.authenticated = 1;
+
+    if (!ephyrDRIAuthConnection (stuff->screen, stuff->magic)) {
+        ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
+        rep.authenticated = 0;
+    }
+    WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRICloseConnection(
+    register ClientPtr client
+)
+{
+    REQUEST(xXF86DRICloseConnectionReq);
+    REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    /*
+    DRICloseConnection( screenInfo.screens[stuff->screen]);
+    */
+
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRIGetClientDriverName(
+    register ClientPtr client
+)
+{
+    xXF86DRIGetClientDriverNameReply	rep;
+    char* clientDriverName;
+
+    REQUEST(xXF86DRIGetClientDriverNameReq);
+    REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    ephyrDRIGetClientDriverName (stuff->screen,
+                                 (int *)&rep.ddxDriverMajorVersion,
+                                 (int *)&rep.ddxDriverMinorVersion,
+                                 (int *)&rep.ddxDriverPatchVersion,
+                                 &clientDriverName);
+
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.clientDriverNameLength = 0;
+    if (clientDriverName)
+	rep.clientDriverNameLength = strlen(clientDriverName);
+    rep.length = (SIZEOF(xXF86DRIGetClientDriverNameReply) - 
+			SIZEOF(xGenericReply) +
+			((rep.clientDriverNameLength + 3) & ~3)) >> 2;
+
+    WriteToClient(client, 
+	sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
+    if (rep.clientDriverNameLength)
+	WriteToClient(client, 
+                      rep.clientDriverNameLength, 
+                      clientDriverName);
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRICreateContext(
+    register ClientPtr client
+)
+{
+    xXF86DRICreateContextReply	rep;
+    ScreenPtr pScreen;
+    VisualPtr visual;
+    int i;
+
+    REQUEST(xXF86DRICreateContextReq);
+    REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+
+    pScreen = screenInfo.screens[stuff->screen];
+    visual = pScreen->visuals;
+
+    /* Find the requested X visual */
+    for (i = 0; i < pScreen->numVisuals; i++, visual++)
+	if (visual->vid == stuff->visual)
+	    break;
+    if (i == pScreen->numVisuals) {
+	/* No visual found */
+	return BadValue;
+    }
+
+    /*
+    if (!DRICreateContext( pScreen,
+			   visual,
+			   stuff->context,
+			   (drm_context_t *)&rep.hHWContext)) {
+	return BadValue;
+    }
+    */
+
+    WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRIDestroyContext(
+    register ClientPtr client
+)
+{
+    REQUEST(xXF86DRIDestroyContextReq);
+    REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    /*
+    if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
+			    stuff->context)) {
+	return BadValue;
+    }
+    */
+
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRICreateDrawable(
+    ClientPtr client
+)
+{
+    xXF86DRICreateDrawableReply	rep;
+    DrawablePtr pDrawable;
+    int rc;
+
+    REQUEST(xXF86DRICreateDrawableReq);
+    REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+
+    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+			   DixReadAccess);
+    if (rc != Success)
+	return rc;
+
+    /*TODO: this cannot work. We must properly
+     * do the mapping between the xephyr drawable and
+     * the host drawable
+     */
+    if (!ephyrDRICreateDrawable (stuff->screen,
+                                 0/*should be host drawableID*/,
+                                 (drm_drawable_t *)&rep.hHWDrawable)) {
+        return BadValue;
+    }
+
+    WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRIDestroyDrawable(
+    register ClientPtr client
+)
+{
+    REQUEST(xXF86DRIDestroyDrawableReq);
+    DrawablePtr pDrawable;
+    REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
+    int rc;
+
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+			   DixReadAccess);
+    if (rc != Success)
+	return rc;
+
+    if (!ephyrDRIDestroyDrawable(stuff->screen,
+                                 0/*should be drawable in host x*/)) {
+	return BadValue;
+    }
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRIGetDrawableInfo(
+    register ClientPtr client
+)
+{
+    xXF86DRIGetDrawableInfoReply	rep;
+    DrawablePtr pDrawable;
+    int X, Y, W, H;
+    drm_clip_rect_t * pClipRects, *pClippedRects;
+    drm_clip_rect_t * pBackClipRects;
+    int backX, backY, rc;
+
+    REQUEST(xXF86DRIGetDrawableInfoReq);
+    REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+
+    /*TODO: this cannot work.
+     * We must properly do the mapping
+     * between xephyr drawable and the host drawable
+     */
+    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+			   DixReadAccess);
+    if (rc != Success)
+	return rc;
+
+    if (!ephyrDRIGetDrawableInfo (stuff->screen,
+                                  0 /*should be the drawable in hostx*/,
+                                  (unsigned int*)&rep.drawableTableIndex,
+                                  (unsigned int*)&rep.drawableTableStamp,
+                                  (int*)&X,
+                                  (int*)&Y,
+                                  (int*)&W,
+                                  (int*)&H,
+                                  (int*)&rep.numClipRects,
+                                  &pClipRects,
+                                  &backX,
+                                  &backY,
+                                  (int*)&rep.numBackClipRects,
+                                  &pBackClipRects)) {
+	return BadValue;
+    }
+
+    rep.drawableX = X;
+    rep.drawableY = Y;
+    rep.drawableWidth = W;
+    rep.drawableHeight = H;
+    rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - 
+		  SIZEOF(xGenericReply));
+
+    rep.backX = backX;
+    rep.backY = backY;
+        
+    if (rep.numBackClipRects) 
+       rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;    
+
+    pClippedRects = pClipRects;
+
+    if (rep.numClipRects) {
+       /* Clip cliprects to screen dimensions (redirected windows) */
+       pClippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t));
+
+       if (pClippedRects) {
+	    ScreenPtr pScreen = screenInfo.screens[stuff->screen];
+	    int i, j;
+
+	    for (i = 0, j = 0; i < rep.numClipRects; i++) {
+		pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
+		pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
+		pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
+		pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
+
+		if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
+		    pClippedRects[j].y1 < pClippedRects[j].y2) {
+		    j++;
+		}
+	    }
+
+	    rep.numClipRects = j;
+       } else {
+	    rep.numClipRects = 0;
+       }
+
+       rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+    }
+    
+    rep.length = ((rep.length + 3) & ~3) >> 2;
+
+    WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
+
+    if (rep.numClipRects) {
+	WriteToClient(client,  
+		      sizeof(drm_clip_rect_t) * rep.numClipRects,
+		      (char *)pClippedRects);
+	xfree(pClippedRects);
+    }
+
+    if (rep.numBackClipRects) {
+       WriteToClient(client, 
+		     sizeof(drm_clip_rect_t) * rep.numBackClipRects,
+		     (char *)pBackClipRects);
+    }
+
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRIGetDeviceInfo(
+    register ClientPtr client
+)
+{
+    xXF86DRIGetDeviceInfoReply	rep;
+    drm_handle_t hFrameBuffer;
+    void *pDevPrivate;
+
+    REQUEST(xXF86DRIGetDeviceInfoReq);
+    REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
+    if (stuff->screen >= screenInfo.numScreens) {
+	client->errorValue = stuff->screen;
+	return BadValue;
+    }
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+
+    if (!ephyrDRIGetDeviceInfo (stuff->screen,
+                                &hFrameBuffer,
+                                (int*)&rep.framebufferOrigin,
+                                (int*)&rep.framebufferSize,
+                                (int*)&rep.framebufferStride,
+                                (int*)&rep.devPrivateSize,
+                                &pDevPrivate)) {
+        return BadValue;
+    }
+
+    rep.hFrameBufferLow  = (CARD32)(hFrameBuffer & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+    rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
+#else
+    rep.hFrameBufferHigh = 0;
+#endif
+
+    rep.length = 0;
+    if (rep.devPrivateSize) {
+        rep.length = (SIZEOF(xXF86DRIGetDeviceInfoReply) - 
+                      SIZEOF(xGenericReply) +
+                      ((rep.devPrivateSize + 3) & ~3)) >> 2;
+    }
+
+    WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
+    if (rep.length) {
+        WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
+    }
+    return (client->noClientException);
+}
+
+static int
+ProcXF86DRIDispatch (
+    register ClientPtr	client
+)
+{
+    REQUEST(xReq);
+
+    switch (stuff->data)
+    {
+    case X_XF86DRIQueryVersion:
+        return ProcXF86DRIQueryVersion(client);
+    case X_XF86DRIQueryDirectRenderingCapable:
+        return ProcXF86DRIQueryDirectRenderingCapable(client);
+    }
+
+    if (!LocalClient(client))
+        return DRIErrorBase + XF86DRIClientNotLocal;
+
+    switch (stuff->data)
+    {
+    case X_XF86DRIOpenConnection:
+        return ProcXF86DRIOpenConnection(client);
+    case X_XF86DRICloseConnection:
+        return ProcXF86DRICloseConnection(client);
+    case X_XF86DRIGetClientDriverName:
+        return ProcXF86DRIGetClientDriverName(client);
+    case X_XF86DRICreateContext:
+        return ProcXF86DRICreateContext(client);
+    case X_XF86DRIDestroyContext:
+        return ProcXF86DRIDestroyContext(client);
+    case X_XF86DRICreateDrawable:
+        return ProcXF86DRICreateDrawable(client);
+    case X_XF86DRIDestroyDrawable:
+        return ProcXF86DRIDestroyDrawable(client);
+    case X_XF86DRIGetDrawableInfo:
+        return ProcXF86DRIGetDrawableInfo(client);
+    case X_XF86DRIGetDeviceInfo:
+        return ProcXF86DRIGetDeviceInfo(client);
+    case X_XF86DRIAuthConnection:
+        return ProcXF86DRIAuthConnection(client);
+    /* {Open,Close}FullScreen are deprecated now */
+    default:
+        return BadRequest;
+    }
+}
+
+static int
+SProcXF86DRIQueryVersion(
+    register ClientPtr	client
+)
+{
+    register int n;
+    REQUEST(xXF86DRIQueryVersionReq);
+    swaps(&stuff->length, n);
+    return ProcXF86DRIQueryVersion(client);
+}
+
+static int
+SProcXF86DRIQueryDirectRenderingCapable(
+    register ClientPtr client
+)
+{
+    register int n;
+    REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->screen, n);
+    return ProcXF86DRIQueryDirectRenderingCapable(client);
+}
+
+static int
+SProcXF86DRIDispatch (
+    register ClientPtr	client
+)
+{
+    REQUEST(xReq);
+
+    /*
+     * Only local clients are allowed DRI access, but remote clients still need
+     * these requests to find out cleanly.
+     */
+    switch (stuff->data)
+    {
+    case X_XF86DRIQueryVersion:
+	return SProcXF86DRIQueryVersion(client);
+    case X_XF86DRIQueryDirectRenderingCapable:
+	return SProcXF86DRIQueryDirectRenderingCapable(client);
+    default:
+	return DRIErrorBase + XF86DRIClientNotLocal;
+    }
+}
+
commit e01d3dd98d1b596e75d25f94dd89c7d41223011d
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Thu Aug 9 10:55:10 2007 +0200

    Support clipping region in PutImage.
    
    	* hw/kdrive/ephyr/ephyrhostvideo.c,h:
    	  (ephyrHostXVPutImage): make this support clipping region.
    	  The clipping region is propagated to host using XSetClipRectangles.
    	  This changes the API of ephyrHostXVPutImage.
    	* hw/kdrive/ephyr/ephyrvideo.c:
    	  (ephyrPutImage): propagate the clipping region to the new
    	  ephyrHostXVPutImage() entry point.

diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index b1b926a..85fc7bd 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -757,17 +757,21 @@ ephyrHostXVPutImage (int a_port_id,
                      int a_src_h,
                      int a_image_width,
                      int a_image_height,
-                     unsigned char *a_buf)
+                     unsigned char *a_buf,
+                     EphyrHostBox *a_clip_rects,
+                     int a_clip_rect_nums )
 {
     Bool is_ok=TRUE ;
     XvImage *xv_image=NULL ;
     GC gc=0 ;
     XGCValues gc_values;
     Display *dpy = hostx_get_display () ;
+    XRectangle *rects=NULL ;
+    int res = 0 ;
 
     EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
 
-    EPHYR_LOG ("enter\n") ;
+    EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
 
     gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
     if (!gc) {
@@ -782,16 +786,32 @@ ephyrHostXVPutImage (int a_port_id,
         goto out ;
     }
     xv_image->data = (char*)a_buf ;
-    XvPutImage (dpy, a_port_id, hostx_get_window (),
-                gc, xv_image,
-                a_src_x, a_src_y, a_src_w, a_src_h,
-                a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
-    XFlush (dpy) ;
+    if (a_clip_rect_nums) {
+        int i=0 ;
+        rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ;
+        for (i=0; i < a_clip_rect_nums; i++) {
+            rects[i].x = a_clip_rects[i].x1 ;
+            rects[i].y = a_clip_rects[i].y1 ;
+            rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
+            rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
+            EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n",
+                       rects[i].x, rects[i].y,
+                       rects[i].width, rects[i].height) ;
+        }
+        XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ;
+        /*this always returns 1*/
+    }
+    res = XvPutImage (dpy, a_port_id, hostx_get_window (),
+                      gc, xv_image,
+                      a_src_x, a_src_y, a_src_w, a_src_h,
+                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+    if (res != Success) {
+        EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ;
+        goto out ;
+    }
     is_ok = TRUE ;
 
 out:
-
-    EPHYR_LOG ("leave\n") ;
     if (xv_image) {
         XFree (xv_image) ;
         xv_image = NULL ;
@@ -800,6 +820,11 @@ out:
         XFreeGC (dpy, gc) ;
         gc = NULL ;
     }
+    if (rects) {
+        free (rects) ;
+        rects = NULL ;
+    }
+    EPHYR_LOG ("leave\n") ;
     return is_ok ;
 }
 
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
index 9c97c6a..661792b 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.h
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -84,6 +84,10 @@ typedef struct _EphyrHostImageFormat {
     int scanline_order;          /* XvTopToBottom, XvBottomToTop */
 } EphyrHostImageFormat ;
 
+typedef struct {
+    unsigned short x1, y1, x2, y2 ;
+} EphyrHostBox ;
+
 void ephyrHostXVInit (void) ;
 
 void ephyrHostFree (void *a_pointer) ;
@@ -197,7 +201,9 @@ Bool ephyrHostXVPutImage (int a_port_id,
                           int a_src_h,
                           int a_image_width,
                           int a_image_height,
-                          unsigned char *a_buf) ;
+                          unsigned char *a_buf,
+                          EphyrHostBox *a_clip_rects,
+                          int a_clip_rect_nums) ;
 
 /*
  * Putvideo/PutStill/GetVideo
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 90c7535..e2f00c8 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -613,7 +613,6 @@ ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
         goto out ;
     num_registered_adaptors =
                 KdXVListGenericAdaptors (screen, &registered_adaptors);
-    EPHYR_LOG ("") ;
 
     num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
     adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
@@ -824,36 +823,19 @@ ephyrPutImage (KdScreenInfo *a_info,
                pointer a_port_priv)
 {
     EphyrPortPriv *port_priv = a_port_priv ;
-    BoxRec clipped_area, dst_box ;
     int result=BadImplementation ;
-    int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
 
     EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
 
     EPHYR_LOG ("enter\n") ;
 
-    dst_box.x1 = a_drw_x ;
-    dst_box.x2 = a_drw_x + a_drw_w;
-    dst_box.y1 = a_drw_y ;
-    dst_box.y2 = a_drw_y + a_drw_h;
-
-    if (!DoSimpleClip (&dst_box,
-                       REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
-                       &clipped_area)) {
-        EPHYR_LOG_ERROR ("failed to simple clip\n") ;
-        goto out ;
-    }
-
-    drw_x = clipped_area.x1 ;
-    drw_y = clipped_area.y1 ;
-    drw_w = clipped_area.x2 - clipped_area.x1 ;
-    drw_h = clipped_area.y2 - clipped_area.y1 ;
-
     if (!ephyrHostXVPutImage (port_priv->port_number,
                               a_id,
-                              drw_x, drw_y, drw_w, drw_h,
+                              a_drw_x, a_drw_y, a_drw_w, a_drw_h,
                               a_src_x, a_src_y, a_src_w, a_src_h,
-                              a_width, a_height, a_buf)) {
+                              a_width, a_height, a_buf,
+                              (EphyrHostBox*)REGION_RECTS (a_clipping_region),
+                              REGION_NUM_RECTS (a_clipping_region))) {
         EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
         goto out ;
     }
commit 39d3895469f07304d72800d8dcef6c7732f13d5f
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Wed Aug 8 14:27:32 2007 +0200

    make EphyrXVPriv be a singleton
    
    	* hw/kdrive/ephyr/ephyrvideo.c:
    	  (ephyrInitVideo) make the EphyrXVPriv object be a
    	   singleton instance, otherwise a new object is created at each
    	   generation.

diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 1cc45ff..90c7535 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -1,4 +1,4 @@
-/*  
+/*
  * Xephyr - A kdrive X server thats runs in a host X window.
  *          Authored by Matthew Allum <mallum at openedhand.com>
  * 
@@ -267,9 +267,10 @@ out:
 Bool
 ephyrInitVideo (ScreenPtr pScreen)
 {
+    Bool is_ok = FALSE ;
     KdScreenPriv(pScreen);
     KdScreenInfo *screen = pScreenPriv->screen;
-    EphyrXVPriv *xv_priv = NULL ;
+    static EphyrXVPriv *xv_priv;
 
     EPHYR_LOG ("enter\n") ;
 
@@ -278,17 +279,22 @@ ephyrInitVideo (ScreenPtr pScreen)
         return FALSE ;
     }
 
-    xv_priv = ephyrXVPrivNew () ;
+    if (!xv_priv) {
+        xv_priv = ephyrXVPrivNew () ;
+    }
     if (!xv_priv) {
         EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
-        return FALSE ;
+        goto out ;
     }
 
     if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
         EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
-        return FALSE ;
+        goto out ;
     }
-    return TRUE ;
+    is_ok = TRUE ;
+
+out:
+    return is_ok ;
 }
 
 static EphyrXVPriv*
@@ -607,6 +613,8 @@ ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
         goto out ;
     num_registered_adaptors =
                 KdXVListGenericAdaptors (screen, &registered_adaptors);
+    EPHYR_LOG ("") ;
+
     num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
     adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
     if (!adaptors) {
@@ -621,7 +629,7 @@ ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
         EPHYR_LOG_ERROR ("failed to register adaptors\n");
         goto out ;
     }
-    EPHYR_LOG ("registered %d adaptors\n", num_adaptors) ;
+    EPHYR_LOG ("there are  %d registered adaptors\n", num_adaptors) ;
     is_ok = TRUE ;
 
 out:
commit 4ed083095a13ec92bb4c8e705f26500f8312c138
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Tue Aug 7 14:16:13 2007 +0200

    add [Get/Put]Video and [Get/Put]Still support
    
    	* hw/kdrive/ephyr/ephyrhostvideo.c,h:
    	  (ephyrHostXVAdaptorHasXXX): fix these.
    	  (ephyrHostXVAdaptorHasGetVideo): added this
    	  (ephyrHostXVAdaptorHasGetStill): ditto
    	  (ephyrHostXVPutVideo): added this
    	  (ephyrHostXVGetVideo): ditto
    	  (ephyrHostXVPutStill): ditto
    	  (ephyrHostXVGetStill): ditto
    	* hw/kdrive/ephyr/ephyrvideo.c:
    	  (ephyrPutVideo): implement this
    	  (ephyrGetVideo): ditto
    	  (ephyrPutStill): ditto
    	  (ephyrGetStill): ditto
    	  (ephyrXVPrivSetAdaptorsHooks): advertise GetVideo and GetStill
    	  when the host X supports it.

diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index 3310993..b1b926a 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -370,7 +370,18 @@ ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
 {
     EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
 
-    if (((XvAdaptorInfo*)a_this)->type & XvVideoMask)
+    if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvInputMask)
+        *a_result = TRUE ;
+    else
+        *a_result = FALSE ;
+    return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
+                               Bool *a_result)
+{
+    if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvOutputMask)
         *a_result = TRUE ;
     else
         *a_result = FALSE ;
@@ -383,7 +394,20 @@ ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
 {
     EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
 
-    if (((XvAdaptorInfo*)a_this)->type & XvStillMask)
+    if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvInputMask)
+        *a_result = TRUE ;
+    else
+        *a_result = FALSE ;
+    return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
+                               Bool *a_result)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+    if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvOutputMask)
         *a_result = TRUE ;
     else
         *a_result = FALSE ;
@@ -396,7 +420,7 @@ ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
 {
     EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
 
-    if (((XvAdaptorInfo*)a_this)->type & XvImageMask)
+    if (((XvAdaptorInfo*)a_this)->type & XvImageMask && XvInputMask)
         *a_result = TRUE ;
     else
         *a_result = FALSE ;
@@ -739,12 +763,13 @@ ephyrHostXVPutImage (int a_port_id,
     XvImage *xv_image=NULL ;
     GC gc=0 ;
     XGCValues gc_values;
+    Display *dpy = hostx_get_display () ;
 
     EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
 
     EPHYR_LOG ("enter\n") ;
 
-    gc = XCreateGC (hostx_get_display (), hostx_get_window (), 0L, &gc_values);
+    gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
     if (!gc) {
         EPHYR_LOG_ERROR ("failed to create gc \n") ;
         goto out ;
@@ -757,11 +782,11 @@ ephyrHostXVPutImage (int a_port_id,
         goto out ;
     }
     xv_image->data = (char*)a_buf ;
-    XvPutImage (hostx_get_display (), a_port_id, hostx_get_window (),
+    XvPutImage (dpy, a_port_id, hostx_get_window (),
                 gc, xv_image,
                 a_src_x, a_src_y, a_src_w, a_src_h,
                 a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
-    XFlush (hostx_get_display ()) ;
+    XFlush (dpy) ;
     is_ok = TRUE ;
 
 out:
@@ -771,5 +796,158 @@ out:
         XFree (xv_image) ;
         xv_image = NULL ;
     }
+    if (gc) {
+        XFreeGC (dpy, gc) ;
+        gc = NULL ;
+    }
+    return is_ok ;
+}
+
+Bool
+ephyrHostXVPutVideo (int a_port_id,
+                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+    Bool is_ok=FALSE ;
+    int res=FALSE ;
+    GC gc=0 ;
+    XGCValues gc_values;
+    Display *dpy=hostx_get_display () ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+    gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
+    if (!gc) {
+        EPHYR_LOG_ERROR ("failed to create gc \n") ;
+        goto out ;
+    }
+    res = XvPutVideo (dpy, a_port_id, hostx_get_window (), gc,
+                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+    if (res != Success) {
+        EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ;
+        goto out ;
+    }
+
+    is_ok = TRUE ;
+
+out:
+    if (gc) {
+        XFreeGC (dpy, gc) ;
+        gc = NULL ;
+    }
+    return is_ok ;
+}
+
+Bool
+ephyrHostXVGetVideo (int a_port_id,
+                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+    Bool is_ok=FALSE ;
+    int res=FALSE ;
+    GC gc=0 ;
+    XGCValues gc_values;
+    Display *dpy=hostx_get_display () ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+    gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
+    if (!gc) {
+        EPHYR_LOG_ERROR ("failed to create gc \n") ;
+        goto out ;
+    }
+    res = XvGetVideo (dpy, a_port_id, hostx_get_window (), gc,
+                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+    if (res != Success) {
+        EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ;
+        goto out ;
+    }
+
+    is_ok = TRUE ;
+
+out:
+    if (gc) {
+        XFreeGC (dpy, gc) ;
+        gc = NULL ;
+    }
+    return is_ok ;
+}
+
+Bool
+ephyrHostXVPutStill (int a_port_id,
+                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+    Bool is_ok=FALSE ;
+    int res=FALSE ;
+    GC gc=0 ;
+    XGCValues gc_values;
+    Display *dpy=hostx_get_display () ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+    gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
+    if (!gc) {
+        EPHYR_LOG_ERROR ("failed to create gc \n") ;
+        goto out ;
+    }
+    res = XvPutStill (dpy, a_port_id, hostx_get_window (), gc,
+                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+    if (res != Success) {
+        EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ;
+        goto out ;
+    }
+
+    is_ok = TRUE ;
+
+out:
+    if (gc) {
+        XFreeGC (dpy, gc) ;
+        gc = NULL ;
+    }
     return is_ok ;
 }
+
+Bool
+ephyrHostXVGetStill (int a_port_id,
+                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+    Bool is_ok=FALSE ;
+    int res=FALSE ;
+    GC gc=0 ;
+    XGCValues gc_values;
+    Display *dpy=hostx_get_display () ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+    gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
+    if (!gc) {
+        EPHYR_LOG_ERROR ("failed to create gc \n") ;
+        goto out ;
+    }
+    res = XvGetStill (dpy, a_port_id, hostx_get_window (), gc,
+                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+    if (res != Success) {
+        EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ;
+        goto out ;
+    }
+
+    is_ok = TRUE ;
+
+out:
+    if (gc) {
+        XFreeGC (dpy, gc) ;
+        gc = NULL ;
+    }
+    return is_ok ;
+}
+
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
index 9499446..9c97c6a 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.h
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -111,8 +111,12 @@ int ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ;
 
 Bool ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
                                     Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
+                                    Bool *a_result) ;
 Bool ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
                                     Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
+                                    Bool *a_result) ;
 Bool ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
                                     Bool *a_result) ;
 
@@ -195,5 +199,23 @@ Bool ephyrHostXVPutImage (int a_port_id,
                           int a_image_height,
                           unsigned char *a_buf) ;
 
+/*
+ * Putvideo/PutStill/GetVideo
+ */
+Bool ephyrHostXVPutVideo (int a_port_id,
+                          int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+                          int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
+
+Bool ephyrHostXVGetVideo (int a_port_id,
+                          int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+                          int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
+
+Bool ephyrHostXVPutStill (int a_port_id,
+                          int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+                          int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
+
+Bool ephyrHostXVGetStill (int a_port_id,
+                          int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+                          int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
 #endif /*__EPHYRHOSTVIDEO_H__*/
 
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 8ac2204..1cc45ff 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -97,24 +97,6 @@ static void ephyrQueryBestSize (KdScreenInfo *a_info,
                                 unsigned int *a_prefered_h,
                                 pointer a_port_priv);
 
-static int ephyrPutVideo (KdScreenInfo *a_screen,
-                          DrawablePtr a_drw,
-                          short a_vid_x, short a_vid_y,
-                          short a_drw_x, short a_drw_y,
-                          short a_vid_w, short a_vid_h,
-                          short a_drw_w, short a_drw_h,
-                          RegionPtr a_clip_region,
-                          pointer a_port_priv) ;
-
-static int ephyrPutStill (KdScreenInfo *a_screen,
-                          DrawablePtr a_drw,
-                          short a_vid_x, short a_vid_y,
-                          short a_drw_x, short a_drw_y,
-                          short a_vid_w, short a_vid_h,
-                          short a_drw_w, short a_drw_h,
-                          RegionPtr a_clip_region,
-                          pointer a_port_priv) ;
-
 static int ephyrPutImage (KdScreenInfo *a_info,
                           DrawablePtr a_drawable,
                           short a_src_x,
@@ -133,6 +115,42 @@ static int ephyrPutImage (KdScreenInfo *a_info,
                           RegionPtr a_clipping_region,
                           pointer a_port_priv);
 
+static int ephyrPutVideo (KdScreenInfo *a_info,
+                          DrawablePtr a_drawable,
+                          short a_vid_x, short a_vid_y,
+                          short a_drw_x, short a_drw_y,
+                          short a_vid_w, short a_vid_h,
+                          short a_drw_w, short a_drw_h,
+                          RegionPtr a_clip_region,
+                          pointer a_port_priv) ;
+
+static int ephyrGetVideo (KdScreenInfo *a_info,
+                          DrawablePtr a_drawable,
+                          short a_vid_x, short a_vid_y,
+                          short a_drw_x, short a_drw_y,
+                          short a_vid_w, short a_vid_h,
+                          short a_drw_w, short a_drw_h,
+                          RegionPtr a_clip_region,
+                          pointer a_port_priv) ;
+
+static int ephyrPutStill (KdScreenInfo *a_info,
+                          DrawablePtr a_drawable,
+                          short a_vid_x, short a_vid_y,
+                          short a_drw_x, short a_drw_y,
+                          short a_vid_w, short a_vid_h,
+                          short a_drw_w, short a_drw_h,
+                          RegionPtr a_clip_region,
+                          pointer a_port_priv) ;
+
+static int ephyrGetStill (KdScreenInfo *a_info,
+                          DrawablePtr a_drawable,
+                          short a_vid_x, short a_vid_y,
+                          short a_drw_x, short a_drw_y,
+                          short a_vid_w, short a_vid_h,
+                          short a_drw_w, short a_drw_h,
+                          RegionPtr a_clip_region,
+                          pointer a_port_priv) ;
+
 static int ephyrQueryImageAttributes (KdScreenInfo *a_info,
                                       int a_id,
                                       unsigned short *a_w,
@@ -547,11 +565,25 @@ ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
             a_this->adaptors[i].PutVideo = ephyrPutVideo;
 
         has_it = FALSE ;
+        if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
+            EPHYR_LOG_ERROR ("error\n") ;
+        }
+        if (has_it)
+            a_this->adaptors[i].GetVideo = ephyrGetVideo;
+
+        has_it = FALSE ;
         if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
             EPHYR_LOG_ERROR ("error\n") ;
         }
         if (has_it)
             a_this->adaptors[i].PutStill = ephyrPutStill;
+
+        has_it = FALSE ;
+        if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
+            EPHYR_LOG_ERROR ("error\n") ;
+        }
+        if (has_it)
+            a_this->adaptors[i].GetStill = ephyrGetStill;
     }
     EPHYR_LOG ("leave\n") ;
     return TRUE ;
@@ -765,51 +797,171 @@ ephyrQueryBestSize (KdScreenInfo *a_info,
 }
 
 static int
-ephyrPutVideo (KdScreenInfo *a_screen,
-               DrawablePtr a_drw,
+ephyrPutImage (KdScreenInfo *a_info,
+               DrawablePtr a_drawable,
+               short a_src_x,
+               short a_src_y,
+               short a_drw_x,
+               short a_drw_y,
+               short a_src_w,
+               short a_src_h,
+               short a_drw_w,
+               short a_drw_h,
+               int a_id,
+               unsigned char *a_buf,
+               short a_width,
+               short a_height,
+               Bool a_sync,
+               RegionPtr a_clipping_region,
+               pointer a_port_priv)
+{
+    EphyrPortPriv *port_priv = a_port_priv ;
+    BoxRec clipped_area, dst_box ;
+    int result=BadImplementation ;
+    int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    dst_box.x1 = a_drw_x ;
+    dst_box.x2 = a_drw_x + a_drw_w;
+    dst_box.y1 = a_drw_y ;
+    dst_box.y2 = a_drw_y + a_drw_h;
+
+    if (!DoSimpleClip (&dst_box,
+                       REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+                       &clipped_area)) {
+        EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+        goto out ;
+    }
+
+    drw_x = clipped_area.x1 ;
+    drw_y = clipped_area.y1 ;
+    drw_w = clipped_area.x2 - clipped_area.x1 ;
+    drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+    if (!ephyrHostXVPutImage (port_priv->port_number,
+                              a_id,
+                              drw_x, drw_y, drw_w, drw_h,
+                              a_src_x, a_src_y, a_src_w, a_src_h,
+                              a_width, a_height, a_buf)) {
+        EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
+        goto out ;
+    }
+
+    result = Success ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return result ;
+}
+
+static int
+ephyrPutVideo (KdScreenInfo *a_info,
+               DrawablePtr a_drawable,
                short a_vid_x, short a_vid_y,
                short a_drw_x, short a_drw_y,
                short a_vid_w, short a_vid_h,
                short a_drw_w, short a_drw_h,
-               RegionPtr a_clip_region,
+               RegionPtr a_clipping_region,
                pointer a_port_priv)
 {
+    EphyrPortPriv *port_priv = a_port_priv ;
+    BoxRec clipped_area, dst_box ;
+    int result=BadImplementation ;
+    int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
     EPHYR_LOG ("enter\n") ;
-    return Success ;
+
+    dst_box.x1 = a_drw_x ;
+    dst_box.x2 = a_drw_x + a_drw_w;
+    dst_box.y1 = a_drw_y ;
+    dst_box.y2 = a_drw_y + a_drw_h;
+
+    if (!DoSimpleClip (&dst_box,
+                       REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+                       &clipped_area)) {
+        EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+        goto out ;
+    }
+
+    drw_x = clipped_area.x1 ;
+    drw_y = clipped_area.y1 ;
+    drw_w = clipped_area.x2 - clipped_area.x1 ;
+    drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+    if (!ephyrHostXVPutVideo (port_priv->port_number,
+                              a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+                              a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+        EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ;
+        goto out ;
+    }
+    result = Success ;
+
+out:
     EPHYR_LOG ("leave\n") ;
+    return result ;
 }
 
 static int
-ephyrPutStill (KdScreenInfo *a_screen,
-               DrawablePtr a_drw,
+ephyrGetVideo (KdScreenInfo *a_info,
+               DrawablePtr a_drawable,
                short a_vid_x, short a_vid_y,
                short a_drw_x, short a_drw_y,
                short a_vid_w, short a_vid_h,
                short a_drw_w, short a_drw_h,
-               RegionPtr a_clip_region,
+               RegionPtr a_clipping_region,
                pointer a_port_priv)
 {
+    EphyrPortPriv *port_priv = a_port_priv ;
+    BoxRec clipped_area, dst_box ;
+    int result=BadImplementation ;
+    int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
     EPHYR_LOG ("enter\n") ;
-    return Success ;
+
+    dst_box.x1 = a_drw_x ;
+    dst_box.x2 = a_drw_x + a_drw_w;
+    dst_box.y1 = a_drw_y ;
+    dst_box.y2 = a_drw_y + a_drw_h;
+
+    if (!DoSimpleClip (&dst_box,
+                       REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+                       &clipped_area)) {
+        EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+        goto out ;
+    }
+
+    drw_x = clipped_area.x1 ;
+    drw_y = clipped_area.y1 ;
+    drw_w = clipped_area.x2 - clipped_area.x1 ;
+    drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+    if (!ephyrHostXVGetVideo (port_priv->port_number,
+                              a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+                              a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+        EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ;
+        goto out ;
+    }
+    result = Success ;
+
+out:
     EPHYR_LOG ("leave\n") ;
+    return result ;
 }
 
 static int
-ephyrPutImage (KdScreenInfo *a_info,
+ephyrPutStill (KdScreenInfo *a_info,
                DrawablePtr a_drawable,
-               short a_src_x,
-               short a_src_y,
-               short a_drw_x,
-               short a_drw_y,
-               short a_src_w,
-               short a_src_h,
-               short a_drw_w,
-               short a_drw_h,
-               int a_id,
-               unsigned char *a_buf,
-               short a_width,
-               short a_height,
-               Bool a_sync,
+               short a_vid_x, short a_vid_y,
+               short a_drw_x, short a_drw_y,
+               short a_vid_w, short a_vid_h,
+               short a_drw_w, short a_drw_h,
                RegionPtr a_clipping_region,
                pointer a_port_priv)
 {
@@ -818,7 +970,7 @@ ephyrPutImage (KdScreenInfo *a_info,
     int result=BadImplementation ;
     int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
 
-    EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
+    EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
 
     EPHYR_LOG ("enter\n") ;
 
@@ -839,15 +991,61 @@ ephyrPutImage (KdScreenInfo *a_info,
     drw_w = clipped_area.x2 - clipped_area.x1 ;
     drw_h = clipped_area.y2 - clipped_area.y1 ;
 
-    if (!ephyrHostXVPutImage (port_priv->port_number,
-                              a_id,
-                              drw_x, drw_y, drw_w, drw_h,
-                              a_src_x, a_src_y, a_src_w, a_src_h,
-                              a_width, a_height, a_buf)) {
-        EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
+    if (!ephyrHostXVPutStill (port_priv->port_number,
+                              a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+                              a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+        EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ;
+        goto out ;
+    }
+    result = Success ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return result ;
+}
+
+static int
+ephyrGetStill (KdScreenInfo *a_info,
+               DrawablePtr a_drawable,
+               short a_vid_x, short a_vid_y,
+               short a_drw_x, short a_drw_y,
+               short a_vid_w, short a_vid_h,
+               short a_drw_w, short a_drw_h,
+               RegionPtr a_clipping_region,
+               pointer a_port_priv)
+{
+    EphyrPortPriv *port_priv = a_port_priv ;
+    BoxRec clipped_area, dst_box ;
+    int result=BadImplementation ;
+    int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    dst_box.x1 = a_drw_x ;
+    dst_box.x2 = a_drw_x + a_drw_w;
+    dst_box.y1 = a_drw_y ;
+    dst_box.y2 = a_drw_y + a_drw_h;
+
+    if (!DoSimpleClip (&dst_box,
+                       REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+                       &clipped_area)) {
+        EPHYR_LOG_ERROR ("failed to simple clip\n") ;
         goto out ;
     }
 
+    drw_x = clipped_area.x1 ;
+    drw_y = clipped_area.y1 ;
+    drw_w = clipped_area.x2 - clipped_area.x1 ;
+    drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+    if (!ephyrHostXVGetStill (port_priv->port_number,
+                              a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+                              a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+        EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ;
+        goto out ;
+    }
     result = Success ;
 
 out:
commit 6f7961bc218169aaa0d10cfad0952adb7fac2f00
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Mon Aug 6 18:38:54 2007 +0200

    advertise only the hooks implemented by host X
    
            * hw/kdrive/ephyr/ephyrhostvideo.c,h:
              (ephyrHostXVAdaptorHasPutVideo): detect if
              host X has the PutVideo call.
              (ephyrHostXVAdaptorHasPutStill): detect if
              host X has the PutStill call
              (ephyrHostXVAdaptorHasPutImage): detect if
              host X has the PutImage call
            * hw/kdrive/ephyr/ephyrvideo.c:
              (ephyrXVPrivQueryHostAdaptors): make sure to create
              atoms for attribute names otherwise subsequent
              calls to get/set attribute from clients won't work.
              (ephyrXVPrivSetAdaptorsHooks): don't hardwire advertising
              of the PutImage call. Instead, advertise the calls advertised
              by the host.

diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index 1ccd994..3310993 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -365,6 +365,45 @@ ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
 }
 
 Bool
+ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
+                               Bool *a_result)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+    if (((XvAdaptorInfo*)a_this)->type & XvVideoMask)
+        *a_result = TRUE ;
+    else
+        *a_result = FALSE ;
+    return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
+                               Bool *a_result)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+    if (((XvAdaptorInfo*)a_this)->type & XvStillMask)
+        *a_result = TRUE ;
+    else
+        *a_result = FALSE ;
+    return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
+                               Bool *a_result)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+    if (((XvAdaptorInfo*)a_this)->type & XvImageMask)
+        *a_result = TRUE ;
+    else
+        *a_result = FALSE ;
+    return TRUE ;
+}
+
+Bool
 ephyrHostXVQueryEncodings (int a_port_id,
                            EphyrHostEncoding **a_encodings,
                            unsigned int *a_num_encodings)
@@ -545,9 +584,9 @@ ephyrHostXVQueryBestSize (int a_port_id,
         EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ;
         goto out ;
     }
+    XSync (hostx_get_display (), FALSE) ;
 
     EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ;
-
     is_ok = TRUE ;
 
 out:
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
index 86154bc..9499446 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.h
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -109,6 +109,13 @@ EphyrHostVideoFormat* ephyrHostXVAdaptorGetVideoFormats
 int ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ;
 int ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ;
 
+Bool ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
+                                    Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
+                                    Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
+                                    Bool *a_result) ;
+
 /*
  * encoding
  */
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 5cd9d17..8ac2204 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -97,6 +97,24 @@ static void ephyrQueryBestSize (KdScreenInfo *a_info,
                                 unsigned int *a_prefered_h,
                                 pointer a_port_priv);
 
+static int ephyrPutVideo (KdScreenInfo *a_screen,
+                          DrawablePtr a_drw,
+                          short a_vid_x, short a_vid_y,
+                          short a_drw_x, short a_drw_y,
+                          short a_vid_w, short a_vid_h,
+                          short a_drw_w, short a_drw_h,
+                          RegionPtr a_clip_region,
+                          pointer a_port_priv) ;
+
+static int ephyrPutStill (KdScreenInfo *a_screen,
+                          DrawablePtr a_drw,
+                          short a_vid_x, short a_vid_y,
+                          short a_drw_x, short a_drw_y,
+                          short a_vid_w, short a_vid_h,
+                          short a_drw_w, short a_drw_h,
+                          RegionPtr a_clip_region,
+                          pointer a_port_priv) ;
+
 static int ephyrPutImage (KdScreenInfo *a_info,
                           DrawablePtr a_drawable,
                           short a_src_x,
@@ -458,6 +476,13 @@ ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
         a_this->adaptors[i].pAttributes =
                     portAttributesDup (attributes, num_attributes);
         a_this->adaptors[i].nAttributes = num_attributes ;
+        /*make sure atoms of attrs names are created in xephyr*/
+        for (j=0; j < a_this->adaptors[i].nAttributes; j++) {
+            if (a_this->adaptors[i].pAttributes[j].name)
+                MakeAtom (a_this->adaptors[i].pAttributes[j].name,
+                          strlen (a_this->adaptors[i].pAttributes[j].name),
+                          TRUE) ;
+        }
         if (!ephyrHostXVQueryImageFormats (base_port_id,
                                            &image_formats,
                                            &num_formats)) {
@@ -487,6 +512,8 @@ static Bool
 ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
 {
     int i=0 ;
+    Bool has_it=FALSE ;
+    EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
 
     EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
 
@@ -497,8 +524,34 @@ ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
         a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
         a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
         a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ;
-        a_this->adaptors[i].PutImage = ephyrPutImage;
         a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ;
+
+        cur_host_adaptor =
+                   ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+        if (!cur_host_adaptor) {
+            EPHYR_LOG_ERROR ("failed to get host adaptor at index %d\n", i) ;
+            continue ;
+        }
+        has_it = FALSE ;
+        if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
+            EPHYR_LOG_ERROR ("error\n") ;
+        }
+        if (has_it)
+            a_this->adaptors[i].PutImage = ephyrPutImage;
+
+        has_it = FALSE ;
+        if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
+            EPHYR_LOG_ERROR ("error\n") ;
+        }
+        if (has_it)
+            a_this->adaptors[i].PutVideo = ephyrPutVideo;
+
+        has_it = FALSE ;
+        if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
+            EPHYR_LOG_ERROR ("error\n") ;
+        }
+        if (has_it)
+            a_this->adaptors[i].PutStill = ephyrPutStill;
     }
     EPHYR_LOG ("leave\n") ;
     return TRUE ;
@@ -711,6 +764,35 @@ ephyrQueryBestSize (KdScreenInfo *a_info,
     EPHYR_LOG ("leave\n") ;
 }
 
+static int
+ephyrPutVideo (KdScreenInfo *a_screen,
+               DrawablePtr a_drw,
+               short a_vid_x, short a_vid_y,
+               short a_drw_x, short a_drw_y,
+               short a_vid_w, short a_vid_h,
+               short a_drw_w, short a_drw_h,
+               RegionPtr a_clip_region,
+               pointer a_port_priv)
+{
+    EPHYR_LOG ("enter\n") ;
+    return Success ;
+    EPHYR_LOG ("leave\n") ;
+}
+
+static int
+ephyrPutStill (KdScreenInfo *a_screen,
+               DrawablePtr a_drw,
+               short a_vid_x, short a_vid_y,
+               short a_drw_x, short a_drw_y,
+               short a_vid_w, short a_vid_h,
+               short a_drw_w, short a_drw_h,
+               RegionPtr a_clip_region,
+               pointer a_port_priv)
+{
+    EPHYR_LOG ("enter\n") ;
+    return Success ;
+    EPHYR_LOG ("leave\n") ;
+}
 
 static int
 ephyrPutImage (KdScreenInfo *a_info,
commit 1de89239bdfa68ded2ef25fbb7d08369f527f7a9
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Sat Aug 4 01:13:38 2007 +0200

    don't crash when hostX reports an error.
    
            * hw/kdrive/ephyr/ephyrhostvideo.c,h:
              (ephyrHostXVLogXErrorEvent): add this to
              log X error events. Heavily copied from libx11
              (ephyrHostXVErrorHandler): new x error handler that
              logs the error but does not exits.
              (ephyrHostXVInit): add this to be called at the beginning
              of xvideo lifetime. It sets an xerror handler that does not
              exit.
            * hw/kdrive/ephyr/ephyrvideo.c:
              (ephyrXVPrivIsAttrValueValid): this validates an attribute
              value.
              (ephyrSetPortAttribute): before setting an attribute,
              validate the new value so that we don't send a buggy
              request to host X.
            * hw/kdrive/ephyr/*.c: fix case in ephyrvideo code.
            * hw/kdrive/ephyr/ephyr.c: fix a typo

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 2cb7d0b..2febb65 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -610,7 +610,7 @@ ephyrInitScreen (ScreenPtr pScreen)
   if (!ephyrInitVideo (pScreen)) {
       EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
   } else {
-      EPHYR_LOG_ERROR ("initialized xvideo okay\n") ;
+      EPHYR_LOG ("initialized xvideo okay\n") ;
   }
 #endif /*XV*/
   return TRUE;
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index c15a904..1ccd994 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -108,8 +108,141 @@ struct _EphyrHostXVAdaptorArray {
     unsigned int nb_adaptors ;
 };
 
+/*heavily copied from libx11*/
+#define BUFSIZE 2048
+static void
+ephyrHostXVLogXErrorEvent (Display *a_display,
+                           XErrorEvent *a_err_event,
+                           FILE *a_fp)
+{
+    char buffer[BUFSIZ];
+    char mesg[BUFSIZ];
+    char number[32];
+    const char *mtype = "XlibMessage";
+    register _XExtension *ext = (_XExtension *)NULL;
+    _XExtension *bext = (_XExtension *)NULL;
+    Display *dpy = a_display ;
+
+    XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
+    XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
+    (void) fprintf(a_fp, "%s:  %s\n  ", mesg, buffer);
+    XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
+            mesg, BUFSIZ);
+    (void) fprintf(a_fp, mesg, a_err_event->request_code);
+    if (a_err_event->request_code < 128) {
+        sprintf(number, "%d", a_err_event->request_code);
+        XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
+    } else {
+        for (ext = dpy->ext_procs;
+                ext && (ext->codes.major_opcode != a_err_event->request_code);
+                ext = ext->next)
+            ; 
+        if (ext)
+            strcpy(buffer, ext->name);
+        else
+            buffer[0] = '\0';
+    }
+    (void) fprintf(a_fp, " (%s)\n", buffer);
+    if (a_err_event->request_code >= 128) {
+        XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
+                mesg, BUFSIZ);
+        fputs("  ", a_fp);
+        (void) fprintf(a_fp, mesg, a_err_event->minor_code);
+        if (ext) {
+            sprintf(mesg, "%s.%d", ext->name, a_err_event->minor_code);
+            XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
+            (void) fprintf(a_fp, " (%s)", buffer);
+        }
+        fputs("\n", a_fp);
+    }
+    if (a_err_event->error_code >= 128) { 
+        /* kludge, try to find the extension that caused it */
+        buffer[0] = '\0';
+        for (ext = dpy->ext_procs; ext; ext = ext->next) {
+            if (ext->error_string)
+                (*ext->error_string)(dpy, a_err_event->error_code, &ext->codes,
+                        buffer, BUFSIZ);
+            if (buffer[0]) {
+                bext = ext;
+                break;
+            }
+            if (ext->codes.first_error &&
+                    ext->codes.first_error < (int)a_err_event->error_code &&
+                    (!bext || ext->codes.first_error > bext->codes.first_error))
+                bext = ext;
+        }
+        if (bext)
+            sprintf(buffer, "%s.%d", bext->name,
+                    a_err_event->error_code - bext->codes.first_error);
+        else
+            strcpy(buffer, "Value");
+        XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
+        if (mesg[0]) {
+            fputs("  ", a_fp);
+            (void) fprintf(a_fp, mesg, a_err_event->resourceid);
+            fputs("\n", a_fp);
+        }
+        /* let extensions try to print the values */
+        for (ext = dpy->ext_procs; ext; ext = ext->next) {
+            if (ext->error_values)
+                (*ext->error_values)(dpy, a_err_event, a_fp);
+        }
+    } else if ((a_err_event->error_code == BadWindow) ||
+            (a_err_event->error_code == BadPixmap) ||
+            (a_err_event->error_code == BadCursor) ||
+            (a_err_event->error_code == BadFont) ||
+            (a_err_event->error_code == BadDrawable) ||
+            (a_err_event->error_code == BadColor) ||
+            (a_err_event->error_code == BadGC) ||
+            (a_err_event->error_code == BadIDChoice) ||
+            (a_err_event->error_code == BadValue) ||
+            (a_err_event->error_code == BadAtom)) {
+        if (a_err_event->error_code == BadValue)
+            XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
+                    mesg, BUFSIZ);
+        else if (a_err_event->error_code == BadAtom)
+            XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
+                    mesg, BUFSIZ);
+        else
+            XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
+                    mesg, BUFSIZ);
+        fputs("  ", a_fp);
+        (void) fprintf(a_fp, mesg, a_err_event->resourceid);
+        fputs("\n", a_fp);
+    }
+    XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
+            mesg, BUFSIZ);
+    fputs("  ", a_fp);
+    (void) fprintf(a_fp, mesg, a_err_event->serial);
+    XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
+            mesg, BUFSIZ);
+    fputs("\n  ", a_fp);
+    (void) fprintf(a_fp, mesg, dpy->request);
+    fputs("\n", a_fp);
+}
+
+static int
+ephyrHostXVErrorHandler (Display *a_display,
+                         XErrorEvent *a_error_event)
+{
+    EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ;
+    ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ;
+    return Success ;
+}
+
+void
+ephyrHostXVInit (void)
+{
+    static Bool s_initialized ;
+
+    if (s_initialized)
+        return ;
+    XSetErrorHandler (ephyrHostXVErrorHandler) ;
+    s_initialized = TRUE ;
+}
+
 Bool
-EphyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
+ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
 {
     EphyrHostXVAdaptorArray *result=NULL ;
     int ret=0 ;
@@ -140,7 +273,7 @@ out:
 }
 
 void
-EphyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
+ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
 {
     if (!a_adaptors)
         return ;
@@ -153,14 +286,14 @@ EphyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
 }
 
 int
-EphyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
+ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
 {
     EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
     return a_this->nb_adaptors ;
 }
 
 EphyrHostXVAdaptor*
-EphyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
+ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
                            int a_index)
 {
     EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
@@ -171,14 +304,14 @@ EphyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
 }
 
 char
-EphyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
+ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
 {
     EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
     return ((XvAdaptorInfo*)a_this)->type ;
 }
 
 const char*
-EphyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
+ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
 {
     EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
 
@@ -186,7 +319,7 @@ EphyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
 }
 
 EphyrHostVideoFormat*
-EphyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
+ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
                                    int *a_nb_formats)
 {
     EphyrHostVideoFormat *formats=NULL ;
@@ -216,7 +349,7 @@ EphyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
 }
 
 int
-EphyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
+ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
 {
     EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
 
@@ -224,7 +357,7 @@ EphyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
 }
 
 int
-EphyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
+ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
 {
     EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
 
@@ -232,7 +365,7 @@ EphyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
 }
 
 Bool
-EphyrHostXVQueryEncodings (int a_port_id,
+ephyrHostXVQueryEncodings (int a_port_id,
                            EphyrHostEncoding **a_encodings,
                            unsigned int *a_num_encodings)
 {
@@ -271,7 +404,7 @@ EphyrHostXVQueryEncodings (int a_port_id,
 }
 
 void
-EphyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
+ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
                           int a_num_encodings)
 {
     int i=0 ;
@@ -288,7 +421,7 @@ EphyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
 }
 
 void
-EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
+ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
 {
     if (!a_attributes)
         return ;
@@ -296,7 +429,7 @@ EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
 }
 
 Bool
-EphyrHostXVQueryPortAttributes (int a_port_id,
+ephyrHostXVQueryPortAttributes (int a_port_id,
                                 EphyrHostAttribute **a_attributes,
                                 int *a_num_attributes)
 {
@@ -311,7 +444,7 @@ EphyrHostXVQueryPortAttributes (int a_port_id,
 }
 
 Bool
-EphyrHostXVQueryImageFormats (int a_port_id,
+ephyrHostXVQueryImageFormats (int a_port_id,
                               EphyrHostImageFormat **a_formats,
                               int *a_num_format)
 {
@@ -328,13 +461,16 @@ EphyrHostXVQueryImageFormats (int a_port_id,
 }
 
 Bool
-EphyrHostXVSetPortAttribute (int a_port_id,
+ephyrHostXVSetPortAttribute (int a_port_id,
                              int a_atom,
                              int a_attr_value)
 {
     int res=Success ;
 
-    EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, a_attr_value) ;
+    EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n",
+               a_atom,
+               XGetAtomName (hostx_get_display (), a_atom),
+               a_attr_value) ;
 
     res = XvSetPortAttribute (hostx_get_display (),
                               a_port_id,
@@ -344,13 +480,14 @@ EphyrHostXVSetPortAttribute (int a_port_id,
         EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
         return FALSE ;
     }
+    XFlush (hostx_get_display ()) ;
     EPHYR_LOG ("leave\n") ;
 
     return TRUE ;
 }
 
 Bool
-EphyrHostXVGetPortAttribute (int a_port_id,
+ephyrHostXVGetPortAttribute (int a_port_id,
                              int a_atom,
                              int *a_attr_value)
 {
@@ -380,7 +517,7 @@ out:
 }
 
 Bool
-EphyrHostXVQueryBestSize (int a_port_id,
+ephyrHostXVQueryBestSize (int a_port_id,
                           Bool a_motion,
                           unsigned int a_frame_w,
                           unsigned int a_frame_h,
@@ -458,7 +595,7 @@ xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
 }
 
 Bool
-EphyrHostXVQueryImageAttributes (int a_port_id,
+ephyrHostXVQueryImageAttributes (int a_port_id,
                                  int a_image_id /*image fourcc code*/,
                                  unsigned short *a_width,
                                  unsigned short *a_height,
@@ -515,7 +652,7 @@ out:
 }
 
 Bool
-EphyrHostGetAtom (const char* a_name,
+ephyrHostGetAtom (const char* a_name,
                   Bool a_create_if_not_exists,
                   int *a_atom)
 {
@@ -532,20 +669,20 @@ EphyrHostGetAtom (const char* a_name,
 }
 
 char*
-EphyrHostGetAtomName (int a_atom)
+ephyrHostGetAtomName (int a_atom)
 {
     return XGetAtomName (hostx_get_display (), a_atom) ;
 }
 
 void
-EphyrHostFree (void *a_pointer)
+ephyrHostFree (void *a_pointer)
 {
     if (a_pointer)
         XFree (a_pointer) ;
 }
 
 Bool
-EphyrHostXVPutImage (int a_port_id,
+ephyrHostXVPutImage (int a_port_id,
                      int a_image_id,
                      int a_drw_x,
                      int a_drw_y,
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
index 0e97bde..86154bc 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.h
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -84,67 +84,69 @@ typedef struct _EphyrHostImageFormat {
     int scanline_order;          /* XvTopToBottom, XvBottomToTop */
 } EphyrHostImageFormat ;
 
-void EphyrHostFree (void *a_pointer) ;
+void ephyrHostXVInit (void) ;
+
+void ephyrHostFree (void *a_pointer) ;
 
 /*
  * host adaptor array
  */
-Bool EphyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) ;
-void EphyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) ;
-int EphyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) ;
-EphyrHostXVAdaptor* EphyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
+Bool ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) ;
+void ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) ;
+int ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) ;
+EphyrHostXVAdaptor* ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
                                                int a_index) ;
 
 /*
  * host adaptor
  */
 
-char EphyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) ;
-const char* EphyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) ;
-EphyrHostVideoFormat* EphyrHostXVAdaptorGetVideoFormats
+char ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) ;
+const char* ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) ;
+EphyrHostVideoFormat* ephyrHostXVAdaptorGetVideoFormats
                                                 (const EphyrHostXVAdaptor *a_this,
                                                  int *a_nb_formats) ;
-int EphyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ;
-int EphyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ;
+int ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ;
+int ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ;
 
 /*
  * encoding
  */
-Bool EphyrHostXVQueryEncodings (int a_port_id,
+Bool ephyrHostXVQueryEncodings (int a_port_id,
                                 EphyrHostEncoding **a_encodings,
                                 unsigned int *a_num_encodings) ;
 
-void EphyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
+void ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
                                int a_num_encodings) ;
 
 /*
  * attribute
  */
-Bool EphyrHostXVQueryPortAttributes (int a_port_id,
+Bool ephyrHostXVQueryPortAttributes (int a_port_id,
                                      EphyrHostAttribute **a_attributes,
                                      int *a_num_attributes) ;
 
-void EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes) ;
+void ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes) ;
 /*
  * image format
  */
 
-Bool EphyrHostXVQueryImageFormats (int a_port_id,
+Bool ephyrHostXVQueryImageFormats (int a_port_id,
                                    EphyrHostImageFormat **a_formats,
                                    int *a_num_format) ;
 /*
  * Port Attribute Get/Set
  */
-Bool EphyrHostXVSetPortAttribute (int a_port_id,
+Bool ephyrHostXVSetPortAttribute (int a_port_id,
                                   int a_atom,
                                   int a_attr_value) ;
-Bool EphyrHostXVGetPortAttribute (int a_port_id,
+Bool ephyrHostXVGetPortAttribute (int a_port_id,
                                   int a_atom,
                                   int *a_attr_value) ;
 /*
  *size query
  */
-Bool EphyrHostXVQueryBestSize (int a_port_id,
+Bool ephyrHostXVQueryBestSize (int a_port_id,
                                Bool a_motion,
                                unsigned int a_frame_w,
                                unsigned int a_frame_h,
@@ -153,7 +155,7 @@ Bool EphyrHostXVQueryBestSize (int a_port_id,
                                unsigned int *a_actual_w,
                                unsigned int *a_actual_h) ;
 
-Bool EphyrHostXVQueryImageAttributes (int a_port_id,
+Bool ephyrHostXVQueryImageAttributes (int a_port_id,
                                       int a_image_id /*image fourcc code*/,
                                       unsigned short *a_width,
                                       unsigned short *a_height,
@@ -163,16 +165,16 @@ Bool EphyrHostXVQueryImageAttributes (int a_port_id,
 /*
  * atom
  */
-Bool EphyrHostGetAtom (const char* a_name,
+Bool ephyrHostGetAtom (const char* a_name,
                        Bool a_create_if_not_exists,
                        int *a_atom) ;
-char* EphyrHostGetAtomName (int a_atom) ;
+char* ephyrHostGetAtomName (int a_atom) ;
 
 /*
  *PutImage
  * (ignore clipping for now)
  */
-Bool EphyrHostXVPutImage (int a_port_id,
+Bool ephyrHostXVPutImage (int a_port_id,
                           int a_image_id,
                           int a_drw_x,
                           int a_drw_y,
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 9cd479b..5cd9d17 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -47,6 +47,7 @@ typedef struct _EphyrXVPriv EphyrXVPriv ;
 
 struct _EphyrPortPriv {
     int port_number ;
+    KdVideoAdaptorPtr current_adaptor ;
     EphyrXVPriv *xv_priv;
 };
 typedef struct _EphyrPortPriv EphyrPortPriv ;
@@ -55,31 +56,38 @@ static Bool DoSimpleClip (BoxPtr a_dst_drw,
                           BoxPtr a_clipper,
                           BoxPtr a_result) ;
 
-static Bool EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
+static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
 
-static Bool EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
+static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
 
-static EphyrXVPriv* EphyrXVPrivNew (void) ;
-static void EphyrXVPrivDelete (EphyrXVPriv *a_this) ;
-static Bool EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
-static Bool EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
-static Bool EphyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+static EphyrXVPriv* ephyrXVPrivNew (void) ;
+static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
                                          ScreenPtr a_screen) ;
-static void EphyrStopVideo (KdScreenInfo *a_info,
+
+static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
+                                         int a_attrs_len,
+                                         const char *a_attr_name,
+                                         int a_attr_value,
+                                         Bool *a_is_valid) ;
+
+static void ephyrStopVideo (KdScreenInfo *a_info,
                             pointer a_xv_priv,
                             Bool a_exit);
 
-static int EphyrSetPortAttribute (KdScreenInfo *a_info,
+static int ephyrSetPortAttribute (KdScreenInfo *a_info,
                                   Atom a_attr_name,
                                   int a_attr_value,
                                   pointer a_port_priv);
 
-static int EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
+static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
                                   Atom a_attr_name,
                                   int *a_attr_value,
                                   pointer a_port_priv);
 
-static void EphyrQueryBestSize (KdScreenInfo *a_info,
+static void ephyrQueryBestSize (KdScreenInfo *a_info,
                                 Bool a_motion,
                                 short a_src_w,
                                 short a_src_h,
@@ -89,7 +97,7 @@ static void EphyrQueryBestSize (KdScreenInfo *a_info,
                                 unsigned int *a_prefered_h,
                                 pointer a_port_priv);
 
-static int EphyrPutImage (KdScreenInfo *a_info,
+static int ephyrPutImage (KdScreenInfo *a_info,
                           DrawablePtr a_drawable,
                           short a_src_x,
                           short a_src_y,
@@ -107,7 +115,7 @@ static int EphyrPutImage (KdScreenInfo *a_info,
                           RegionPtr a_clipping_region,
                           pointer a_port_priv);
 
-static int EphyrQueryImageAttributes (KdScreenInfo *a_info,
+static int ephyrQueryImageAttributes (KdScreenInfo *a_info,
                                       int a_id,
                                       unsigned short *a_w,
                                       unsigned short *a_h,
@@ -165,7 +173,7 @@ DoSimpleClip (BoxPtr a_dst_box,
 }
 
 static Bool
-EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
+ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
 {
     char *atom_name=NULL;
     int host_atom=None ;
@@ -180,7 +188,7 @@ EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
     if (!atom_name)
         return FALSE ;
 
-    if (!EphyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
+    if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
         EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n",
                          atom_name) ;
         return FALSE ;
@@ -190,7 +198,7 @@ EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
 }
 
 static Bool
-EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
+ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
 {
     Bool is_ok=FALSE ;
     char *atom_name=NULL ;
@@ -198,7 +206,7 @@ EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
 
     EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ;
 
-    atom_name = EphyrHostGetAtomName (a_host_atom) ;
+    atom_name = ephyrHostGetAtomName (a_host_atom) ;
     if (!atom_name)
         goto out ;
 
@@ -211,7 +219,7 @@ EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
 
 out:
     if (atom_name) {
-        EphyrHostFree (atom_name) ;
+        ephyrHostFree (atom_name) ;
     }
     return is_ok ;
 }
@@ -234,13 +242,13 @@ ephyrInitVideo (ScreenPtr pScreen)
         return FALSE ;
     }
 
-    xv_priv = EphyrXVPrivNew () ;
+    xv_priv = ephyrXVPrivNew () ;
     if (!xv_priv) {
         EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
         return FALSE ;
     }
 
-    if (!EphyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
+    if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
         EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
         return FALSE ;
     }
@@ -248,7 +256,7 @@ ephyrInitVideo (ScreenPtr pScreen)
 }
 
 static EphyrXVPriv*
-EphyrXVPrivNew (void)
+ephyrXVPrivNew (void)
 {
     EphyrXVPriv *xv_priv=NULL ;
 
@@ -259,11 +267,14 @@ EphyrXVPrivNew (void)
         EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ;
         goto error ;
     }
-    if (!EphyrXVPrivQueryHostAdaptors (xv_priv)) {
+
+    ephyrHostXVInit () ;
+
+    if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) {
         EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
         goto error ;
     }
-    if (!EphyrXVPrivSetAdaptorsHooks (xv_priv)) {
+    if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) {
         EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
         goto error ;
     }
@@ -273,21 +284,21 @@ EphyrXVPrivNew (void)
 
 error:
     if (xv_priv) {
-        EphyrXVPrivDelete (xv_priv) ;
+        ephyrXVPrivDelete (xv_priv) ;
         xv_priv = NULL ;
     }
     return NULL ;
 }
 
 static void
-EphyrXVPrivDelete (EphyrXVPriv *a_this)
+ephyrXVPrivDelete (EphyrXVPriv *a_this)
 {
     EPHYR_LOG ("enter\n") ;
 
     if (!a_this)
         return ;
     if (a_this->host_adaptors) {
-        EphyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
+        ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
         a_this->host_adaptors = NULL ;
     }
     if (a_this->adaptors) {
@@ -343,7 +354,7 @@ portAttributesDup (EphyrHostAttribute *a_encodings,
 }
 
 static Bool
-EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
+ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
 {
     EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
     EphyrHostVideoFormat *video_formats=NULL ;
@@ -359,13 +370,13 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
 
     EPHYR_LOG ("enter\n") ;
 
-    if (!EphyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
+    if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
         EPHYR_LOG_ERROR ("failed to query host adaptors\n") ;
         goto out ;
     }
     if (a_this->host_adaptors)
         a_this->num_adaptors =
-                    EphyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
+                    ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
     if (a_this->num_adaptors < 0) {
         EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
         goto out ;
@@ -385,20 +396,20 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
     for (i=0; i < a_this->num_adaptors; i++) {
         int j=0 ;
         cur_host_adaptor =
-                   EphyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+                   ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
         if (!cur_host_adaptor)
             continue ;
         a_this->adaptors[i].type =
-                        EphyrHostXVAdaptorGetType (cur_host_adaptor) ;
+                        ephyrHostXVAdaptorGetType (cur_host_adaptor) ;
         a_this->adaptors[i].type |= XvWindowMask ;
         a_this->adaptors[i].flags =
                         VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
-        if (EphyrHostXVAdaptorGetName (cur_host_adaptor))
+        if (ephyrHostXVAdaptorGetName (cur_host_adaptor))
             a_this->adaptors[i].name =
-                    strdup (EphyrHostXVAdaptorGetName (cur_host_adaptor)) ;
+                    strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ;
         else
             a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
-        base_port_id = EphyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
+        base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
         if (base_port_id < 0) {
             EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
             continue ;
@@ -406,7 +417,7 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
         if (!s_base_port_id)
             s_base_port_id = base_port_id ;
 
-        if (!EphyrHostXVQueryEncodings (base_port_id,
+        if (!ephyrHostXVQueryEncodings (base_port_id,
                                         &encodings,
                                         &num_encodings)) {
             EPHYR_LOG_ERROR ("failed to get encodings for port port id %d,"
@@ -418,12 +429,12 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
         a_this->adaptors[i].pEncodings =
                             videoEncodingDup (encodings, num_encodings) ;
         video_formats = (EphyrHostVideoFormat*)
-            EphyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
+            ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
                                                &num_video_formats);
         a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
         a_this->adaptors[i].nFormats = num_video_formats ;
         a_this->adaptors[i].nPorts =
-                            EphyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+                            ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
         a_this->adaptors[i].pPortPrivates =
                 xcalloc (a_this->adaptors[i].nPorts,
                          sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
@@ -433,10 +444,11 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
                 (EphyrPortPriv*)
                     &a_this->adaptors[i].pPortPrivates[port_priv_offset + j];
             port_priv->port_number = base_port_id + j;
+            port_priv->current_adaptor = &a_this->adaptors[i] ;
             port_priv->xv_priv = a_this ;
             a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
         }
-        if (!EphyrHostXVQueryPortAttributes (base_port_id,
+        if (!ephyrHostXVQueryPortAttributes (base_port_id,
                                              &attributes,
                                              &num_attributes)) {
             EPHYR_LOG_ERROR ("failed to get port attribute "
@@ -446,7 +458,7 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
         a_this->adaptors[i].pAttributes =
                     portAttributesDup (attributes, num_attributes);
         a_this->adaptors[i].nAttributes = num_attributes ;
-        if (!EphyrHostXVQueryImageFormats (base_port_id,
+        if (!ephyrHostXVQueryImageFormats (base_port_id,
                                            &image_formats,
                                            &num_formats)) {
             EPHYR_LOG_ERROR ("failed to get image formats "
@@ -460,11 +472,11 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
 
 out:
     if (encodings) {
-        EphyrHostEncodingsDelete (encodings, num_encodings) ;
+        ephyrHostEncodingsDelete (encodings, num_encodings) ;
         encodings = NULL ;
     }
     if (attributes) {
-        EphyrHostAttributesDelete (attributes) ;
+        ephyrHostAttributesDelete (attributes) ;
         attributes = NULL ;
     }
     EPHYR_LOG ("leave\n") ;
@@ -472,7 +484,7 @@ out:
 }
 
 static Bool
-EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
+ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
 {
     int i=0 ;
 
@@ -481,19 +493,19 @@ EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
     EPHYR_LOG ("enter\n") ;
 
     for (i=0; i < a_this->num_adaptors; i++) {
-        a_this->adaptors[i].StopVideo = EphyrStopVideo ;
-        a_this->adaptors[i].SetPortAttribute = EphyrSetPortAttribute ;
-        a_this->adaptors[i].GetPortAttribute = EphyrGetPortAttribute ;
-        a_this->adaptors[i].QueryBestSize = EphyrQueryBestSize ;
-        a_this->adaptors[i].PutImage = EphyrPutImage;
-        a_this->adaptors[i].QueryImageAttributes = EphyrQueryImageAttributes ;
+        a_this->adaptors[i].StopVideo = ephyrStopVideo ;
+        a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
+        a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
+        a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ;
+        a_this->adaptors[i].PutImage = ephyrPutImage;
+        a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ;
     }
     EPHYR_LOG ("leave\n") ;
     return TRUE ;
 }
 
 static Bool
-EphyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
                              ScreenPtr a_screen)
 {
     KdScreenPriv(a_screen);
@@ -540,23 +552,55 @@ out:
     return is_ok ;
 }
 
+static Bool
+ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
+                             int a_attrs_len,
+                             const char *a_attr_name,
+                             int a_attr_value,
+                             Bool *a_is_valid)
+{
+    int i=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid,
+                              FALSE) ;
+
+    for (i=0; i < a_attrs_len; i++) {
+        if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name))
+            continue ;
+        if (a_attrs[i].min_value > a_attr_value ||
+            a_attrs[i].max_value < a_attr_value) {
+            *a_is_valid = FALSE ;
+        } else {
+            *a_is_valid = TRUE ;
+        }
+        return TRUE ;
+    }
+    return FALSE ;
+}
+
 static void
-EphyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
+ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
 {
     EPHYR_LOG ("enter\n") ;
     EPHYR_LOG ("leave\n") ;
 }
 
 static int
-EphyrSetPortAttribute (KdScreenInfo *a_info,
+ephyrSetPortAttribute (KdScreenInfo *a_info,
                        Atom a_attr_name,
                        int a_attr_value,
                        pointer a_port_priv)
 {
     int res=Success, host_atom=0 ;
     EphyrPortPriv *port_priv = a_port_priv ;
+    Bool is_attr_valid=FALSE ;
 
     EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+    EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ;
+    EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes,
+                              BadMatch) ;
+    EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes,
+                              BadMatch) ;
     EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
 
     EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n",
@@ -565,13 +609,30 @@ EphyrSetPortAttribute (KdScreenInfo *a_info,
                NameForAtom (a_attr_name),
                a_attr_value) ;
 
-    if (!EphyrLocalAtomToHost (a_attr_name, &host_atom)) {
+    if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
         EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
         res = BadMatch ;
         goto out ;
     }
 
-    if (!EphyrHostXVSetPortAttribute (port_priv->port_number,
+    if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes,
+                                      port_priv->current_adaptor->nAttributes,
+                                      NameForAtom (a_attr_name),
+                                      a_attr_value,
+                                      &is_attr_valid)) {
+        EPHYR_LOG_ERROR ("failed to validate attribute %s\n",
+                         NameForAtom (a_attr_name)) ;
+        res = BadMatch ;
+        goto out ;
+    }
+    if (!is_attr_valid) {
+        EPHYR_LOG_ERROR ("attribute %s is not valid\n",
+                         NameForAtom (a_attr_name)) ;
+        res = BadMatch ;
+        goto out ;
+    }
+
+    if (!ephyrHostXVSetPortAttribute (port_priv->port_number,
                                       host_atom,
                                       a_attr_value)) {
         EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
@@ -586,7 +647,7 @@ out:
 }
 
 static int
-EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
+ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
                        Atom a_attr_name,
                        int *a_attr_value,
                        pointer a_port_priv)
@@ -602,13 +663,13 @@ EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
                (int)a_attr_name,
                NameForAtom (a_attr_name)) ;
 
-    if (!EphyrLocalAtomToHost (a_attr_name, &host_atom)) {
+    if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
         EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
         res = BadMatch ;
         goto out ;
     }
 
-    if (!EphyrHostXVGetPortAttribute (port_priv->port_number,
+    if (!ephyrHostXVGetPortAttribute (port_priv->port_number,
                                       host_atom,
                                       a_attr_value)) {
         EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
@@ -623,7 +684,7 @@ out:
 }
 
 static void
-EphyrQueryBestSize (KdScreenInfo *a_info,
+ephyrQueryBestSize (KdScreenInfo *a_info,
                     Bool a_motion,
                     short a_src_w,
                     short a_src_h,
@@ -639,7 +700,7 @@ EphyrQueryBestSize (KdScreenInfo *a_info,
     EPHYR_RETURN_IF_FAIL (port_priv) ;
 
     EPHYR_LOG ("enter\n") ;
-    res = EphyrHostXVQueryBestSize (port_priv->port_number,
+    res = ephyrHostXVQueryBestSize (port_priv->port_number,
                                     a_motion,
                                     a_src_w, a_src_h,
                                     a_drw_w, a_drw_h,
@@ -652,7 +713,7 @@ EphyrQueryBestSize (KdScreenInfo *a_info,
 
 
 static int
-EphyrPutImage (KdScreenInfo *a_info,
+ephyrPutImage (KdScreenInfo *a_info,
                DrawablePtr a_drawable,
                short a_src_x,
                short a_src_y,
@@ -696,7 +757,7 @@ EphyrPutImage (KdScreenInfo *a_info,
     drw_w = clipped_area.x2 - clipped_area.x1 ;
     drw_h = clipped_area.y2 - clipped_area.y1 ;
 
-    if (!EphyrHostXVPutImage (port_priv->port_number,
+    if (!ephyrHostXVPutImage (port_priv->port_number,
                               a_id,
                               drw_x, drw_y, drw_w, drw_h,
                               a_src_x, a_src_y, a_src_w, a_src_h,
@@ -713,7 +774,7 @@ out:
 }
 
 static int
-EphyrQueryImageAttributes (KdScreenInfo *a_info,
+ephyrQueryImageAttributes (KdScreenInfo *a_info,
                            int a_id,
                            unsigned short *a_w,
                            unsigned short *a_h,
@@ -727,7 +788,7 @@ EphyrQueryImageAttributes (KdScreenInfo *a_info,
     EPHYR_LOG ("enter: dim (%dx%d), pitches: %#x, offsets: %#x\n",
                *a_w, *a_h, (unsigned int)a_pitches, (unsigned int)a_offsets) ;
 
-   if (!EphyrHostXVQueryImageAttributes (s_base_port_id,
+   if (!ephyrHostXVQueryImageAttributes (s_base_port_id,
                                          a_id,
                                          a_w, a_h,
                                          &image_size,
commit 207714b60d18e94bbe2d755a431dbb29fe5677f7
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Fri Aug 3 01:10:39 2007 +0200

    first implementation of putimage
    
            * hw/kdrive/ephyr/ephyrhostvideo.c,h:
              (EphyrHostXVPutImage): first implementation. does not
              support clipping regions yet.
            * hw/kdrive/ephyr/ephyrvideo.c:
              (DoSimpleClip): clip using a clipping box. Does not
               support regions yet.
              (EphyrPutImage): first implementation.
               Uses a simple clipping rectangle, no region yet.
            * hw/kdrive/ephyr/hostx.c:
              (hostx_get_window): added this to get the main
              window of the host x.

diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index fa1e15b..c15a904 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -544,3 +544,56 @@ EphyrHostFree (void *a_pointer)
         XFree (a_pointer) ;
 }
 
+Bool
+EphyrHostXVPutImage (int a_port_id,
+                     int a_image_id,
+                     int a_drw_x,
+                     int a_drw_y,
+                     int a_drw_w,
+                     int a_drw_h,
+                     int a_src_x,
+                     int a_src_y,
+                     int a_src_w,
+                     int a_src_h,
+                     int a_image_width,
+                     int a_image_height,
+                     unsigned char *a_buf)
+{
+    Bool is_ok=TRUE ;
+    XvImage *xv_image=NULL ;
+    GC gc=0 ;
+    XGCValues gc_values;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    gc = XCreateGC (hostx_get_display (), hostx_get_window (), 0L, &gc_values);
+    if (!gc) {
+        EPHYR_LOG_ERROR ("failed to create gc \n") ;
+        goto out ;
+    }
+    xv_image = (XvImage*) XvCreateImage (hostx_get_display (),
+                                         a_port_id, a_image_id,
+                                         NULL, a_image_width, a_image_height) ;
+    if (!xv_image) {
+        EPHYR_LOG_ERROR ("failed to create image\n") ;
+        goto out ;
+    }
+    xv_image->data = (char*)a_buf ;
+    XvPutImage (hostx_get_display (), a_port_id, hostx_get_window (),
+                gc, xv_image,
+                a_src_x, a_src_y, a_src_w, a_src_h,
+                a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+    XFlush (hostx_get_display ()) ;
+    is_ok = TRUE ;
+
+out:
+
+    EPHYR_LOG ("leave\n") ;
+    if (xv_image) {
+        XFree (xv_image) ;
+        xv_image = NULL ;
+    }
+    return is_ok ;
+}
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
index fa3eba0..0e97bde 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.h
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -168,6 +168,23 @@ Bool EphyrHostGetAtom (const char* a_name,
                        int *a_atom) ;
 char* EphyrHostGetAtomName (int a_atom) ;
 
+/*
+ *PutImage
+ * (ignore clipping for now)
+ */
+Bool EphyrHostXVPutImage (int a_port_id,
+                          int a_image_id,
+                          int a_drw_x,
+                          int a_drw_y,
+                          int a_drw_w,
+                          int a_drw_h,
+                          int a_src_x,
+                          int a_src_y,
+                          int a_src_w,
+                          int a_src_h,
+                          int a_image_width,
+                          int a_image_height,
+                          unsigned char *a_buf) ;
 
 #endif /*__EPHYRHOSTVIDEO_H__*/
 
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 6f0bc8f..9cd479b 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -51,6 +51,10 @@ struct _EphyrPortPriv {
 };
 typedef struct _EphyrPortPriv EphyrPortPriv ;
 
+static Bool DoSimpleClip (BoxPtr a_dst_drw,
+                          BoxPtr a_clipper,
+                          BoxPtr a_result) ;
+
 static Bool EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
 
 static Bool EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
@@ -116,6 +120,51 @@ static int s_base_port_id ;
  * ************/
 
 static Bool
+DoSimpleClip (BoxPtr a_dst_box,
+              BoxPtr a_clipper,
+              BoxPtr a_result)
+{
+    BoxRec dstClippedBox ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_dst_box && a_clipper && a_result, FALSE) ;
+
+    /*
+     * setup the clipbox inside the destination.
+     */
+    dstClippedBox.x1 = a_dst_box->x1 ;
+    dstClippedBox.x2 = a_dst_box->x2 ;
+    dstClippedBox.y1 = a_dst_box->y1 ;
+    dstClippedBox.y2 = a_dst_box->y2 ;
+
+    /*
+     * if the cliper leftmost edge is inside
+     * the destination area then the leftmost edge of the resulting
+     * clipped box is the leftmost edge of the cliper.
+     */
+    if (a_clipper->x1 > dstClippedBox.x1)
+        dstClippedBox.x1 = a_clipper->x1 ;
+
+    /*
+     * if the cliper top edge is inside the destination area
+     * then the bottom horizontal edge of the resulting clipped box
+     * is the bottom edge of the cliper
+     */
+    if (a_clipper->y1 > dstClippedBox.y1)
+        dstClippedBox.y1 = a_clipper->y1 ;
+
+    /*ditto for right edge*/
+    if (a_clipper->x2 < dstClippedBox.x2)
+        dstClippedBox.x2 = a_clipper->x2 ;
+
+    /*ditto for bottom edge*/
+    if (a_clipper->y2 < dstClippedBox.y2)
+        dstClippedBox.y2 = a_clipper->y2 ;
+
+    memcpy (a_result, &dstClippedBox, sizeof (dstClippedBox)) ;
+    return TRUE ;
+}
+
+static Bool
 EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
 {
     char *atom_name=NULL;
@@ -601,6 +650,7 @@ EphyrQueryBestSize (KdScreenInfo *a_info,
     EPHYR_LOG ("leave\n") ;
 }
 
+
 static int
 EphyrPutImage (KdScreenInfo *a_info,
                DrawablePtr a_drawable,
@@ -620,9 +670,46 @@ EphyrPutImage (KdScreenInfo *a_info,
                RegionPtr a_clipping_region,
                pointer a_port_priv)
 {
+    EphyrPortPriv *port_priv = a_port_priv ;
+    BoxRec clipped_area, dst_box ;
+    int result=BadImplementation ;
+    int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
+
     EPHYR_LOG ("enter\n") ;
-    return 0 ;
+
+    dst_box.x1 = a_drw_x ;
+    dst_box.x2 = a_drw_x + a_drw_w;
+    dst_box.y1 = a_drw_y ;
+    dst_box.y2 = a_drw_y + a_drw_h;
+
+    if (!DoSimpleClip (&dst_box,
+                       REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+                       &clipped_area)) {
+        EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+        goto out ;
+    }
+
+    drw_x = clipped_area.x1 ;
+    drw_y = clipped_area.y1 ;
+    drw_w = clipped_area.x2 - clipped_area.x1 ;
+    drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+    if (!EphyrHostXVPutImage (port_priv->port_number,
+                              a_id,
+                              drw_x, drw_y, drw_w, drw_h,
+                              a_src_x, a_src_y, a_src_w, a_src_h,
+                              a_width, a_height, a_buf)) {
+        EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
+        goto out ;
+    }
+
+    result = Success ;
+
+out:
     EPHYR_LOG ("leave\n") ;
+    return result ;
 }
 
 static int
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 11cfe26..8a2762f 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -962,3 +962,8 @@ hostx_get_display(void)
     return HostX.dpy ;
 }
 
+int
+hostx_get_window(void)
+{
+    return HostX.win ;
+}
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index dc8eb99..1d8cd70 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -175,4 +175,7 @@ hostx_get_event(EphyrHostXEvent *ev);
 void*
 hostx_get_display(void) ;
 
+int
+hostx_get_window(void) ;
+
 #endif
commit aa478e09e25a1cb19b808e7e52b2ee155e34f03b
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Thu Aug 2 12:49:36 2007 +0200

    make properties setting/query code work and hopefully complete.
    
            * hw/kdrive/ephyr/ephyrhostvideo.c,h:
             (EphyrHostXVQueryImageAttributes): add this call. It calls
             XvQueryBestSize xserver entry point. It uses the protocol
             level machinery because Xvlib does not expose that entry point
             as a C function.
             (EphyrHostXVQueryBestSize): added this wrapper around XvQueryBestSize().
             (EphyrHostGetAtom, EphyrHostGetAtomName): added this to get
              an atom or atom name from the host server
            * hw/kdrive/ephyr/ephyrvideo.c:
              (EphyrSetPortAttribute): convert the atom into an host server
              server atom before attacking the host server with it, because in
              in its current form, the input atom is only valid in xephyr.
              This fix makes this call work.
              (EphyrGetPortAttribute): ditto.
              (EphyrQueryBestSize): implement this.
              (EphyrQueryImageAttributes): implement this.

diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index ed6dbb0..fa1e15b 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -29,7 +29,12 @@
 #include <kdrive-config.h>
 #endif
 #include <X11/Xutil.h>
+#include <X11/Xlibint.h>
 #include <X11/extensions/Xvlib.h>
+#include <X11/extensions/Xvproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#define _HAVE_XALLOC_DECLS
 
 #include "hostx.h"
 #include "ephyrhostvideo.h"
@@ -43,6 +48,61 @@
 #define FALSE 0
 #endif /*FALSE*/
 
+static XExtensionInfo _xv_info_data;
+static XExtensionInfo *xv_info = &_xv_info_data;
+static char *xv_extension_name = XvName;
+static char *xv_error_string(Display *dpy, int code, XExtCodes *codes,
+                             char * buf, int n);
+static int xv_close_display(Display *dpy, XExtCodes *codes);
+static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire);
+
+static XExtensionHooks xv_extension_hooks = {
+    NULL,                               /* create_gc */
+    NULL,                               /* copy_gc */
+    NULL,                               /* flush_gc */
+    NULL,                               /* free_gc */
+    NULL,                               /* create_font */
+    NULL,                               /* free_font */
+    xv_close_display,                   /* close_display */
+    xv_wire_to_event,                   /* wire_to_event */
+    NULL,                               /* event_to_wire */
+    NULL,                               /* error */
+    xv_error_string                     /* error_string */
+};
+
+
+static char *xv_error_list[] =
+{
+   "BadPort",       /* XvBadPort     */
+   "BadEncoding",   /* XvBadEncoding */
+   "BadControl"     /* XvBadControl  */
+};
+
+
+#define XvCheckExtension(dpy, i, val) \
+  XextCheckExtension(dpy, i, xv_extension_name, val)
+#define XvGetReq(name, req) \
+        WORD64ALIGN\
+        if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
+                _XFlush(dpy);\
+        req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
+        req->reqType = info->codes->major_opcode;\
+        req->xvReqType = xv_##name; \
+        req->length = (SIZEOF(xv##name##Req))>>2;\
+        dpy->bufptr += SIZEOF(xv##name##Req);\
+        dpy->request++
+
+static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
+
+
+static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
+                                   xv_extension_name,
+                                   &xv_extension_hooks,
+                                   XvNumEvents, NULL)
+
+static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
+                                   XvNumErrors, xv_error_list)
+
 struct _EphyrHostXVAdaptorArray {
     XvAdaptorInfo *adaptors ;
     unsigned int nb_adaptors ;
@@ -59,7 +119,7 @@ EphyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
 
     EPHYR_LOG ("enter\n") ;
 
-    result = Xcalloc (sizeof (EphyrHostXVAdaptorArray)) ;
+    result = Xcalloc (1, sizeof (EphyrHostXVAdaptorArray)) ;
     if (!result)
         goto out ;
 
@@ -137,7 +197,7 @@ EphyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
     EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
 
     nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
-    formats = Xcalloc (nb_formats * sizeof (EphyrHostVideoFormat)) ;
+    formats = Xcalloc (nb_formats, sizeof (EphyrHostVideoFormat)) ;
     for (i=0; i < nb_formats; i++) {
         memset (&visual_info_template, 0, sizeof (visual_info_template)) ;
         visual_info_template.visualid =
@@ -188,7 +248,7 @@ EphyrHostXVQueryEncodings (int a_port_id,
                             &num_encodings,
                             &encoding_info) ;
     if (num_encodings && encoding_info) {
-        encodings = Xcalloc (num_encodings * sizeof (EphyrHostEncoding)) ;
+        encodings = Xcalloc (num_encodings, sizeof (EphyrHostEncoding)) ;
         for (i=0; i<num_encodings; i++) {
             encodings[i].id = encoding_info[i].encoding_id ;
             encodings[i].name = strdup (encoding_info[i].name) ;
@@ -242,9 +302,10 @@ EphyrHostXVQueryPortAttributes (int a_port_id,
 {
     EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
 
-    *a_attributes = (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
-                                                                a_port_id,
-                                                                a_num_attributes);
+    *a_attributes =
+        (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
+                                                    a_port_id,
+                                                    a_num_attributes);
 
     return TRUE ;
 }
@@ -258,7 +319,9 @@ EphyrHostXVQueryImageFormats (int a_port_id,
 
     EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ;
 
-    result = XvListImageFormats (hostx_get_display (), a_port_id, a_num_format) ;
+    result = XvListImageFormats (hostx_get_display (),
+                                 a_port_id,
+                                 a_num_format) ;
     *a_formats = (EphyrHostImageFormat*) result ;
     return TRUE ;
 
@@ -271,6 +334,8 @@ EphyrHostXVSetPortAttribute (int a_port_id,
 {
     int res=Success ;
 
+    EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, a_attr_value) ;
+
     res = XvSetPortAttribute (hostx_get_display (),
                               a_port_id,
                               a_atom,
@@ -279,6 +344,8 @@ EphyrHostXVSetPortAttribute (int a_port_id,
         EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
         return FALSE ;
     }
+    EPHYR_LOG ("leave\n") ;
+
     return TRUE ;
 }
 
@@ -288,16 +355,192 @@ EphyrHostXVGetPortAttribute (int a_port_id,
                              int *a_attr_value)
 {
     int res=Success ;
+    Bool ret=FALSE ;
 
     EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ;
 
+    EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
+               a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ;
+
     res = XvGetPortAttribute (hostx_get_display (),
                               a_port_id,
                               a_atom,
                               a_attr_value) ;
     if (res != Success) {
         EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ;
+        goto out ;
+    }
+    EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ;
+
+    ret = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return ret ;
+}
+
+Bool
+EphyrHostXVQueryBestSize (int a_port_id,
+                          Bool a_motion,
+                          unsigned int a_frame_w,
+                          unsigned int a_frame_h,
+                          unsigned int a_drw_w,
+                          unsigned int a_drw_h,
+                          unsigned int *a_actual_w,
+                          unsigned int *a_actual_h)
+{
+    int res=0 ;
+    Bool is_ok=FALSE ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ;
+
+    EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n",
+               a_frame_w, a_frame_h,
+               a_drw_w, a_drw_h) ;
+
+    res = XvQueryBestSize (hostx_get_display (),
+                           a_port_id,
+                           a_motion,
+                           a_frame_w, a_frame_h,
+                           a_drw_w, a_drw_h,
+                           a_actual_w, a_actual_h) ;
+    if (res != Success) {
+        EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ;
+        goto out ;
+    }
+
+    EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ;
+
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+static Bool
+xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
+{
+    XExtDisplayInfo *info = xv_find_display (dpy);
+    XvEvent *re    = (XvEvent *)host;
+    xvEvent *event = (xvEvent *)wire;
+
+    XvCheckExtension(dpy, info, False);
+
+    switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
+        case XvVideoNotify:
+            re->xvvideo.type = event->u.u.type & 0x7f;
+            re->xvvideo.serial =
+            _XSetLastRequestRead(dpy, (xGenericReply *)event);
+            re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
+            re->xvvideo.display = dpy;
+            re->xvvideo.time = event->u.videoNotify.time;
+            re->xvvideo.reason = event->u.videoNotify.reason;
+            re->xvvideo.drawable = event->u.videoNotify.drawable;
+            re->xvvideo.port_id = event->u.videoNotify.port;
+            break;
+        case XvPortNotify:
+            re->xvport.type = event->u.u.type & 0x7f;
+            re->xvport.serial =
+            _XSetLastRequestRead(dpy, (xGenericReply *)event);
+            re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
+            re->xvport.display = dpy;
+            re->xvport.time = event->u.portNotify.time;
+            re->xvport.port_id = event->u.portNotify.port;
+            re->xvport.attribute = event->u.portNotify.attribute;
+            re->xvport.value = event->u.portNotify.value;
+            break;
+        default:
+            return False;
+    }
+
+    return True ;
+}
+
+Bool
+EphyrHostXVQueryImageAttributes (int a_port_id,
+                                 int a_image_id /*image fourcc code*/,
+                                 unsigned short *a_width,
+                                 unsigned short *a_height,
+                                 int *a_image_size,
+                                 int *a_pitches,
+                                 int *a_offsets)
+{
+    Display *dpy = hostx_get_display () ;
+    Bool ret=FALSE ;
+    XExtDisplayInfo *info = xv_find_display (dpy);
+    xvQueryImageAttributesReq *req=NULL;
+    xvQueryImageAttributesReply rep;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ;
+    EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ;
+    EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ;
+
+    XvCheckExtension (dpy, info, FALSE);
+
+    LockDisplay (dpy);
+
+    XvGetReq (QueryImageAttributes, req);
+    req->id = a_image_id;
+    req->port = a_port_id;
+    req->width = *a_width;
+    req->height = *a_height;
+    /*
+     * read the reply
+     */
+    if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
+        EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ;
+        goto out ;
+    }
+    if (a_pitches && a_offsets) {
+        _XRead (dpy,
+                (char*)a_pitches,
+                rep.num_planes << 2);
+        _XRead (dpy,
+                (char*)a_offsets,
+                rep.num_planes << 2);
+    } else {
+        _XEatData(dpy, rep.length << 2);
+    }
+    *a_width = rep.width ;
+    *a_height = rep.height ;
+    *a_image_size = rep.data_size ;
+
+    ret = TRUE ;
+
+out:
+    UnlockDisplay (dpy) ;
+    SyncHandle ();
+    return ret ;
+}
+
+Bool
+EphyrHostGetAtom (const char* a_name,
+                  Bool a_create_if_not_exists,
+                  int *a_atom)
+{
+    int atom=None ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ;
+
+    atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists);
+    if (atom == None) {
         return FALSE ;
     }
+    *a_atom = atom ;
     return TRUE ;
 }
+
+char*
+EphyrHostGetAtomName (int a_atom)
+{
+    return XGetAtomName (hostx_get_display (), a_atom) ;
+}
+
+void
+EphyrHostFree (void *a_pointer)
+{
+    if (a_pointer)
+        XFree (a_pointer) ;
+}
+
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
index af54560..fa3eba0 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.h
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -84,6 +84,8 @@ typedef struct _EphyrHostImageFormat {
     int scanline_order;          /* XvTopToBottom, XvBottomToTop */
 } EphyrHostImageFormat ;
 
+void EphyrHostFree (void *a_pointer) ;
+
 /*
  * host adaptor array
  */
@@ -139,5 +141,33 @@ Bool EphyrHostXVSetPortAttribute (int a_port_id,
 Bool EphyrHostXVGetPortAttribute (int a_port_id,
                                   int a_atom,
                                   int *a_attr_value) ;
+/*
+ *size query
+ */
+Bool EphyrHostXVQueryBestSize (int a_port_id,
+                               Bool a_motion,
+                               unsigned int a_frame_w,
+                               unsigned int a_frame_h,
+                               unsigned int a_drw_w,
+                               unsigned int a_drw_h,
+                               unsigned int *a_actual_w,
+                               unsigned int *a_actual_h) ;
+
+Bool EphyrHostXVQueryImageAttributes (int a_port_id,
+                                      int a_image_id /*image fourcc code*/,
+                                      unsigned short *a_width,
+                                      unsigned short *a_height,
+                                      int *a_image_size,
+                                      int *a_pitches,
+                                      int *a_offsets) ;
+/*
+ * atom
+ */
+Bool EphyrHostGetAtom (const char* a_name,
+                       Bool a_create_if_not_exists,
+                       int *a_atom) ;
+char* EphyrHostGetAtomName (int a_atom) ;
+
+
 #endif /*__EPHYRHOSTVIDEO_H__*/
 
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index eedbf15..6f0bc8f 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -51,6 +51,10 @@ struct _EphyrPortPriv {
 };
 typedef struct _EphyrPortPriv EphyrPortPriv ;
 
+static Bool EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
+
+static Bool EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
+
 static EphyrXVPriv* EphyrXVPrivNew (void) ;
 static void EphyrXVPrivDelete (EphyrXVPriv *a_this) ;
 static Bool EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
@@ -105,6 +109,67 @@ static int EphyrQueryImageAttributes (KdScreenInfo *a_info,
                                       unsigned short *a_h,
                                       int *a_pitches,
                                       int *a_offsets);
+static int s_base_port_id ;
+
+/**************
+ * <helpers>
+ * ************/
+
+static Bool
+EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
+{
+    char *atom_name=NULL;
+    int host_atom=None ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_host_atom, FALSE) ;
+
+    if (!ValidAtom (a_local_atom))
+        return FALSE ;
+
+    atom_name = NameForAtom (a_local_atom) ;
+
+    if (!atom_name)
+        return FALSE ;
+
+    if (!EphyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
+        EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n",
+                         atom_name) ;
+        return FALSE ;
+    }
+    *a_host_atom = host_atom ;
+    return TRUE ;
+}
+
+static Bool
+EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
+{
+    Bool is_ok=FALSE ;
+    char *atom_name=NULL ;
+    int atom=None ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ;
+
+    atom_name = EphyrHostGetAtomName (a_host_atom) ;
+    if (!atom_name)
+        goto out ;
+
+    atom = MakeAtom (atom_name, strlen (atom_name), TRUE) ;
+    if (atom == None)
+        goto out ;
+
+    *a_local_atom = atom ;
+    is_ok = TRUE ;
+
+out:
+    if (atom_name) {
+        EphyrHostFree (atom_name) ;
+    }
+    return is_ok ;
+}
+
+/**************
+ *</helpers>
+ * ************/
 
 Bool
 ephyrInitVideo (ScreenPtr pScreen)
@@ -289,6 +354,9 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
             EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
             continue ;
         }
+        if (!s_base_port_id)
+            s_base_port_id = base_port_id ;
+
         if (!EphyrHostXVQueryEncodings (base_port_id,
                                         &encodings,
                                         &num_encodings)) {
@@ -436,7 +504,7 @@ EphyrSetPortAttribute (KdScreenInfo *a_info,
                        int a_attr_value,
                        pointer a_port_priv)
 {
-    int res=Success ;
+    int res=Success, host_atom=0 ;
     EphyrPortPriv *port_priv = a_port_priv ;
 
     EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
@@ -448,8 +516,14 @@ EphyrSetPortAttribute (KdScreenInfo *a_info,
                NameForAtom (a_attr_name),
                a_attr_value) ;
 
+    if (!EphyrLocalAtomToHost (a_attr_name, &host_atom)) {
+        EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
+        res = BadMatch ;
+        goto out ;
+    }
+
     if (!EphyrHostXVSetPortAttribute (port_priv->port_number,
-                                      a_attr_name,
+                                      host_atom,
                                       a_attr_value)) {
         EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
         res = BadMatch ;
@@ -468,7 +542,7 @@ EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
                        int *a_attr_value,
                        pointer a_port_priv)
 {
-    int res=Success ;
+    int res=Success, host_atom=0 ;
     EphyrPortPriv *port_priv = a_port_priv ;
 
     EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
@@ -479,8 +553,14 @@ EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
                (int)a_attr_name,
                NameForAtom (a_attr_name)) ;
 
+    if (!EphyrLocalAtomToHost (a_attr_name, &host_atom)) {
+        EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
+        res = BadMatch ;
+        goto out ;
+    }
+
     if (!EphyrHostXVGetPortAttribute (port_priv->port_number,
-                                      a_attr_name,
+                                      host_atom,
                                       a_attr_value)) {
         EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
         res = BadMatch ;
@@ -489,6 +569,7 @@ EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
 
     res = Success ;
 out:
+    EPHYR_LOG ("leave\n") ;
     return res ;
 }
 
@@ -503,6 +584,21 @@ EphyrQueryBestSize (KdScreenInfo *a_info,
                     unsigned int *a_prefered_h,
                     pointer a_port_priv)
 {
+    int res=0 ;
+    EphyrPortPriv *port_priv = a_port_priv ;
+
+    EPHYR_RETURN_IF_FAIL (port_priv) ;
+
+    EPHYR_LOG ("enter\n") ;
+    res = EphyrHostXVQueryBestSize (port_priv->port_number,
+                                    a_motion,
+                                    a_src_w, a_src_h,
+                                    a_drw_w, a_drw_h,
+                                    a_prefered_w, a_prefered_h) ;
+    if (!res) {
+        EPHYR_LOG_ERROR ("Failed to query best size\n") ;
+    }
+    EPHYR_LOG ("leave\n") ;
 }
 
 static int
@@ -537,8 +633,24 @@ EphyrQueryImageAttributes (KdScreenInfo *a_info,
                            int *a_pitches,
                            int *a_offsets)
 {
-    EPHYR_LOG ("enter\n") ;
-    return 0 ;
+    int image_size=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_w && a_h, FALSE) ;
+
+    EPHYR_LOG ("enter: dim (%dx%d), pitches: %#x, offsets: %#x\n",
+               *a_w, *a_h, (unsigned int)a_pitches, (unsigned int)a_offsets) ;
+
+   if (!EphyrHostXVQueryImageAttributes (s_base_port_id,
+                                         a_id,
+                                         a_w, a_h,
+                                         &image_size,
+                                         a_pitches, a_offsets)) {
+       EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ;
+       goto out ;
+   }
+   EPHYR_LOG ("image size: %d, dim (%dx%d)", image_size, *a_w, *a_h) ;
+
+out:
     EPHYR_LOG ("leave\n") ;
+    return image_size ;
 }
-
commit 24c837c0be6f85a917582156ab61d6c9c69301f9
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Tue Jul 31 23:18:52 2007 +0200

    implement setportattribute and getportattribute calls

diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index 98b7549..ed6dbb0 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -263,3 +263,41 @@ EphyrHostXVQueryImageFormats (int a_port_id,
     return TRUE ;
 
 }
+
+Bool
+EphyrHostXVSetPortAttribute (int a_port_id,
+                             int a_atom,
+                             int a_attr_value)
+{
+    int res=Success ;
+
+    res = XvSetPortAttribute (hostx_get_display (),
+                              a_port_id,
+                              a_atom,
+                              a_attr_value) ;
+    if (res != Success) {
+        EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
+        return FALSE ;
+    }
+    return TRUE ;
+}
+
+Bool
+EphyrHostXVGetPortAttribute (int a_port_id,
+                             int a_atom,
+                             int *a_attr_value)
+{
+    int res=Success ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ;
+
+    res = XvGetPortAttribute (hostx_get_display (),
+                              a_port_id,
+                              a_atom,
+                              a_attr_value) ;
+    if (res != Success) {
+        EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ;
+        return FALSE ;
+    }
+    return TRUE ;
+}
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
index d9034fd..af54560 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.h
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -130,6 +130,14 @@ void EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes) ;
 Bool EphyrHostXVQueryImageFormats (int a_port_id,
                                    EphyrHostImageFormat **a_formats,
                                    int *a_num_format) ;
-
+/*
+ * Port Attribute Get/Set
+ */
+Bool EphyrHostXVSetPortAttribute (int a_port_id,
+                                  int a_atom,
+                                  int a_attr_value) ;
+Bool EphyrHostXVGetPortAttribute (int a_port_id,
+                                  int a_atom,
+                                  int *a_attr_value) ;
 #endif /*__EPHYRHOSTVIDEO_H__*/
 
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index d08f111..eedbf15 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -43,9 +43,14 @@ struct _EphyrXVPriv {
     KdVideoAdaptorPtr adaptors ;
     int num_adaptors ;
 };
-
 typedef struct _EphyrXVPriv EphyrXVPriv ;
 
+struct _EphyrPortPriv {
+    int port_number ;
+    EphyrXVPriv *xv_priv;
+};
+typedef struct _EphyrPortPriv EphyrPortPriv ;
+
 static EphyrXVPriv* EphyrXVPrivNew (void) ;
 static void EphyrXVPrivDelete (EphyrXVPriv *a_this) ;
 static Bool EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
@@ -59,12 +64,12 @@ static void EphyrStopVideo (KdScreenInfo *a_info,
 static int EphyrSetPortAttribute (KdScreenInfo *a_info,
                                   Atom a_attr_name,
                                   int a_attr_value,
-                                  pointer a_xv_priv);
+                                  pointer a_port_priv);
 
 static int EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
                                   Atom a_attr_name,
                                   int *a_attr_value,
-                                  pointer a_xv_priv);
+                                  pointer a_port_priv);
 
 static void EphyrQueryBestSize (KdScreenInfo *a_info,
                                 Bool a_motion,
@@ -74,7 +79,7 @@ static void EphyrQueryBestSize (KdScreenInfo *a_info,
                                 short a_drw_h,
                                 unsigned int *a_prefered_w,
                                 unsigned int *a_prefered_h,
-                                pointer a_xv_priv);
+                                pointer a_port_priv);
 
 static int EphyrPutImage (KdScreenInfo *a_info,
                           DrawablePtr a_drawable,
@@ -92,7 +97,7 @@ static int EphyrPutImage (KdScreenInfo *a_info,
                           short a_height,
                           Bool a_sync,
                           RegionPtr a_clipping_region,
-                          pointer a_xv_priv);
+                          pointer a_port_priv);
 
 static int EphyrQueryImageAttributes (KdScreenInfo *a_info,
                                       int a_id,
@@ -231,7 +236,8 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
     EphyrHostEncoding *encodings=NULL ;
     EphyrHostAttribute *attributes=NULL ;
     EphyrHostImageFormat *image_formats=NULL ;
-    int num_video_formats=0, base_port_id=0, num_attributes=0, num_formats=0, i=0 ;
+    int num_video_formats=0, base_port_id=0,
+        num_attributes=0, num_formats=0, i=0;
     unsigned num_encodings=0 ;
     Bool is_ok = FALSE ;
 
@@ -244,7 +250,8 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
         goto out ;
     }
     if (a_this->host_adaptors)
-        a_this->num_adaptors = EphyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
+        a_this->num_adaptors =
+                    EphyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
     if (a_this->num_adaptors < 0) {
         EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
         goto out ;
@@ -254,7 +261,8 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
      * copy what we can from adaptors into a_this->adaptors
      */
     if (a_this->num_adaptors) {
-        a_this->adaptors = xcalloc (a_this->num_adaptors, sizeof (KdVideoAdaptorRec)) ;
+        a_this->adaptors = xcalloc (a_this->num_adaptors,
+                                    sizeof (KdVideoAdaptorRec)) ;
         if (!a_this->adaptors) {
             EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
             goto out ;
@@ -262,15 +270,18 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
     }
     for (i=0; i < a_this->num_adaptors; i++) {
         int j=0 ;
-        cur_host_adaptor = EphyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+        cur_host_adaptor =
+                   EphyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
         if (!cur_host_adaptor)
             continue ;
-        a_this->adaptors[i].type = EphyrHostXVAdaptorGetType (cur_host_adaptor) ;
+        a_this->adaptors[i].type =
+                        EphyrHostXVAdaptorGetType (cur_host_adaptor) ;
         a_this->adaptors[i].type |= XvWindowMask ;
-        a_this->adaptors[i].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+        a_this->adaptors[i].flags =
+                        VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
         if (EphyrHostXVAdaptorGetName (cur_host_adaptor))
             a_this->adaptors[i].name =
-                                strdup (EphyrHostXVAdaptorGetName (cur_host_adaptor)) ;
+                    strdup (EphyrHostXVAdaptorGetName (cur_host_adaptor)) ;
         else
             a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
         base_port_id = EphyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
@@ -278,33 +289,51 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
             EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
             continue ;
         }
-        if (!EphyrHostXVQueryEncodings (base_port_id, &encodings, &num_encodings)) {
-            EPHYR_LOG_ERROR ("failed to get encodings for port port id %d, adaptors %d\n",
+        if (!EphyrHostXVQueryEncodings (base_port_id,
+                                        &encodings,
+                                        &num_encodings)) {
+            EPHYR_LOG_ERROR ("failed to get encodings for port port id %d,"
+                             " adaptors %d\n",
                              base_port_id, i) ;
             continue ;
         }
         a_this->adaptors[i].nEncodings = num_encodings ;
-        a_this->adaptors[i].pEncodings = videoEncodingDup (encodings, num_encodings) ;
+        a_this->adaptors[i].pEncodings =
+                            videoEncodingDup (encodings, num_encodings) ;
         video_formats = (EphyrHostVideoFormat*)
-            EphyrHostXVAdaptorGetVideoFormats (cur_host_adaptor, &num_video_formats);
+            EphyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
+                                               &num_video_formats);
         a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
         a_this->adaptors[i].nFormats = num_video_formats ;
-        a_this->adaptors[i].nPorts = EphyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
-        a_this->adaptors[i].pPortPrivates = xcalloc (a_this->adaptors[i].nPorts,
-                                                     sizeof (DevUnion)) ;
+        a_this->adaptors[i].nPorts =
+                            EphyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+        a_this->adaptors[i].pPortPrivates =
+                xcalloc (a_this->adaptors[i].nPorts,
+                         sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
         for (j=0; j < a_this->adaptors[i].nPorts; j++) {
-            a_this->adaptors[i].pPortPrivates[j].ptr = a_this ;
+            int port_priv_offset = a_this->adaptors[i].nPorts ;
+            EphyrPortPriv *port_priv =
+                (EphyrPortPriv*)
+                    &a_this->adaptors[i].pPortPrivates[port_priv_offset + j];
+            port_priv->port_number = base_port_id + j;
+            port_priv->xv_priv = a_this ;
+            a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
         }
         if (!EphyrHostXVQueryPortAttributes (base_port_id,
                                              &attributes,
                                              &num_attributes)) {
-            EPHYR_LOG_ERROR ("failed to get port attribute for adaptor %d\n", i) ;
+            EPHYR_LOG_ERROR ("failed to get port attribute "
+                             "for adaptor %d\n", i) ;
             continue ;
         }
-        a_this->adaptors[i].pAttributes = portAttributesDup (attributes, num_attributes);
+        a_this->adaptors[i].pAttributes =
+                    portAttributesDup (attributes, num_attributes);
         a_this->adaptors[i].nAttributes = num_attributes ;
-        if (!EphyrHostXVQueryImageFormats (base_port_id, &image_formats, &num_formats)) {
-            EPHYR_LOG_ERROR ("failed to get image formats for adaptor %d\n", i) ;
+        if (!EphyrHostXVQueryImageFormats (base_port_id,
+                                           &image_formats,
+                                           &num_formats)) {
+            EPHYR_LOG_ERROR ("failed to get image formats "
+                             "for adaptor %d\n", i) ;
             continue ;
         }
         a_this->adaptors[i].pImages = (KdImagePtr) image_formats ;
@@ -362,7 +391,8 @@ EphyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
 
     if (!a_this->num_adaptors)
         goto out ;
-    num_registered_adaptors = KdXVListGenericAdaptors (screen, &registered_adaptors);
+    num_registered_adaptors =
+                KdXVListGenericAdaptors (screen, &registered_adaptors);
     num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
     adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
     if (!adaptors) {
@@ -394,7 +424,7 @@ out:
 }
 
 static void
-EphyrStopVideo (KdScreenInfo *a_info, pointer a_xv_priv, Bool a_exit)
+EphyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
 {
     EPHYR_LOG ("enter\n") ;
     EPHYR_LOG ("leave\n") ;
@@ -404,22 +434,62 @@ static int
 EphyrSetPortAttribute (KdScreenInfo *a_info,
                        Atom a_attr_name,
                        int a_attr_value,
-                       pointer a_xv_priv)
+                       pointer a_port_priv)
 {
-    EPHYR_LOG ("enter\n") ;
-    return 0 ;
+    int res=Success ;
+    EphyrPortPriv *port_priv = a_port_priv ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+    EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
+
+    EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n",
+               port_priv->port_number,
+               (int)a_attr_name,
+               NameForAtom (a_attr_name),
+               a_attr_value) ;
+
+    if (!EphyrHostXVSetPortAttribute (port_priv->port_number,
+                                      a_attr_name,
+                                      a_attr_value)) {
+        EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
+        res = BadMatch ;
+        goto out ;
+    }
+
+    res = Success ;
+out:
     EPHYR_LOG ("leave\n") ;
+    return res ;
 }
 
 static int
 EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
                        Atom a_attr_name,
                        int *a_attr_value,
-                       pointer a_xv_priv)
+                       pointer a_port_priv)
 {
-    EPHYR_LOG ("enter\n") ;
-    return 0 ;
-    EPHYR_LOG ("leave\n") ;
+    int res=Success ;
+    EphyrPortPriv *port_priv = a_port_priv ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+    EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
+
+    EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s\n",
+               port_priv->port_number,
+               (int)a_attr_name,
+               NameForAtom (a_attr_name)) ;
+
+    if (!EphyrHostXVGetPortAttribute (port_priv->port_number,
+                                      a_attr_name,
+                                      a_attr_value)) {
+        EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
+        res = BadMatch ;
+        goto out ;
+    }
+
+    res = Success ;
+out:
+    return res ;
 }
 
 static void
@@ -431,7 +501,7 @@ EphyrQueryBestSize (KdScreenInfo *a_info,
                     short a_drw_h,
                     unsigned int *a_prefered_w,
                     unsigned int *a_prefered_h,
-                    pointer a_xv_priv)
+                    pointer a_port_priv)
 {
 }
 
@@ -452,7 +522,7 @@ EphyrPutImage (KdScreenInfo *a_info,
                short a_height,
                Bool a_sync,
                RegionPtr a_clipping_region,
-               pointer a_xv_priv)
+               pointer a_port_priv)
 {
     EPHYR_LOG ("enter\n") ;
     return 0 ;
commit b8cd313be467fd14b8e5c9ba68e1a2029c1e888b
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Mon Jul 23 12:43:43 2007 +0200

    make xvinfo work
    
            * hw/kdrive/ephyr/ephyrhostvideo.c:
              (EphyrHostXVAdaptorGetVideoFormats): properly get visual class instead of
                returning the visual id.
              (EphyrHostXVQueryEncodings): properly copy the fields because simple casting does
                truncate some fields.
               (EphyrHostAttributesDelete): XFree the whole array instead of trying to free invidial members.
            * hw/kdrive/ephyr/ephyrvideo.c:
              (ephyrInitVideo): fix a typo
              (EphyrXVPrivQueryHostAdaptors): set XvWindowMask mask to adaptors type.
               use host adaptor name. Don't forget to set nImages field.
              (EphyrXVPrivRegisterAdaptors): report an error when KdXVScreenInit() fails.

diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index 6c5891c..98b7549 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -28,7 +28,7 @@
 #ifdef HAVE_CONFIG_H
 #include <kdrive-config.h>
 #endif
-#include <X11/Xlib.h>
+#include <X11/Xutil.h>
 #include <X11/extensions/Xvlib.h>
 
 #include "hostx.h"
@@ -125,15 +125,34 @@ EphyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
     return ((XvAdaptorInfo*)a_this)->name ;
 }
 
-const EphyrHostVideoFormat*
+EphyrHostVideoFormat*
 EphyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
                                    int *a_nb_formats)
 {
+    EphyrHostVideoFormat *formats=NULL ;
+    int nb_formats=0, i=0 ;
+    XVisualInfo *visual_info, visual_info_template ;
+    int nb_visual_info ;
+
     EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
 
+    nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
+    formats = Xcalloc (nb_formats * sizeof (EphyrHostVideoFormat)) ;
+    for (i=0; i < nb_formats; i++) {
+        memset (&visual_info_template, 0, sizeof (visual_info_template)) ;
+        visual_info_template.visualid =
+                            ((XvAdaptorInfo*)a_this)->formats[i].visual_id;
+        visual_info = XGetVisualInfo (hostx_get_display (),
+                                      VisualIDMask,
+                                      &visual_info_template,
+                                      &nb_visual_info) ;
+        formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ;
+        formats[i].visual_class = visual_info->class ;
+        XFree (visual_info) ;
+    }
     if (a_nb_formats)
-        *a_nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
-    return (EphyrHostVideoFormat*) ((XvAdaptorInfo*)a_this)->formats ;
+        *a_nb_formats = nb_formats ;
+    return formats ;
 }
 
 int
@@ -157,16 +176,38 @@ EphyrHostXVQueryEncodings (int a_port_id,
                            EphyrHostEncoding **a_encodings,
                            unsigned int *a_num_encodings)
 {
-    int ret = 0 ;
+    EphyrHostEncoding *encodings=NULL ;
+    XvEncodingInfo *encoding_info=NULL ;
+    unsigned int num_encodings=0, i;
+    int ret=0 ;
+
     EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ;
 
     ret = XvQueryEncodings (hostx_get_display (),
                             a_port_id,
-                            a_num_encodings,
-                            (XvEncodingInfo**)a_encodings) ;
-    if (ret == Success)
-        return TRUE ;
-    return FALSE ;
+                            &num_encodings,
+                            &encoding_info) ;
+    if (num_encodings && encoding_info) {
+        encodings = Xcalloc (num_encodings * sizeof (EphyrHostEncoding)) ;
+        for (i=0; i<num_encodings; i++) {
+            encodings[i].id = encoding_info[i].encoding_id ;
+            encodings[i].name = strdup (encoding_info[i].name) ;
+            encodings[i].width = encoding_info[i].width ;
+            encodings[i].height = encoding_info[i].height ;
+            encodings[i].rate.numerator = encoding_info[i].rate.numerator ;
+            encodings[i].rate.denominator = encoding_info[i].rate.denominator ;
+        }
+    }
+    if (encoding_info) {
+        XvFreeEncodingInfo (encoding_info) ;
+        encoding_info = NULL ;
+    }
+    *a_encodings = encodings ;
+    *a_num_encodings = num_encodings ;
+
+    if (ret != Success)
+        return FALSE ;
+    return TRUE ;
 }
 
 void
@@ -187,20 +228,11 @@ EphyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
 }
 
 void
-EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes,
-                           int a_num_attributes)
+EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
 {
-    int i=0 ;
-
     if (!a_attributes)
         return ;
-    for (i=0; i < a_num_attributes; i++) {
-        if (a_attributes[i].name) {
-            xfree (a_attributes[i].name) ;
-            a_attributes[i].name = NULL ;
-        }
-    }
-    xfree (a_attributes) ;
+    XFree (a_attributes) ;
 }
 
 Bool
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
index 89c087c..d9034fd 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.h
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -28,13 +28,12 @@
 #ifndef __EPHYRHOSTVIDEO_H__
 #define __EPHYRHOSTVIDEO_H__
 
-
 typedef void* EphyrHostXVAdaptor ;
 typedef struct _EphyrHostXVAdaptorArray EphyrHostXVAdaptorArray ;
 
 typedef struct _EphyrHostVideoFormat {
     char depth ;
-    unsigned long visual_id;
+    short visual_class;
 } EphyrHostVideoFormat ;
 
 typedef struct _EphyrHostRational {
@@ -100,9 +99,7 @@ EphyrHostXVAdaptor* EphyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_
 
 char EphyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) ;
 const char* EphyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) ;
-const EphyrHostVideoFormat* EphyrHostXVAdaptorGetNbVideoFormats
-                                                (const EphyrHostXVAdaptor *a_this) ;
-const EphyrHostVideoFormat* EphyrHostXVAdaptorGetVideoFormats
+EphyrHostVideoFormat* EphyrHostXVAdaptorGetVideoFormats
                                                 (const EphyrHostXVAdaptor *a_this,
                                                  int *a_nb_formats) ;
 int EphyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ;
@@ -125,8 +122,7 @@ Bool EphyrHostXVQueryPortAttributes (int a_port_id,
                                      EphyrHostAttribute **a_attributes,
                                      int *a_num_attributes) ;
 
-void EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes,
-                                int a_num_attributes) ;
+void EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes) ;
 /*
  * image format
  */
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 4808685..d08f111 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -121,7 +121,7 @@ ephyrInitVideo (ScreenPtr pScreen)
         return FALSE ;
     }
 
-    if (EphyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
+    if (!EphyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
         EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
         return FALSE ;
     }
@@ -266,11 +266,13 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
         if (!cur_host_adaptor)
             continue ;
         a_this->adaptors[i].type = EphyrHostXVAdaptorGetType (cur_host_adaptor) ;
+        a_this->adaptors[i].type |= XvWindowMask ;
         a_this->adaptors[i].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
         if (EphyrHostXVAdaptorGetName (cur_host_adaptor))
             a_this->adaptors[i].name =
                                 strdup (EphyrHostXVAdaptorGetName (cur_host_adaptor)) ;
-        a_this->adaptors[i].name = "Xephyr Video Overlay";
+        else
+            a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
         base_port_id = EphyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
         if (base_port_id < 0) {
             EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
@@ -306,6 +308,7 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
             continue ;
         }
         a_this->adaptors[i].pImages = (KdImagePtr) image_formats ;
+        a_this->adaptors[i].nImages = num_formats ;
     }
     is_ok = TRUE ;
 
@@ -315,13 +318,9 @@ out:
         encodings = NULL ;
     }
     if (attributes) {
-        EphyrHostAttributesDelete (attributes, num_attributes) ;
+        EphyrHostAttributesDelete (attributes) ;
         attributes = NULL ;
     }
-    if (image_formats) {
-        xfree (image_formats) ;
-        image_formats = NULL ;
-    }
     EPHYR_LOG ("leave\n") ;
     return is_ok ;
 }
@@ -374,7 +373,11 @@ EphyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
     for (i=0 ; i < a_this->num_adaptors; i++) {
         *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ;
     }
-    KdXVScreenInit (a_screen, adaptors, num_adaptors);
+    if (!KdXVScreenInit (a_screen, adaptors, num_adaptors)) {
+        EPHYR_LOG_ERROR ("failed to register adaptors\n");
+        goto out ;
+    }
+    EPHYR_LOG ("registered %d adaptors\n", num_adaptors) ;
     is_ok = TRUE ;
 
 out:
commit aa2fae7b75f741e57bc4a9b754b5ea7518d78f47
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Sat Jul 21 23:56:13 2007 +0200

    misc fixes.
    
            *(EphyrHostXVQueryAdaptors): return the queried adaptors list
            * (EphyrHostXVQueryPortAttributes): return port attributes number

diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index d86f976..6c5891c 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -71,6 +71,7 @@ EphyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
         EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ;
         goto out ;
     }
+    *a_adaptors = result ;
     is_ok = TRUE ;
 
 out:
@@ -207,13 +208,11 @@ EphyrHostXVQueryPortAttributes (int a_port_id,
                                 EphyrHostAttribute **a_attributes,
                                 int *a_num_attributes)
 {
-    XvAttribute *attributes=NULL ;
-    int num_attributes=0 ;
-
     EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
 
-    attributes = XvQueryPortAttributes (hostx_get_display (), a_port_id, &num_attributes) ;
-    *a_attributes = (EphyrHostAttribute*)attributes ;
+    *a_attributes = (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
+                                                                a_port_id,
+                                                                a_num_attributes);
 
     return TRUE ;
 }
commit 2bf7f3c223fd32cd4922f98eadda2e3f06d9e119
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Sat Jul 21 17:55:12 2007 +0200

    link and init xv

diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index bd0dbde..4808685 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -1,4 +1,4 @@
-/*
+/*  
  * Xephyr - A kdrive X server thats runs in a host X window.
  *          Authored by Matthew Allum <mallum at openedhand.com>
  * 
commit 66b28532e533ff5688705c5286425e68d6403cee
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Sat Jul 21 12:08:39 2007 +0200

    initial commit of xv support work

diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index c87af19..bd0dbde 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -52,7 +52,6 @@ static Bool EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
 static Bool EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
 static Bool EphyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
                                          ScreenPtr a_screen) ;
-
 static void EphyrStopVideo (KdScreenInfo *a_info,
                             pointer a_xv_priv,
                             Bool a_exit);
commit 1e8f8b36a56a884092ee01a0bb3f40436e30fa42
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Sat Jul 21 18:22:20 2007 +0200

    works with no adaptors
    
    Debug the early code to make work when the host has no video adaptors

diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index 59a01bb..d86f976 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -64,7 +64,7 @@ EphyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
         goto out ;
 
     ret = XvQueryAdaptors (hostx_get_display (),
-                           DefaultRootWindow (hostx_get_display),
+                           DefaultRootWindow (hostx_get_display ()),
                            &result->nb_adaptors,
                            &result->adaptors) ;
     if (ret != Success) {
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index d80dab3..c87af19 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -145,7 +145,7 @@ EphyrXVPrivNew (void)
         EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
         goto error ;
     }
-    if (EphyrXVPrivSetAdaptorsHooks (xv_priv)) {
+    if (!EphyrXVPrivSetAdaptorsHooks (xv_priv)) {
         EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
         goto error ;
     }
@@ -232,7 +232,7 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
     EphyrHostEncoding *encodings=NULL ;
     EphyrHostAttribute *attributes=NULL ;
     EphyrHostImageFormat *image_formats=NULL ;
-    int num_video_formats=0, base_port_id=0, num_attributes=0, num_formats=0, res=0, i=0 ;
+    int num_video_formats=0, base_port_id=0, num_attributes=0, num_formats=0, i=0 ;
     unsigned num_encodings=0 ;
     Bool is_ok = FALSE ;
 
@@ -240,22 +240,26 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
 
     EPHYR_LOG ("enter\n") ;
 
-    if (!EphyrHostXVQueryAdaptors (&a_this->host_adaptors) || !a_this->host_adaptors) {
-        EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", res) ;
+    if (!EphyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
+        EPHYR_LOG_ERROR ("failed to query host adaptors\n") ;
         goto out ;
     }
-    a_this->num_adaptors = EphyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
+    if (a_this->host_adaptors)
+        a_this->num_adaptors = EphyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
     if (a_this->num_adaptors < 0) {
         EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
         goto out ;
     }
+    EPHYR_LOG ("host has %d adaptors\n", a_this->num_adaptors) ;
     /*
      * copy what we can from adaptors into a_this->adaptors
      */
-    a_this->adaptors = xcalloc (a_this->num_adaptors, sizeof (KdVideoAdaptorRec)) ;
-    if (!a_this->host_adaptors) {
-        EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
-        goto out ;
+    if (a_this->num_adaptors) {
+        a_this->adaptors = xcalloc (a_this->num_adaptors, sizeof (KdVideoAdaptorRec)) ;
+        if (!a_this->adaptors) {
+            EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
+            goto out ;
+        }
     }
     for (i=0; i < a_this->num_adaptors; i++) {
         int j=0 ;
commit 50ff2377cac50ae25218be5b30612fb8bf6046a6
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Sat Jul 21 18:20:59 2007 +0200

    add -verbosity <level> option to command line

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 6874609..c8fbdff 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -27,6 +27,7 @@
 #include <kdrive-config.h>
 #endif
 #include "ephyr.h"
+#include "ephyrlog.h"
 
 extern Window EphyrPreExistingHostWin;
 extern Bool   EphyrWantGrayScale;
@@ -92,11 +93,12 @@ ddxUseMsg (void)
   KdUseMsg();
 
   ErrorF("\nXephyr Option Usage:\n");
-  ErrorF("-parent XID   Use existing window as Xephyr root win\n");
-  ErrorF("-host-cursor  Re-use exisiting X host server cursor\n");
-  ErrorF("-fullscreen   Attempt to run Xephyr fullscreen\n");
-  ErrorF("-grayscale    Simulate 8bit grayscale\n");
-  ErrorF("-fakexa       Simulate acceleration using software rendering\n");
+  ErrorF("-parent <XID>        Use existing window as Xephyr root win\n");
+  ErrorF("-host-cursor         Re-use exisiting X host server cursor\n");
+  ErrorF("-fullscreen          Attempt to run Xephyr fullscreen\n");
+  ErrorF("-grayscale           Simulate 8bit grayscale\n");
+  ErrorF("-fakexa              Simulate acceleration using software rendering\n");
+  ErrorF("-verbosity <level>   Set log verbosity level\n");
   ErrorF("\n");
 
   exit(1);
@@ -182,6 +184,21 @@ ddxProcessArgument (int argc, char **argv, int i)
       ephyrFuncs.finiAccel = ephyrDrawFini;
       return 1;
     }
+  else if (!strcmp (argv[i], "-verbosity"))
+    {
+      if(i+1 < argc && argv[i+1][0] != '-')
+	{
+	  int verbosity=atoi (argv[i+1]) ;
+	  LogSetParameter (XLOG_VERBOSITY, verbosity) ;
+	  EPHYR_LOG ("set verbosiry to %d\n", verbosity) ;
+	  return 2 ;
+	}
+      else
+	{
+	  UseMsg() ;
+	  exit(1) ;
+	}
+    }
   else if (argv[i][0] == ':')
     {
       hostx_set_display_name(argv[i]);
commit 8426eb2433f964ea19848f24dc99eb4588d10d1a
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Sat Jul 21 17:55:12 2007 +0200

    link and init xv

diff --git a/configure.ac b/configure.ac
index 5c5ff7d..a7f1e84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -723,6 +723,7 @@ if test "x$XV" = xyes; then
 	AC_DEFINE(XV, 1, [Support Xv extension])
 	AC_DEFINE(XvExtension, 1, [Build Xv extension])
 	REQUIRED_MODULES="$REQUIRED_MODULES videoproto"
+        PKG_CHECK_MODULES(XV, [xv >= 0.22])
 else
 	XVMC=no
 fi
@@ -1860,9 +1861,9 @@ if test "$KDRIVE" = yes; then
     KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux'
     KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC"
     
-    KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS"
+    KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS $XV_CFLAGS"
 
-    KDRIVE_PURE_LIBS="$FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB"
+    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $XV_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB"
     KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a'
     case $host_os in
 	*linux*)
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index c5cb21a..2cb7d0b 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -23,11 +23,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/*  TODO:
- *
- *  o Support multiple screens, shouldn't be hard just alot of rejigging.
- */
-
 #ifdef HAVE_CONFIG_H
 #include <kdrive-config.h>
 #endif
@@ -35,6 +30,7 @@
 
 #include "inputstr.h"
 #include "scrnintstr.h"
+#include "ephyrlog.h"
 
 extern int KdTsPhyScreen;
 KdKeyboardInfo *ephyrKbd;
@@ -209,7 +205,7 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
   KdPointerMatrix m;
   int buffer_height;
   
-  EPHYR_DBG("screen->width: %d, screen->height: %d index=%d",
+  EPHYR_LOG("screen->width: %d, screen->height: %d index=%d",
 	     screen->width, screen->height, screen->mynum);
   
   KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
@@ -245,7 +241,7 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
       /* Rotated/Reflected so we need to use shadow fb */
       scrpriv->shadow = TRUE;
       
-      EPHYR_DBG("allocing shadow");
+      EPHYR_LOG("allocing shadow");
       
       KdShadowFbAlloc (screen, 0, 
 		       scrpriv->randr & (RR_Rotate_90|RR_Rotate_270));
@@ -296,7 +292,7 @@ ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
   KdScreenPriv(pScreen);
   KdScreenInfo *screen = pScreenPriv->screen;
   
-  EPHYR_DBG("slow paint");
+  EPHYR_LOG("slow paint");
   
   /* FIXME: Slow Rotated/Reflected updates could be much
    * much faster efficiently updating via tranforming 
@@ -410,7 +406,7 @@ ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
   Rotation		    randr;
   int			    n = 0;
   
-  EPHYR_DBG("mark");
+  EPHYR_LOG("mark");
   
   struct { int width, height; } sizes[] = 
     {
@@ -563,7 +559,7 @@ ephyrRandRSetConfig (ScreenPtr		pScreen,
   return TRUE;
   
  bail4:
-  EPHYR_DBG("bailed");
+  EPHYR_LOG("bailed");
   
   ephyrUnmapFramebuffer (screen);
   *scrpriv = oldscr;
@@ -606,10 +602,17 @@ ephyrInitScreen (ScreenPtr pScreen)
   KdScreenPriv(pScreen);
   KdScreenInfo	*screen    = pScreenPriv->screen;
 
-  EPHYR_DBG ("pScreen->myNum:%d\n", pScreen->myNum) ;
+  EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ;
   hostx_set_screen_number (screen, pScreen->myNum);
   hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
   pScreen->CreateColormap = ephyrCreateColormap;
+#ifdef XV
+  if (!ephyrInitVideo (pScreen)) {
+      EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
+  } else {
+      EPHYR_LOG_ERROR ("initialized xvideo okay\n") ;
+  }
+#endif /*XV*/
   return TRUE;
 }
 
@@ -637,7 +640,7 @@ ephyrCreateResources (ScreenPtr pScreen)
   KdScreenInfo	*screen    = pScreenPriv->screen;
   EphyrScrPriv	*scrpriv   = screen->driver;
 
-  EPHYR_DBG("mark pScreen=%p mynum=%d shadow=%d",
+  EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
             pScreen, pScreen->myNum, scrpriv->shadow);
 
   if (scrpriv->shadow) 
@@ -809,20 +812,20 @@ ephyrPoll(void)
         case EPHYR_EV_MOUSE_MOTION:
           if (!ephyrMouse ||
               !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
-              EPHYR_DBG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
+              EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
               continue;
           }
           {
             if (ephyrCurScreen != ev.data.mouse_motion.screen)
               {
-                  EPHYR_DBG ("warping mouse cursor:%d\n", ephyrCurScreen) ;
+                  EPHYR_LOG ("warping mouse cursor:%d\n", ephyrCurScreen) ;
                   ephyrWarpCursor(screenInfo.screens[ev.data.mouse_motion.screen],
                                    ev.data.mouse_motion.x,
                                    ev.data.mouse_motion.y );
               }
             else
               {
-                  EPHYR_DBG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
+                  EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
                   KdEnqueuePointerEvent(ephyrMouse, mouseState,
                                         ev.data.mouse_motion.x,
                                         ev.data.mouse_motion.y,
@@ -834,10 +837,10 @@ ephyrPoll(void)
         case EPHYR_EV_MOUSE_PRESS:
           if (!ephyrMouse ||
               !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
-              EPHYR_DBG ("skipping mouse press:%d\n", ephyrCurScreen) ;
+              EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ;
               continue;
           }
-          EPHYR_DBG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
+          EPHYR_LOG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
 	  ephyrUpdateModifierState(ev.key_state);
 	  mouseState |= ev.data.mouse_down.button_num;
 	  KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
@@ -849,7 +852,7 @@ ephyrPoll(void)
               continue;
 	  ephyrUpdateModifierState(ev.key_state);
 	  mouseState &= ~ev.data.mouse_up.button_num;
-          EPHYR_DBG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
+          EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
 	  KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
 	  break;
 
@@ -886,7 +889,7 @@ ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
 {
   /* XXX Not sure if this is right */
   
-  EPHYR_DBG("mark");
+  EPHYR_LOG("mark");
   
   while (n--)
     {
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 6be177b..d80dab3 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -50,6 +50,8 @@ static EphyrXVPriv* EphyrXVPrivNew (void) ;
 static void EphyrXVPrivDelete (EphyrXVPriv *a_this) ;
 static Bool EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
 static Bool EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
+static Bool EphyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+                                         ScreenPtr a_screen) ;
 
 static void EphyrStopVideo (KdScreenInfo *a_info,
                             pointer a_xv_priv,
@@ -106,9 +108,6 @@ ephyrInitVideo (ScreenPtr pScreen)
     KdScreenPriv(pScreen);
     KdScreenInfo *screen = pScreenPriv->screen;
     EphyrXVPriv *xv_priv = NULL ;
-    KdVideoAdaptorPtr *adaptors, *newAdaptors = NULL;
-    KdVideoAdaptorPtr newAdaptor = NULL;
-    int num_adaptors=0;
 
     EPHYR_LOG ("enter\n") ;
 
@@ -123,39 +122,11 @@ ephyrInitVideo (ScreenPtr pScreen)
         return FALSE ;
     }
 
-    /*
-     * TODO:
-     * queried host adaptors, now get xv_priv->adaptors and.
-     * add it to those already existing.
-     */
-    num_adaptors = KdXVListGenericAdaptors (screen, &adaptors);
-
-    if (newAdaptor) {
-        if (!num_adaptors) {
-            num_adaptors = 1;
-            adaptors = &newAdaptor;
-        } else {
-            newAdaptors = xalloc ((num_adaptors + 1) * sizeof(KdVideoAdaptorPtr*));
-            if (newAdaptors) {
-                memcpy (newAdaptors,
-                        adaptors,
-                        num_adaptors * sizeof(KdVideoAdaptorPtr));
-                newAdaptors[num_adaptors] = newAdaptor;
-                adaptors = newAdaptors;
-                num_adaptors++;
-            }
-        }
-    }
-
-    if (num_adaptors) {
-        KdXVScreenInit (pScreen, adaptors, num_adaptors);
-    } else {
-        EPHYR_LOG_ERROR ("XVideo not initialised\n") ;
+    if (EphyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
+        EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
+        return FALSE ;
     }
-
-    if (newAdaptors)
-        xfree (newAdaptors);
-    return TRUE;
+    return TRUE ;
 }
 
 static EphyrXVPriv*
@@ -267,6 +238,8 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
 
     EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
 
+    EPHYR_LOG ("enter\n") ;
+
     if (!EphyrHostXVQueryAdaptors (&a_this->host_adaptors) || !a_this->host_adaptors) {
         EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", res) ;
         goto out ;
@@ -346,6 +319,7 @@ out:
         xfree (image_formats) ;
         image_formats = NULL ;
     }
+    EPHYR_LOG ("leave\n") ;
     return is_ok ;
 }
 
@@ -356,6 +330,8 @@ EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
 
     EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
 
+    EPHYR_LOG ("enter\n") ;
+
     for (i=0; i < a_this->num_adaptors; i++) {
         a_this->adaptors[i].StopVideo = EphyrStopVideo ;
         a_this->adaptors[i].SetPortAttribute = EphyrSetPortAttribute ;
@@ -364,9 +340,53 @@ EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
         a_this->adaptors[i].PutImage = EphyrPutImage;
         a_this->adaptors[i].QueryImageAttributes = EphyrQueryImageAttributes ;
     }
+    EPHYR_LOG ("leave\n") ;
     return TRUE ;
 }
 
+static Bool
+EphyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+                             ScreenPtr a_screen)
+{
+    KdScreenPriv(a_screen);
+    KdScreenInfo *screen = pScreenPriv->screen;
+    Bool is_ok = FALSE ;
+    KdVideoAdaptorPtr *adaptors=NULL, *registered_adaptors=NULL ;
+    int num_registered_adaptors=0, i=0, num_adaptors=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_screen, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    if (!a_this->num_adaptors)
+        goto out ;
+    num_registered_adaptors = KdXVListGenericAdaptors (screen, &registered_adaptors);
+    num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
+    adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
+    if (!adaptors) {
+        EPHYR_LOG_ERROR ("failed to allocate adaptors tab\n") ;
+        goto out ;
+    }
+    memmove (adaptors, registered_adaptors, num_registered_adaptors) ;
+    for (i=0 ; i < a_this->num_adaptors; i++) {
+        *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ;
+    }
+    KdXVScreenInit (a_screen, adaptors, num_adaptors);
+    is_ok = TRUE ;
+
+out:
+    if (registered_adaptors) {
+        xfree (registered_adaptors) ;
+        registered_adaptors = NULL ;
+    }
+    if (adaptors) {
+        xfree (adaptors) ;
+        adaptors=NULL ;
+    }
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
 static void
 EphyrStopVideo (KdScreenInfo *a_info, pointer a_xv_priv, Bool a_exit)
 {
commit 50a64c84e1556ef7f8efcc7f8655e0c5e023ef4d
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Sat Jul 21 12:08:39 2007 +0200

    initial commit of xv support work

diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index cc3019f..193c26b 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -3,22 +3,29 @@ INCLUDES = 					\
 	@KDRIVE_CFLAGS@				\
 	-I$(srcdir)/../../../exa
 
-noinst_LIBRARIES = libxephyr.a libxephyr-hostx.a
+noinst_LIBRARIES = libxephyr-hostx.a libxephyr-hostxv.a libxephyr.a 
 
 bin_PROGRAMS = Xephyr
 
-libxephyr_a_SOURCES =	\
-	ephyr.c		\
-	ephyr_draw.c	\
-	os.c		\
-	hostx.h          \
-	ephyr.h
 
 libxephyr_hostx_a_SOURCES =                             \
 	hostx.c                                         \
-	hostx.h    
+	hostx.h
+
+libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@
 
-libxephyr_hostx_a_INCLUDES = @XEPHYR_INCS@ 
+libxephyr_hostxv_a_SOURCES=				\
+	ephyrhostvideo.c \
+	ephyrhostvideo.h
+
+libxephyr_a_SOURCES =	\
+	ephyr.c		\
+	ephyr_draw.c	\
+	ephyrvideo.c	\
+	os.c		\
+	hostx.h         \
+	ephyr.h		\
+	ephyrlog.h
 
 Xephyr_SOURCES = \
 	ephyrinit.c
@@ -26,6 +33,7 @@ Xephyr_SOURCES = \
 Xephyr_LDADD = 						\
 	libxephyr.a					\
 	libxephyr-hostx.a			        \
+	libxephyr-hostxv.a			        \
 	../../../exa/libexa.la				\
 	@KDRIVE_LIBS@					\
         @XEPHYR_LIBS@
@@ -33,6 +41,7 @@ Xephyr_LDADD = 						\
 Xephyr_DEPENDENCIES =	\
 	libxephyr.a					\
 	libxephyr-hostx.a			        \
+	libxephyr-hostxv.a			        \
 	@KDRIVE_LOCAL_LIBS@
 
 relink:
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 1c9b4f8..8ed7e23 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -194,4 +194,8 @@ ephyrDrawDisable(ScreenPtr pScreen);
 void
 ephyrDrawFini(ScreenPtr pScreen);
 
+/*ephyvideo.c*/
+
+Bool ephyrInitVideo(ScreenPtr pScreen) ;
+
 #endif
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
new file mode 100644
index 0000000..59a01bb
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -0,0 +1,234 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include <X11/Xlib.h>
+#include <X11/extensions/Xvlib.h>
+
+#include "hostx.h"
+#include "ephyrhostvideo.h"
+#include "ephyrlog.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif /*TRUE*/
+
+#ifndef FALSE
+#define FALSE 0
+#endif /*FALSE*/
+
+struct _EphyrHostXVAdaptorArray {
+    XvAdaptorInfo *adaptors ;
+    unsigned int nb_adaptors ;
+};
+
+Bool
+EphyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
+{
+    EphyrHostXVAdaptorArray *result=NULL ;
+    int ret=0 ;
+    Bool is_ok=FALSE ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    result = Xcalloc (sizeof (EphyrHostXVAdaptorArray)) ;
+    if (!result)
+        goto out ;
+
+    ret = XvQueryAdaptors (hostx_get_display (),
+                           DefaultRootWindow (hostx_get_display),
+                           &result->nb_adaptors,
+                           &result->adaptors) ;
+    if (ret != Success) {
+        EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ;
+        goto out ;
+    }
+    is_ok = TRUE ;
+
+out:
+    EPHYR_LOG ("leave\n") ;
+    return is_ok ;
+}
+
+void
+EphyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
+{
+    if (!a_adaptors)
+        return ;
+    if (a_adaptors->adaptors) {
+        XvFreeAdaptorInfo (a_adaptors->adaptors) ;
+        a_adaptors->adaptors = NULL ;
+        a_adaptors->nb_adaptors = 0 ;
+    }
+    XFree (a_adaptors) ;
+}
+
+int
+EphyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+    return a_this->nb_adaptors ;
+}
+
+EphyrHostXVAdaptor*
+EphyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
+                           int a_index)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+    if (a_index >= a_this->nb_adaptors)
+        return NULL ;
+    return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ;
+}
+
+char
+EphyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+    return ((XvAdaptorInfo*)a_this)->type ;
+}
+
+const char*
+EphyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+    return ((XvAdaptorInfo*)a_this)->name ;
+}
+
+const EphyrHostVideoFormat*
+EphyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
+                                   int *a_nb_formats)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+    if (a_nb_formats)
+        *a_nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
+    return (EphyrHostVideoFormat*) ((XvAdaptorInfo*)a_this)->formats ;
+}
+
+int
+EphyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+
+    return ((XvAdaptorInfo*)a_this)->num_ports ;
+}
+
+int
+EphyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
+{
+    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+
+    return ((XvAdaptorInfo*)a_this)->base_id ;
+}
+
+Bool
+EphyrHostXVQueryEncodings (int a_port_id,
+                           EphyrHostEncoding **a_encodings,
+                           unsigned int *a_num_encodings)
+{
+    int ret = 0 ;
+    EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ;
+
+    ret = XvQueryEncodings (hostx_get_display (),
+                            a_port_id,
+                            a_num_encodings,
+                            (XvEncodingInfo**)a_encodings) ;
+    if (ret == Success)
+        return TRUE ;
+    return FALSE ;
+}
+
+void
+EphyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
+                          int a_num_encodings)
+{
+    int i=0 ;
+
+    if (!a_encodings)
+        return ;
+    for (i=0; i < a_num_encodings; i++) {
+        if (a_encodings[i].name) {
+            xfree (a_encodings[i].name) ;
+            a_encodings[i].name = NULL ;
+        }
+    }
+    xfree (a_encodings) ;
+}
+
+void
+EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes,
+                           int a_num_attributes)
+{
+    int i=0 ;
+
+    if (!a_attributes)
+        return ;
+    for (i=0; i < a_num_attributes; i++) {
+        if (a_attributes[i].name) {
+            xfree (a_attributes[i].name) ;
+            a_attributes[i].name = NULL ;
+        }
+    }
+    xfree (a_attributes) ;
+}
+
+Bool
+EphyrHostXVQueryPortAttributes (int a_port_id,
+                                EphyrHostAttribute **a_attributes,
+                                int *a_num_attributes)
+{
+    XvAttribute *attributes=NULL ;
+    int num_attributes=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
+
+    attributes = XvQueryPortAttributes (hostx_get_display (), a_port_id, &num_attributes) ;
+    *a_attributes = (EphyrHostAttribute*)attributes ;
+
+    return TRUE ;
+}
+
+Bool
+EphyrHostXVQueryImageFormats (int a_port_id,
+                              EphyrHostImageFormat **a_formats,
+                              int *a_num_format)
+{
+    XvImageFormatValues *result=NULL ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ;
+
+    result = XvListImageFormats (hostx_get_display (), a_port_id, a_num_format) ;
+    *a_formats = (EphyrHostImageFormat*) result ;
+    return TRUE ;
+
+}
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h
new file mode 100644
index 0000000..89c087c
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -0,0 +1,139 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifndef __EPHYRHOSTVIDEO_H__
+#define __EPHYRHOSTVIDEO_H__
+
+
+typedef void* EphyrHostXVAdaptor ;
+typedef struct _EphyrHostXVAdaptorArray EphyrHostXVAdaptorArray ;
+
+typedef struct _EphyrHostVideoFormat {
+    char depth ;
+    unsigned long visual_id;
+} EphyrHostVideoFormat ;
+
+typedef struct _EphyrHostRational {
+    int numerator ;
+    int denominator ;
+} EphyrHostRational;
+
+typedef struct _EphyrHostEncoding {
+    int id ;
+    char *name ;
+    unsigned short width, height ;
+    EphyrHostRational rate ;
+} EphyrHostEncoding ;
+
+typedef struct _EphyrHostAttribute {
+    int flags;
+    int min_value;
+    int max_value;
+    char *name;
+} EphyrHostAttribute ;
+
+typedef struct _EphyrHostImageFormat {
+    int id;                      /* Unique descriptor for the format */
+    int type;                    /* XvRGB, XvYUV */
+    int byte_order;              /* LSBFirst, MSBFirst */
+    char guid[16];               /* Globally Unique IDentifier */
+    int bits_per_pixel;
+    int format;                  /* XvPacked, XvPlanar */
+    int num_planes;
+
+    /* for RGB formats only */
+    int depth;
+    unsigned int red_mask;
+    unsigned int green_mask;
+    unsigned int blue_mask;
+
+    /* for YUV formats only */
+    unsigned int y_sample_bits;
+    unsigned int u_sample_bits;
+    unsigned int v_sample_bits;
+    unsigned int horz_y_period;
+    unsigned int horz_u_period;
+    unsigned int horz_v_period;
+    unsigned int vert_y_period;
+    unsigned int vert_u_period;
+    unsigned int vert_v_period;
+    char component_order[32];    /* eg. UYVY */
+    int scanline_order;          /* XvTopToBottom, XvBottomToTop */
+} EphyrHostImageFormat ;
+
+/*
+ * host adaptor array
+ */
+Bool EphyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) ;
+void EphyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) ;
+int EphyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) ;
+EphyrHostXVAdaptor* EphyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
+                                               int a_index) ;
+
+/*
+ * host adaptor
+ */
+
+char EphyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) ;
+const char* EphyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) ;
+const EphyrHostVideoFormat* EphyrHostXVAdaptorGetNbVideoFormats
+                                                (const EphyrHostXVAdaptor *a_this) ;
+const EphyrHostVideoFormat* EphyrHostXVAdaptorGetVideoFormats
+                                                (const EphyrHostXVAdaptor *a_this,
+                                                 int *a_nb_formats) ;
+int EphyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ;
+int EphyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ;
+
+/*
+ * encoding
+ */
+Bool EphyrHostXVQueryEncodings (int a_port_id,
+                                EphyrHostEncoding **a_encodings,
+                                unsigned int *a_num_encodings) ;
+
+void EphyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
+                               int a_num_encodings) ;
+
+/*
+ * attribute
+ */
+Bool EphyrHostXVQueryPortAttributes (int a_port_id,
+                                     EphyrHostAttribute **a_attributes,
+                                     int *a_num_attributes) ;
+
+void EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes,
+                                int a_num_attributes) ;
+/*
+ * image format
+ */
+
+Bool EphyrHostXVQueryImageFormats (int a_port_id,
+                                   EphyrHostImageFormat **a_formats,
+                                   int *a_num_format) ;
+
+#endif /*__EPHYRHOSTVIDEO_H__*/
+
diff --git a/hw/kdrive/ephyr/ephyrlog.h b/hw/kdrive/ephyr/ephyrlog.h
new file mode 100644
index 0000000..4c6435e
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrlog.h
@@ -0,0 +1,67 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+#ifndef __EPHYRLOG_H__
+#define __EPHYRLOG_H__
+
+#include <assert.h>
+#include "os.h"
+
+#ifdef NDEBUG
+/*we are not in debug mode*/
+#define EPHYR_LOG
+#define EPHYR_LOG_ERROR
+#endif /*NDEBUG*/
+
+#define ERROR_LOG_LEVEL 3
+#define INFO_LOG_LEVEL 4
+
+#ifndef EPHYR_LOG
+#define EPHYR_LOG(...) \
+LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, "in %s:%d:%s: ",\
+                      __FILE__, __LINE__, __func__) ; \
+LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, __VA_ARGS__)
+#endif /*nomadik_log*/
+
+#ifndef EPHYR_LOG_ERROR
+#define EPHYR_LOG_ERROR(...) \
+LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, "Error:in %s:%d:%s: ",\
+                      __FILE__, __LINE__, __func__) ; \
+LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, __VA_ARGS__)
+#endif /*EPHYR_LOG_ERROR*/
+
+#ifndef EPHYR_RETURN_IF_FAIL
+#define EPHYR_RETURN_IF_FAIL(cond) \
+if (!(cond)) {EPHYR_LOG_ERROR("condition %s failed\n", #cond);return;}
+#endif /*nomadik_return_if_fail*/
+
+#ifndef EPHYR_RETURN_VAL_IF_FAIL
+#define EPHYR_RETURN_VAL_IF_FAIL(cond,val) \
+if (!(cond)) {EPHYR_LOG_ERROR("condition %s failed\n", #cond);return val;}
+#endif /*nomadik_return_val_if_fail*/
+
+#endif /*__EPHYRLOG_H__*/
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
new file mode 100644
index 0000000..6be177b
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -0,0 +1,448 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ *          Authored by Matthew Allum <mallum at openedhand.com>
+ * 
+ * Copyright © 2007 OpenedHand Ltd 
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ *    Dodji Seketeli <dodji at openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include <string.h>
+#include <X11/extensions/Xv.h>
+#include "ephyrlog.h"
+#include "kdrive.h"
+#include "kxv.h"
+#include "ephyr.h"
+#include "hostx.h"
+#include "ephyrhostvideo.h"
+
+struct _EphyrXVPriv {
+    EphyrHostXVAdaptorArray *host_adaptors ;
+    KdVideoAdaptorPtr adaptors ;
+    int num_adaptors ;
+};
+
+typedef struct _EphyrXVPriv EphyrXVPriv ;
+
+static EphyrXVPriv* EphyrXVPrivNew (void) ;
+static void EphyrXVPrivDelete (EphyrXVPriv *a_this) ;
+static Bool EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
+static Bool EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
+
+static void EphyrStopVideo (KdScreenInfo *a_info,
+                            pointer a_xv_priv,
+                            Bool a_exit);
+
+static int EphyrSetPortAttribute (KdScreenInfo *a_info,
+                                  Atom a_attr_name,
+                                  int a_attr_value,
+                                  pointer a_xv_priv);
+
+static int EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
+                                  Atom a_attr_name,
+                                  int *a_attr_value,
+                                  pointer a_xv_priv);
+
+static void EphyrQueryBestSize (KdScreenInfo *a_info,
+                                Bool a_motion,
+                                short a_src_w,
+                                short a_src_h,
+                                short a_drw_w,
+                                short a_drw_h,
+                                unsigned int *a_prefered_w,
+                                unsigned int *a_prefered_h,
+                                pointer a_xv_priv);
+
+static int EphyrPutImage (KdScreenInfo *a_info,
+                          DrawablePtr a_drawable,
+                          short a_src_x,
+                          short a_src_y,
+                          short a_drw_x,
+                          short a_drw_y,
+                          short a_src_w,
+                          short a_src_h,
+                          short a_drw_w,
+                          short a_drw_h,
+                          int a_id,
+                          unsigned char *a_buf,
+                          short a_width,
+                          short a_height,
+                          Bool a_sync,
+                          RegionPtr a_clipping_region,
+                          pointer a_xv_priv);
+
+static int EphyrQueryImageAttributes (KdScreenInfo *a_info,
+                                      int a_id,
+                                      unsigned short *a_w,
+                                      unsigned short *a_h,
+                                      int *a_pitches,
+                                      int *a_offsets);
+
+Bool
+ephyrInitVideo (ScreenPtr pScreen)
+{
+    KdScreenPriv(pScreen);
+    KdScreenInfo *screen = pScreenPriv->screen;
+    EphyrXVPriv *xv_priv = NULL ;
+    KdVideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+    KdVideoAdaptorPtr newAdaptor = NULL;
+    int num_adaptors=0;
+
+    EPHYR_LOG ("enter\n") ;
+
+    if (screen->fb[0].bitsPerPixel == 8) {
+        EPHYR_LOG_ERROR ("8 bits depth not supported\n") ;
+        return FALSE ;
+    }
+
+    xv_priv = EphyrXVPrivNew () ;
+    if (!xv_priv) {
+        EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
+        return FALSE ;
+    }
+
+    /*
+     * TODO:
+     * queried host adaptors, now get xv_priv->adaptors and.
+     * add it to those already existing.
+     */
+    num_adaptors = KdXVListGenericAdaptors (screen, &adaptors);
+
+    if (newAdaptor) {
+        if (!num_adaptors) {
+            num_adaptors = 1;
+            adaptors = &newAdaptor;
+        } else {
+            newAdaptors = xalloc ((num_adaptors + 1) * sizeof(KdVideoAdaptorPtr*));
+            if (newAdaptors) {
+                memcpy (newAdaptors,
+                        adaptors,
+                        num_adaptors * sizeof(KdVideoAdaptorPtr));
+                newAdaptors[num_adaptors] = newAdaptor;
+                adaptors = newAdaptors;
+                num_adaptors++;
+            }
+        }
+    }
+
+    if (num_adaptors) {
+        KdXVScreenInit (pScreen, adaptors, num_adaptors);
+    } else {
+        EPHYR_LOG_ERROR ("XVideo not initialised\n") ;
+    }
+
+    if (newAdaptors)
+        xfree (newAdaptors);
+    return TRUE;
+}
+
+static EphyrXVPriv*
+EphyrXVPrivNew (void)
+{
+    EphyrXVPriv *xv_priv=NULL ;
+
+    EPHYR_LOG ("enter\n") ;
+
+    xv_priv = xcalloc (1, sizeof (EphyrXVPriv)) ;
+    if (!xv_priv) {
+        EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ;
+        goto error ;
+    }
+    if (!EphyrXVPrivQueryHostAdaptors (xv_priv)) {
+        EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
+        goto error ;
+    }
+    if (EphyrXVPrivSetAdaptorsHooks (xv_priv)) {
+        EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
+        goto error ;
+    }
+
+    EPHYR_LOG ("leave\n") ;
+    return xv_priv ;
+
+error:
+    if (xv_priv) {
+        EphyrXVPrivDelete (xv_priv) ;
+        xv_priv = NULL ;
+    }
+    return NULL ;
+}
+
+static void
+EphyrXVPrivDelete (EphyrXVPriv *a_this)
+{
+    EPHYR_LOG ("enter\n") ;
+
+    if (!a_this)
+        return ;
+    if (a_this->host_adaptors) {
+        EphyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
+        a_this->host_adaptors = NULL ;
+    }
+    if (a_this->adaptors) {
+        xfree (a_this->adaptors) ;
+        a_this->adaptors = NULL ;
+    }
+    xfree (a_this) ;
+    EPHYR_LOG ("leave\n") ;
+}
+
+static KdVideoEncodingPtr
+videoEncodingDup (EphyrHostEncoding *a_encodings,
+                   int a_num_encodings)
+{
+    KdVideoEncodingPtr result = NULL ;
+    int i=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
+
+    result = xcalloc (a_num_encodings, sizeof (KdVideoEncodingRec)) ;
+    for (i=0 ; i < a_num_encodings; i++) {
+        result[i].id = a_encodings[i].id ;
+        result[i].name = strdup (a_encodings[i].name) ;
+        result[i].width = a_encodings[i].width ;
+        result[i].height = a_encodings[i].height ;
+        result[i].rate.numerator = a_encodings[i].rate.numerator ;
+        result[i].rate.denominator = a_encodings[i].rate.denominator ;
+    }
+    return result ;
+}
+
+static KdAttributePtr
+portAttributesDup (EphyrHostAttribute *a_encodings,
+                   int a_num_encodings)
+{
+    int i=0 ;
+    KdAttributePtr result=NULL ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
+
+    result = xcalloc (a_num_encodings, sizeof (KdAttributeRec)) ;
+    if (!result) {
+        EPHYR_LOG_ERROR ("failed to allocate attributes\n") ;
+        return NULL ;
+    }
+    for (i=0; i < a_num_encodings; i++) {
+        result[i].flags = a_encodings[i].flags ;
+        result[i].min_value = a_encodings[i].min_value ;
+        result[i].max_value = a_encodings[i].max_value ;
+        result[i].name = strdup (a_encodings[i].name) ;
+    }
+    return result ;
+}
+
+static Bool
+EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
+{
+    EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
+    EphyrHostVideoFormat *video_formats=NULL ;
+    EphyrHostEncoding *encodings=NULL ;
+    EphyrHostAttribute *attributes=NULL ;
+    EphyrHostImageFormat *image_formats=NULL ;
+    int num_video_formats=0, base_port_id=0, num_attributes=0, num_formats=0, res=0, i=0 ;
+    unsigned num_encodings=0 ;
+    Bool is_ok = FALSE ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
+
+    if (!EphyrHostXVQueryAdaptors (&a_this->host_adaptors) || !a_this->host_adaptors) {
+        EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", res) ;
+        goto out ;
+    }
+    a_this->num_adaptors = EphyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
+    if (a_this->num_adaptors < 0) {
+        EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
+        goto out ;
+    }
+    /*
+     * copy what we can from adaptors into a_this->adaptors
+     */
+    a_this->adaptors = xcalloc (a_this->num_adaptors, sizeof (KdVideoAdaptorRec)) ;
+    if (!a_this->host_adaptors) {
+        EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
+        goto out ;
+    }
+    for (i=0; i < a_this->num_adaptors; i++) {
+        int j=0 ;
+        cur_host_adaptor = EphyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+        if (!cur_host_adaptor)
+            continue ;
+        a_this->adaptors[i].type = EphyrHostXVAdaptorGetType (cur_host_adaptor) ;
+        a_this->adaptors[i].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+        if (EphyrHostXVAdaptorGetName (cur_host_adaptor))
+            a_this->adaptors[i].name =
+                                strdup (EphyrHostXVAdaptorGetName (cur_host_adaptor)) ;
+        a_this->adaptors[i].name = "Xephyr Video Overlay";
+        base_port_id = EphyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
+        if (base_port_id < 0) {
+            EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
+            continue ;
+        }
+        if (!EphyrHostXVQueryEncodings (base_port_id, &encodings, &num_encodings)) {
+            EPHYR_LOG_ERROR ("failed to get encodings for port port id %d, adaptors %d\n",
+                             base_port_id, i) ;
+            continue ;
+        }
+        a_this->adaptors[i].nEncodings = num_encodings ;
+        a_this->adaptors[i].pEncodings = videoEncodingDup (encodings, num_encodings) ;
+        video_formats = (EphyrHostVideoFormat*)
+            EphyrHostXVAdaptorGetVideoFormats (cur_host_adaptor, &num_video_formats);
+        a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
+        a_this->adaptors[i].nFormats = num_video_formats ;
+        a_this->adaptors[i].nPorts = EphyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+        a_this->adaptors[i].pPortPrivates = xcalloc (a_this->adaptors[i].nPorts,
+                                                     sizeof (DevUnion)) ;
+        for (j=0; j < a_this->adaptors[i].nPorts; j++) {
+            a_this->adaptors[i].pPortPrivates[j].ptr = a_this ;
+        }
+        if (!EphyrHostXVQueryPortAttributes (base_port_id,
+                                             &attributes,
+                                             &num_attributes)) {
+            EPHYR_LOG_ERROR ("failed to get port attribute for adaptor %d\n", i) ;
+            continue ;
+        }
+        a_this->adaptors[i].pAttributes = portAttributesDup (attributes, num_attributes);
+        a_this->adaptors[i].nAttributes = num_attributes ;
+        if (!EphyrHostXVQueryImageFormats (base_port_id, &image_formats, &num_formats)) {
+            EPHYR_LOG_ERROR ("failed to get image formats for adaptor %d\n", i) ;
+            continue ;
+        }
+        a_this->adaptors[i].pImages = (KdImagePtr) image_formats ;
+    }
+    is_ok = TRUE ;
+
+out:
+    if (encodings) {
+        EphyrHostEncodingsDelete (encodings, num_encodings) ;
+        encodings = NULL ;
+    }
+    if (attributes) {
+        EphyrHostAttributesDelete (attributes, num_attributes) ;
+        attributes = NULL ;
+    }
+    if (image_formats) {
+        xfree (image_formats) ;
+        image_formats = NULL ;
+    }
+    return is_ok ;
+}
+
+static Bool
+EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
+{
+    int i=0 ;
+
+    EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
+
+    for (i=0; i < a_this->num_adaptors; i++) {
+        a_this->adaptors[i].StopVideo = EphyrStopVideo ;
+        a_this->adaptors[i].SetPortAttribute = EphyrSetPortAttribute ;
+        a_this->adaptors[i].GetPortAttribute = EphyrGetPortAttribute ;
+        a_this->adaptors[i].QueryBestSize = EphyrQueryBestSize ;
+        a_this->adaptors[i].PutImage = EphyrPutImage;
+        a_this->adaptors[i].QueryImageAttributes = EphyrQueryImageAttributes ;
+    }
+    return TRUE ;
+}
+
+static void
+EphyrStopVideo (KdScreenInfo *a_info, pointer a_xv_priv, Bool a_exit)
+{
+    EPHYR_LOG ("enter\n") ;
+    EPHYR_LOG ("leave\n") ;
+}
+
+static int
+EphyrSetPortAttribute (KdScreenInfo *a_info,
+                       Atom a_attr_name,
+                       int a_attr_value,
+                       pointer a_xv_priv)
+{
+    EPHYR_LOG ("enter\n") ;
+    return 0 ;
+    EPHYR_LOG ("leave\n") ;
+}
+
+static int
+EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
+                       Atom a_attr_name,
+                       int *a_attr_value,
+                       pointer a_xv_priv)
+{
+    EPHYR_LOG ("enter\n") ;
+    return 0 ;
+    EPHYR_LOG ("leave\n") ;
+}
+
+static void
+EphyrQueryBestSize (KdScreenInfo *a_info,
+                    Bool a_motion,
+                    short a_src_w,
+                    short a_src_h,
+                    short a_drw_w,
+                    short a_drw_h,
+                    unsigned int *a_prefered_w,
+                    unsigned int *a_prefered_h,
+                    pointer a_xv_priv)
+{
+}
+
+static int
+EphyrPutImage (KdScreenInfo *a_info,
+               DrawablePtr a_drawable,
+               short a_src_x,
+               short a_src_y,
+               short a_drw_x,
+               short a_drw_y,
+               short a_src_w,
+               short a_src_h,
+               short a_drw_w,
+               short a_drw_h,
+               int a_id,
+               unsigned char *a_buf,
+               short a_width,
+               short a_height,
+               Bool a_sync,
+               RegionPtr a_clipping_region,
+               pointer a_xv_priv)
+{
+    EPHYR_LOG ("enter\n") ;
+    return 0 ;
+    EPHYR_LOG ("leave\n") ;
+}
+
+static int
+EphyrQueryImageAttributes (KdScreenInfo *a_info,
+                           int a_id,
+                           unsigned short *a_w,
+                           unsigned short *a_h,
+                           int *a_pitches,
+                           int *a_offsets)
+{
+    EPHYR_LOG ("enter\n") ;
+    return 0 ;
+    EPHYR_LOG ("leave\n") ;
+}
+
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 81678d9..11cfe26 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -956,3 +956,9 @@ hostx_get_event(EphyrHostXEvent *ev)
   return 0;
 }
 
+void*
+hostx_get_display(void)
+{
+    return HostX.dpy ;
+}
+
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 93765d0..dc8eb99 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -172,4 +172,7 @@ hostx_load_keymap(void);
 int
 hostx_get_event(EphyrHostXEvent *ev);
 
+void*
+hostx_get_display(void) ;
+
 #endif
commit 95fadbd4022ec99f42ba78ec8a18a064903e8a7f
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Mon Jul 16 17:37:21 2007 +0200

    Add basic Exa driver entry point validation.
    
    In exaDriverInit(), quickly check if the programmer forgot to set some
    mandadory driver hooks, in that case display a meaningful error message.

diff --git a/exa/exa.c b/exa/exa.c
index 3e8054d..fc1f419 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -722,6 +722,48 @@ exaDriverAlloc(void)
     return xcalloc(1, sizeof(ExaDriverRec));
 }
 
+static Bool
+exaDriverValidateEntryPoints (ExaDriverPtr  pExaDriver)
+{
+    Bool res=TRUE ;
+
+    if (!pExaDriver)
+        return FALSE ;
+
+    if (!pExaDriver->memoryBase) {
+        LogMessage(X_ERROR,
+                   "Exa: Exa::memoryBase member "
+                   "must be assigned to a value different from zero\n") ;
+        res = FALSE ;
+    }
+    if (!pExaDriver->memorySize) {
+        LogMessage(X_ERROR,
+                   "Exa: Exa::memorySize member must be different from zero\n") ;
+        res = FALSE ;
+    }
+    if (pExaDriver->offScreenBase > pExaDriver->memorySize) {
+        LogMessage(X_ERROR,
+                   "Exa: Exa::ffscreenBase must be <= pExaDriver->memorySize member\n") ;
+        res = FALSE ;
+    }
+    if (!pExaDriver->PrepareSolid) {
+        LogMessage(X_ERROR,
+                   "Exa: Exa::PrepareSolid member is required to be non NULL\n") ;
+        res = FALSE ;
+    }
+    if (!pExaDriver->PrepareCopy) {
+        LogMessage(X_ERROR,
+                   "Exa: Exa::PrepareCopy member is required to be non NULL\n") ;
+        res = FALSE ;
+    }
+    if (!pExaDriver->WaitMarker) {
+        LogMessage(X_ERROR,
+                   "Exa: Exa::WaitWarker member is required to be non NULL\n") ;
+        res = FALSE ;
+    }
+    return res ;
+}
+
 /**
  * @param pScreen screen being initialized
  * @param pScreenInfo EXA driver record
@@ -806,6 +848,12 @@ exaDriverInit (ScreenPtr		pScreen,
     {
         pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
     }
+    if (!exaDriverValidateEntryPoints(pScreenInfo))
+    {
+	LogMessage(X_ERROR, "Exa(%d): EXA driver entry points validation failed\n",
+		   pScreen->myNum) ;
+	return FALSE ;
+    }
 
 #ifdef RENDER
     ps = GetPictureScreenIfSet(pScreen);
commit e5e6514ffa0fd132e0cc1b15b94119e6e8755f43
Author: Andrew Christan <andrew.christian at nokia.com>
Date:   Tue Oct 2 13:25:51 2007 +0200

    Xephyr: add "multiscreen" suport
    
    	* This patch adds multiscreen support to Xephyr. For instance,
    	  the command line : "Xephyr :4 -ac -screen 320x240 -screen 640x480"
    	  will launch with two "screens" - namely two main windows.
    	  The first main window represents a screen that has the number :4.0, with
    	  a geometry of 320x240 pixels, and the second one represents a screen
    	  that has the number :4.1 with a geometry of 640x480.
    	  The command line: "DISPLAY=:4.1 xclock" will launch the xclock program
    	  on the second screen, for intance.
    
    	*   this patch was edited by Dodji Seketeli <dodji at openedhand.com> for:
    	  - better style compliance with the rest of the Xephyr code
    	  - make sure Xephyr could be launched with no -screen option. By
    	    default that creates a default screen of 640x480 pixel like before
    	  - display full titles on the windows - with insctructions to grab
    	    keyboard and mouse - like before.

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index e8001df..c5cb21a 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -34,6 +34,7 @@
 #include "ephyr.h"
 
 #include "inputstr.h"
+#include "scrnintstr.h"
 
 extern int KdTsPhyScreen;
 KdKeyboardInfo *ephyrKbd;
@@ -83,7 +84,7 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
   int width = 640, height = 480; 
   unsigned long redMask, greenMask, blueMask;
   
-  if (hostx_want_screen_size(&width, &height) 
+  if (hostx_want_screen_size(screen, &width, &height)
       || !screen->width || !screen->height)
     {
       screen->width = width;
@@ -99,13 +100,13 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
 	  && (screen->fb[0].depth == 24 || screen->fb[0].depth == 16
 	      || screen->fb[0].depth == 8))
 	{
-	  hostx_set_server_depth(screen->fb[0].depth);
+	  hostx_set_server_depth(screen, screen->fb[0].depth);
 	}
-      else 
+      else
 	ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n");
     }
   
-  screen->fb[0].depth = hostx_get_server_depth();
+  screen->fb[0].depth = hostx_get_server_depth(screen);
   screen->rate = 72;
   
   if (screen->fb[0].depth <= 8)
@@ -146,7 +147,7 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
 	  screen->fb[0].bitsPerPixel = 32;
 	}
 
-      hostx_get_visual_masks (&redMask, &greenMask, &blueMask);
+      hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask);
 
       screen->fb[0].redMask = (Pixel) redMask;
       screen->fb[0].greenMask = (Pixel) greenMask;
@@ -194,9 +195,7 @@ ephyrWindowLinear (ScreenPtr	pScreen,
   EphyrPriv	    *priv = pScreenPriv->card->driver;
   
   if (!pScreenPriv->enabled)
-    {
-      return 0;
-    }
+    return 0;
 
   *size = priv->bytes_per_line;
   return priv->base + row * priv->bytes_per_line + offset;
@@ -210,8 +209,8 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
   KdPointerMatrix m;
   int buffer_height;
   
-  EPHYR_DBG(" screen->width: %d, screen->height: %d",
-	    screen->width, screen->height);
+  EPHYR_DBG("screen->width: %d, screen->height: %d index=%d",
+	     screen->width, screen->height, screen->mynum);
   
   KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
   KdSetPointerMatrix (&m);
@@ -226,8 +225,8 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
     buffer_height = screen->height;
   else
     buffer_height = 3 * screen->height;
-  
-  priv->base = hostx_screen_init (screen->width, screen->height, buffer_height);
+
+  priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height);
 
   screen->memory_base  = (CARD8 *) (priv->base);
   screen->memory_size  = priv->bytes_per_line * buffer_height;
@@ -304,7 +303,7 @@ ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
    * pBuf->pDamage  regions     
   */
   shadowUpdateRotatePacked(pScreen, pBuf);
-  hostx_paint_rect(0,0,0,0, screen->width, screen->height);
+  hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height);
 }
 
 static void
@@ -314,29 +313,29 @@ ephyrInternalDamageRedisplay (ScreenPtr pScreen)
   KdScreenInfo	*screen = pScreenPriv->screen;
   EphyrScrPriv	*scrpriv = screen->driver;
   RegionPtr	 pRegion;
-  
+
   if (!scrpriv || !scrpriv->pDamage)
     return;
-  
+
   pRegion = DamageRegion (scrpriv->pDamage);
-  
+
   if (REGION_NOTEMPTY (pScreen, pRegion))
     {
       int           nbox;
       BoxPtr        pbox;
-      
+
       nbox = REGION_NUM_RECTS (pRegion);
       pbox = REGION_RECTS (pRegion);
-      
+
       while (nbox--)
-	{
-	  hostx_paint_rect(pbox->x1, pbox->y1,
-			   pbox->x1, pbox->y1,
-			   pbox->x2 - pbox->x1,
-			   pbox->y2 - pbox->y1);
-	  pbox++;
-	}
-      
+        {
+          hostx_paint_rect(screen,
+                           pbox->x1, pbox->y1,
+                           pbox->x1, pbox->y1,
+                           pbox->x2 - pbox->x1,
+                           pbox->y2 - pbox->y1);
+          pbox++;
+        }
       DamageEmpty (scrpriv->pDamage);
     }
 }
@@ -432,11 +431,11 @@ ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
       { 160, 160 }, 
       { 0, 0 }
     };
-  
+
   *rotations = RR_Rotate_All|RR_Reflect_All;
-  
-  if (!hostx_want_preexisting_window()
-      && !hostx_want_fullscreen()) /* only if no -parent switch */
+
+  if (!hostx_want_preexisting_window (screen)
+      && !hostx_want_fullscreen ()) /* only if no -parent switch */
     {
       while (sizes[n].width != 0 && sizes[n].height != 0)
 	{
@@ -586,9 +585,7 @@ ephyrRandRInit (ScreenPtr pScreen)
   rrScrPrivPtr    pScrPriv;
   
   if (!RRScreenInit (pScreen))
-    {
-      return FALSE;
-    }
+    return FALSE;
   
   pScrPriv = rrGetScrPriv(pScreen);
   pScrPriv->rrGetInfo = ephyrRandRGetInfo;
@@ -606,6 +603,12 @@ ephyrCreateColormap (ColormapPtr pmap)
 Bool
 ephyrInitScreen (ScreenPtr pScreen)
 {
+  KdScreenPriv(pScreen);
+  KdScreenInfo	*screen    = pScreenPriv->screen;
+
+  EPHYR_DBG ("pScreen->myNum:%d\n", pScreen->myNum) ;
+  hostx_set_screen_number (screen, pScreen->myNum);
+  hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
   pScreen->CreateColormap = ephyrCreateColormap;
   return TRUE;
 }
@@ -634,7 +637,8 @@ ephyrCreateResources (ScreenPtr pScreen)
   KdScreenInfo	*screen    = pScreenPriv->screen;
   EphyrScrPriv	*scrpriv   = screen->driver;
 
-  EPHYR_DBG("mark");
+  EPHYR_DBG("mark pScreen=%p mynum=%d shadow=%d",
+            pScreen, pScreen->myNum, scrpriv->shadow);
 
   if (scrpriv->shadow) 
     return KdShadowSet (pScreen, 
@@ -743,6 +747,56 @@ ephyrUpdateModifierState(unsigned int state)
     }
 }
 
+static void
+ephyrBlockSigio (void)
+{
+    sigset_t set;
+
+    sigemptyset (&set);
+    sigaddset (&set, SIGIO);
+    sigprocmask (SIG_BLOCK, &set, 0);
+}
+
+static void
+ephyrUnblockSigio (void)
+{
+    sigset_t set;
+
+    sigemptyset (&set);
+    sigaddset (&set, SIGIO);
+    sigprocmask (SIG_UNBLOCK, &set, 0);
+}
+
+static Bool
+ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+  return FALSE;
+}
+
+static void
+ephyrCrossScreen (ScreenPtr pScreen, Bool entering)
+{
+}
+
+int ephyrCurScreen; /*current event screen*/
+
+static void
+ephyrWarpCursor (ScreenPtr pScreen, int x, int y)
+{
+    ephyrBlockSigio ();
+    ephyrCurScreen = pScreen->myNum;
+    miPointerWarpCursor (pScreen, x, y);
+    ephyrUnblockSigio ();
+}
+
+miPointerScreenFuncRec ephyrPointerScreenFuncs =
+{
+  ephyrCursorOffScreen,
+  ephyrCrossScreen,
+  ephyrWarpCursor
+};
+
+
 void
 ephyrPoll(void)
 {
@@ -751,21 +805,39 @@ ephyrPoll(void)
   while (hostx_get_event(&ev))
     {
       switch (ev.type)
-	{
-	case EPHYR_EV_MOUSE_MOTION:
+        {
+        case EPHYR_EV_MOUSE_MOTION:
           if (!ephyrMouse ||
-              !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
+              !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+              EPHYR_DBG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
               continue;
-	  KdEnqueuePointerEvent(ephyrMouse, mouseState,  
-			        ev.data.mouse_motion.x, 
-			        ev.data.mouse_motion.y,
-                                0);
-	  break;
-	  
-	case EPHYR_EV_MOUSE_PRESS:
+          }
+          {
+            if (ephyrCurScreen != ev.data.mouse_motion.screen)
+              {
+                  EPHYR_DBG ("warping mouse cursor:%d\n", ephyrCurScreen) ;
+                  ephyrWarpCursor(screenInfo.screens[ev.data.mouse_motion.screen],
+                                   ev.data.mouse_motion.x,
+                                   ev.data.mouse_motion.y );
+              }
+            else
+              {
+                  EPHYR_DBG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
+                  KdEnqueuePointerEvent(ephyrMouse, mouseState,
+                                        ev.data.mouse_motion.x,
+                                        ev.data.mouse_motion.y,
+                                        0);
+              }
+          }
+          break;
+
+        case EPHYR_EV_MOUSE_PRESS:
           if (!ephyrMouse ||
-              !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
+              !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+              EPHYR_DBG ("skipping mouse press:%d\n", ephyrCurScreen) ;
               continue;
+          }
+          EPHYR_DBG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
 	  ephyrUpdateModifierState(ev.key_state);
 	  mouseState |= ev.data.mouse_down.button_num;
 	  KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
@@ -777,6 +849,7 @@ ephyrPoll(void)
               continue;
 	  ephyrUpdateModifierState(ev.key_state);
 	  mouseState &= ~ev.data.mouse_up.button_num;
+          EPHYR_DBG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
 	  KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
 	  break;
 
@@ -792,7 +865,6 @@ ephyrPoll(void)
           if (!ephyrKbd ||
               !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
               continue;
-	  ephyrUpdateModifierState(ev.key_state);
 	  KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
 	  break;
 
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index f49d920..1c9b4f8 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -71,6 +71,8 @@ extern KdCardFuncs ephyrFuncs;
 extern KdKeyboardInfo *ephyrKbd;
 extern KdPointerInfo *ephyrMouse;
 
+extern miPointerScreenFuncRec ephyrPointerScreenFuncs;
+
 Bool
 ephyrInitialize (KdCardInfo *card, EphyrPriv *priv);
 
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index a76da03..6874609 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -33,6 +33,8 @@ extern Bool   EphyrWantGrayScale;
 extern Bool   kdHasPointer;
 extern Bool   kdHasKbd;
 
+void processScreenArg (char *screen_size, char *parent_id) ;
+
 void
 InitCard (char *name)
 {
@@ -100,19 +102,60 @@ ddxUseMsg (void)
   exit(1);
 }
 
+void
+processScreenArg (char *screen_size, char *parent_id)
+{
+  KdCardInfo   *card;
+  static int card_exists;
+
+  InitCard (0);  /*Put each screen on a separate card*/
+  card = KdCardInfoLast ();
+
+  if (card)
+    {
+      KdScreenInfo *screen;
+      unsigned long p_id = 0;
+
+      screen = KdScreenInfoAdd (card);
+      KdParseScreen (screen, screen_size);
+
+      if (parent_id)
+        {
+          p_id = strtol (parent_id, NULL, 0);
+        }
+      EPHYR_DBG ("screen number:%d\n", screen->mynum) ;
+      hostx_add_screen (screen, p_id, screen->mynum);
+    }
+  else
+    {
+      ErrorF("No matching card found!\n");
+    }
+}
+
 int
 ddxProcessArgument (int argc, char **argv, int i)
 {
-  EPHYR_DBG("mark");
+  EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] );
 
   if (!strcmp (argv[i], "-parent"))
     {
-      if(i+1 < argc) 
+      if(i+1 < argc)
 	{
-	  hostx_use_preexisting_window(strtol(argv[i+1], NULL, 0));
+	  processScreenArg ("100x100", argv[i+1]);
 	  return 2;
-	} 
-      
+	}
+
+      UseMsg();
+      exit(1);
+    }
+  else if (!strcmp (argv[i], "-screen"))
+    {
+      if ((i+1) < argc)
+	{
+	  processScreenArg (argv[i+1], NULL);
+	  return 2;
+	}
+
       UseMsg();
       exit(1);
     }
@@ -198,8 +241,10 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
 Bool
 ephyrCursorInit(ScreenPtr pScreen)
 {
-  miPointerInitialize(pScreen, &EphyrPointerSpriteFuncs,
-		      &kdPointerScreenFuncs, FALSE);
+  miPointerInitialize(pScreen, 
+		      &EphyrPointerSpriteFuncs,
+		      &ephyrPointerScreenFuncs, 
+		      FALSE);
 
   return TRUE;
 }
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 36d3cbd..81678d9 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -47,33 +47,44 @@
  * to get clobbered. 
  */
 
+struct EphyrHostScreen
+{
+  Window          win;
+  Window          win_pre_existing; 	/* Set via -parent option like xnest */
+  XImage         *ximg;
+  int             win_width, win_height;
+  int             server_depth;
+  unsigned char  *fb_data;   	/* only used when host bpp != server bpp */
+  XShmSegmentInfo shminfo;
+
+  void           *info;   /* Pointer to the screen this is associated with */
+  int             mynum;  /* Screen number */
+};
+
 struct EphyrHostXVars
 {
   char           *server_dpy_name;
   Display        *dpy;
   int             screen;
   Visual         *visual;
-  Window          win, winroot;
-  Window          win_pre_existing; 	/* Set via -parent option like xnest */
+  Window          winroot;
   GC              gc;
   int             depth;
-  int             server_depth;
-  XImage         *ximg;
-  int             win_width, win_height;
   Bool            use_host_cursor;
   Bool            use_fullscreen;
   Bool            have_shm;
 
+  int             n_screens;
+  struct EphyrHostScreen *screens;
+
   long            damage_debug_msec;
 
-  unsigned char  *fb_data;   	/* only used when host bpp != server bpp */
   unsigned long   cmap[256];
-
-  XShmSegmentInfo shminfo;
 };
 
 /* memset ( missing> ) instead of below  */
-static EphyrHostXVars HostX = { "?", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+/*static EphyrHostXVars HostX = { "?", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};*/
+static EphyrHostXVars HostX;
 
 static int            HostXWantDamageDebug = 0;
 
@@ -89,8 +100,22 @@ hostx_set_fullscreen_hint(void);
 static int trapped_error_code = 0;
 static int (*old_error_handler) (Display *d, XErrorEvent *e);
 
-#define host_depth_matches_server() (HostX.depth == HostX.server_depth)
+#define host_depth_matches_server(_vars) (HostX.depth == (_vars)->server_depth)
 
+static struct EphyrHostScreen *
+host_screen_from_screen_info (EphyrScreenInfo *screen)
+{
+  int i;
+
+  for (i = 0 ; i < HostX.n_screens ; i++)
+    {
+      if ( HostX.screens[i].info == screen)
+        {
+          return &HostX.screens[i];
+        }
+    }
+  return NULL;
+}
 
 static int
 error_handler(Display     *display,
@@ -115,13 +140,16 @@ hostx_errors_untrap(void)
 }
 
 int
-hostx_want_screen_size(int *width, int *height)
+hostx_want_screen_size (EphyrScreenInfo screen, int *width, int *height )
 {
- if (HostX.win_pre_existing != None
-     || HostX.use_fullscreen == True)
+  struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+  if (host_screen &&
+       (host_screen->win_pre_existing != None ||
+         HostX.use_fullscreen == True))
     {
-      *width  = HostX.win_width;
-      *height = HostX.win_height;
+      *width  = host_screen->win_width;
+      *height = host_screen->win_height;
       return 1;
     }
 
@@ -129,100 +157,140 @@ hostx_want_screen_size(int *width, int *height)
 }
 
 void
-hostx_set_display_name(char *name)
+hostx_add_screen (EphyrScreenInfo screen,
+                  unsigned long win_id,
+                  int screen_num)
+{
+  int index = HostX.n_screens;
+
+  HostX.n_screens += 1;
+  HostX.screens = realloc (HostX.screens,
+                           HostX.n_screens * sizeof(struct EphyrHostScreen));
+  memset (&HostX.screens[index], 0, sizeof (struct EphyrHostScreen));
+
+  HostX.screens[index].info       = screen;
+  HostX.screens[index].win_pre_existing = win_id;
+}
+
+
+void
+hostx_set_display_name (char *name)
 {
-  HostX.server_dpy_name = strdup(name);
+  HostX.server_dpy_name = strdup (name);
 }
 
 void
-hostx_set_win_title(char *extra_text)
+hostx_set_screen_number(EphyrScreenInfo screen, int number)
 {
-  char buf[256];
+  struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+  if (host_screen) {
+    host_screen->mynum = number;
+    hostx_set_win_title (host_screen->info, "") ;
+  }}
+
+void
+hostx_set_win_title (EphyrScreenInfo screen, char *extra_text)
+{
+  struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+#define BUF_LEN 256
+  char buf[BUF_LEN+1];
+
+  if (!host_screen)
+    return;
 
-  snprintf(buf, 256, "Xephyr on %s %s", 
-	   HostX.server_dpy_name,
-	   (extra_text != NULL) ? extra_text : "");
+  memset (buf, 0, BUF_LEN+1) ;
+  snprintf (buf, BUF_LEN, "Xephyr on %s.%d %s", 
+            HostX.server_dpy_name, 
+            host_screen->mynum,
+            (extra_text != NULL) ? extra_text : "");
 
-  XStoreName(HostX.dpy, HostX.win, buf);
+  XStoreName (HostX.dpy, host_screen->win, buf);
 }
 
 int
-hostx_want_host_cursor(void)
+hostx_want_host_cursor (void)
 {
   return HostX.use_host_cursor;
 }
 
 void
-hostx_use_host_cursor(void)
+hostx_use_host_cursor (void)
 {
   HostX.use_host_cursor = True;
 }
 
 int
-hostx_want_preexisting_window(void)
+hostx_want_preexisting_window (EphyrScreenInfo screen)
 {
-  if (HostX.win_pre_existing) 
-    return 1;
+  struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+  if (host_screen && host_screen->win_pre_existing)
+    {
+      return 1;
+    }
   else
+    {
     return 0;
+    }
 }
 
 void
-hostx_use_fullscreen(void)
+hostx_use_fullscreen (void)
 {
   HostX.use_fullscreen = True;
 }
 
 int
-hostx_want_fullscreen(void)
+hostx_want_fullscreen (void)
 {
   return HostX.use_fullscreen;
 }
 
 static void
-hostx_set_fullscreen_hint(void)
+hostx_set_fullscreen_hint (void)
 {
   Atom atom_WINDOW_STATE, atom_WINDOW_STATE_FULLSCREEN;
+  int index;
 
   atom_WINDOW_STATE 
     = XInternAtom(HostX.dpy, "_NET_WM_STATE", False);
   atom_WINDOW_STATE_FULLSCREEN 
     = XInternAtom(HostX.dpy, "_NET_WM_STATE_FULLSCREEN",False);
 
-  XChangeProperty(HostX.dpy, HostX.win,
-		  atom_WINDOW_STATE, XA_ATOM, 32,
-		  PropModeReplace,
-		  (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
+  for (index = 0 ; index < HostX.n_screens ; index++)
+    {
+      XChangeProperty (HostX.dpy, HostX.screens[index].win,
+                       atom_WINDOW_STATE, XA_ATOM, 32,
+                       PropModeReplace,
+                       (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
+    }
 }
 
-void
-hostx_use_preexisting_window(unsigned long win_id)
-{
-  HostX.win_pre_existing = win_id;
-}
 
 static void
-hostx_toggle_damage_debug(void)
+hostx_toggle_damage_debug (void)
 {
   HostXWantDamageDebug ^= 1;
 }
 
-void 
-hostx_handle_signal(int signum)
+void
+hostx_handle_signal (int signum)
 {
   hostx_toggle_damage_debug();
-  EPHYR_DBG("Signal caught. Damage Debug:%i\n", HostXWantDamageDebug);
+  EPHYR_DBG ("Signal caught. Damage Debug:%i\n",
+              HostXWantDamageDebug);
 }
 
 int
-hostx_init(void)
+hostx_init (void)
 {
   XSetWindowAttributes  attr;
   Cursor                empty_cursor;
   Pixmap                cursor_pxm;
   XColor                col;
+  int                   index;
 
-  attr.event_mask = 
+  attr.event_mask =
     ButtonPressMask
     |ButtonReleaseMask
     |PointerMotionMask
@@ -233,126 +301,142 @@ hostx_init(void)
   EPHYR_DBG("mark");
 
   if ((HostX.dpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
-  {
-    fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
-    exit(1);
-  }
+    {
+      fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
+      exit(1);
+    }
 
   HostX.screen  = DefaultScreen(HostX.dpy);
   HostX.winroot = RootWindow(HostX.dpy, HostX.screen);
   HostX.gc      = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL);
   HostX.depth   = DefaultDepth(HostX.dpy, HostX.screen);
-  HostX.visual  = DefaultVisual(HostX.dpy, HostX.screen); 
-
-  HostX.server_depth = HostX.depth;
- 
-  if (HostX.win_pre_existing != None)
-    {
-      Status            result;
-      XWindowAttributes prewin_attr;
-
-      /* Get screen size from existing window */
-
-      hostx_errors_trap();
-
-      result = XGetWindowAttributes(HostX.dpy, 
-				    HostX.win_pre_existing, 
-				    &prewin_attr);
-
-
-      if (hostx_errors_untrap() || !result)
-	{
-	  fprintf(stderr, "\nXephyr -parent window' does not exist!\n");
-	  exit(1);
-	}
+  HostX.visual  = DefaultVisual(HostX.dpy, HostX.screen);
 
-      HostX.win_width  = prewin_attr.width;
-      HostX.win_height = prewin_attr.height;
-
-      HostX.win = XCreateWindow(HostX.dpy,
-				HostX.win_pre_existing,
-				0,0,HostX.win_width,HostX.win_height,
-				0,
-				CopyFromParent,
-				CopyFromParent,
-				CopyFromParent,
-				CWEventMask,
-				&attr);
-    }
-  else
+  for (index = 0 ; index < HostX.n_screens ; index++)
     {
-      HostX.win = XCreateWindow(HostX.dpy,
-				HostX.winroot,
-				0,0,100,100, /* will resize  */
-				0,
-			        CopyFromParent,
-				CopyFromParent,
-				CopyFromParent,
-				CWEventMask,
-				&attr);
-
-      hostx_set_win_title("( ctrl+shift grabs mouse and keyboard )");
-
-      if (HostX.use_fullscreen)
-	{
-	  HostX.win_width  = DisplayWidth(HostX.dpy, HostX.screen); 
-	  HostX.win_height = DisplayHeight(HostX.dpy, HostX.screen); 
-
-	  hostx_set_fullscreen_hint();
-	}
+      struct EphyrHostScreen *host_screen = &HostX.screens[index];
+
+      host_screen->server_depth = HostX.depth;
+      if (host_screen->win_pre_existing != None)
+        {
+          Status            result;
+          XWindowAttributes prewin_attr;
+
+          /* Get screen size from existing window */
+
+          hostx_errors_trap();
+
+          result = XGetWindowAttributes (HostX.dpy,
+                                         host_screen->win_pre_existing,
+                                         &prewin_attr);
+
+
+          if (hostx_errors_untrap() || !result)
+          {
+              fprintf (stderr, "\nXephyr -parent window' does not exist!\n");
+              exit (1);
+          }
+
+          host_screen->win_width  = prewin_attr.width;
+          host_screen->win_height = prewin_attr.height;
+
+          host_screen->win = XCreateWindow (HostX.dpy,
+                                            host_screen->win_pre_existing,
+                                            0,0,
+                                            host_screen->win_width,
+                                            host_screen->win_height,
+                                            0,
+                                            CopyFromParent,
+                                            CopyFromParent,
+                                            CopyFromParent,
+                                            CWEventMask,
+                                            &attr);
+        }
+      else
+        {
+          host_screen->win = XCreateWindow (HostX.dpy,
+                                            HostX.winroot,
+                                            0,0,100,100, /* will resize */
+                                            0,
+                                            CopyFromParent,
+                                            CopyFromParent,
+                                            CopyFromParent,
+                                            CWEventMask,
+                                            &attr);
+
+          hostx_set_win_title (host_screen->info,
+                               "(ctrl+shift grabs mouse and keyboard)");
+
+          if (HostX.use_fullscreen)
+            {
+              host_screen->win_width  = DisplayWidth(HostX.dpy, HostX.screen);
+              host_screen->win_height = DisplayHeight(HostX.dpy, HostX.screen);
+
+              hostx_set_fullscreen_hint();
+            }
+        }
     }
 
 
-  XParseColor(HostX.dpy, DefaultColormap(HostX.dpy,HostX.screen), "red", &col);
-  XAllocColor(HostX.dpy, DefaultColormap(HostX.dpy, HostX.screen), &col);
-  XSetForeground(HostX.dpy, HostX.gc, col.pixel);
+  XParseColor (HostX.dpy, DefaultColormap (HostX.dpy,HostX.screen),
+               "red", &col);
+  XAllocColor (HostX.dpy, DefaultColormap (HostX.dpy, HostX.screen),
+               &col);
+  XSetForeground (HostX.dpy, HostX.gc, col.pixel);
 
-  if (!hostx_want_host_cursor())
+  if (!hostx_want_host_cursor ())
     {
       /* Ditch the cursor, we provide our 'own' */
       cursor_pxm = XCreatePixmap (HostX.dpy, HostX.winroot, 1, 1, 1);
       memset (&col, 0, sizeof (col));
-      empty_cursor = XCreatePixmapCursor (HostX.dpy, 
-					  cursor_pxm, cursor_pxm, 
-					  &col, &col, 1, 1);
-      XDefineCursor (HostX.dpy, HostX.win, empty_cursor);
+      empty_cursor = XCreatePixmapCursor (HostX.dpy,
+                                          cursor_pxm, cursor_pxm, 
+                                          &col, &col, 1, 1);
+      for ( index = 0 ; index < HostX.n_screens ; index++ )
+        {
+          XDefineCursor (HostX.dpy,
+                         HostX.screens[index].win,
+                         empty_cursor);
+        }
       XFreePixmap (HostX.dpy, cursor_pxm);
     }
 
-  HostX.ximg   = NULL;
-
+  for (index = 0 ; index < HostX.n_screens ; index++)
+    {
+      HostX.screens[index].ximg   = NULL;
+    }
   /* Try to get share memory ximages for a little bit more speed */
 
-  if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM")) 
+  if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM"))
     {
       fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
       HostX.have_shm = False;
-    } 
-  else 		            
-    {	
+    }
+  else
+    {
       /* Really really check we have shm - better way ?*/
-      XShmSegmentInfo shminfo; 
+      XShmSegmentInfo shminfo;
 
-      HostX.have_shm = True;
+        HostX.have_shm = True;
 
-      shminfo.shmid=shmget(IPC_PRIVATE, 1, IPC_CREAT|0777);
-      shminfo.shmaddr=shmat(shminfo.shmid,0,0);
-      shminfo.readOnly=True;
+        shminfo.shmid=shmget(IPC_PRIVATE, 1, IPC_CREAT|0777);
+        shminfo.shmaddr=shmat(shminfo.shmid,0,0);
+        shminfo.readOnly=True;
 
-      hostx_errors_trap();
-      
-      XShmAttach(HostX.dpy, &shminfo);
-      XSync(HostX.dpy, False);
+        hostx_errors_trap();
 
-      if (hostx_errors_untrap())
-	{
-	  fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
-	  HostX.have_shm = False;
-	}
+        XShmAttach(HostX.dpy, &shminfo);
+        XSync(HostX.dpy, False);
 
-      shmdt(shminfo.shmaddr);
-      shmctl(shminfo.shmid, IPC_RMID, 0);
-    }
+        if (hostx_errors_untrap())
+          {
+            fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
+            HostX.have_shm = False;
+          }
+
+        shmdt(shminfo.shmaddr);
+        shmctl(shminfo.shmid, IPC_RMID, 0);
+}
 
   XFlush(HostX.dpy);
 
@@ -360,10 +444,10 @@ hostx_init(void)
 
   HostX.damage_debug_msec = 20000; /* 1/50 th of a second */
 
-  if (getenv("XEPHYR_PAUSE"))
+  if (getenv ("XEPHYR_PAUSE"))
     {
-      HostX.damage_debug_msec = strtol(getenv("XEPHYR_PAUSE"), NULL, 0);
-      EPHYR_DBG("pause is %li\n", HostX.damage_debug_msec);
+      HostX.damage_debug_msec = strtol (getenv ("XEPHYR_PAUSE"), NULL, 0);
+      EPHYR_DBG ("pause is %li\n", HostX.damage_debug_msec);
     }
 
   return 1;
@@ -376,38 +460,54 @@ hostx_get_depth (void)
 }
 
 int
-hostx_get_server_depth (void)
+hostx_get_server_depth (EphyrScreenInfo screen)
 {
-  return HostX.server_depth;
+  struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+  return (host_screen ? host_screen->server_depth : 0);
 }
 
 void
-hostx_set_server_depth(int depth)
+hostx_set_server_depth (EphyrScreenInfo screen, int depth)
 {
-  HostX.server_depth = depth;
+  struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+  if (host_screen)
+    host_screen->server_depth = depth;
 }
 
 int
-hostx_get_bpp(void)
+hostx_get_bpp (EphyrScreenInfo screen)
 {
-  if (host_depth_matches_server())
-    return  HostX.visual->bits_per_rgb;
+  struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+  if (!host_screen)
+    return 0;
+
+  if (host_depth_matches_server (host_screen))
+    return HostX.visual->bits_per_rgb;
   else
-    return HostX.server_depth; 	/* XXX correct ? */
+    return host_screen->server_depth; /*XXX correct ?*/
 }
 
 void
-hostx_get_visual_masks (CARD32 *rmsk, 
-			CARD32 *gmsk, 
+hostx_get_visual_masks (EphyrScreenInfo screen,
+			CARD32 *rmsk,
+			CARD32 *gmsk,
 			CARD32 *bmsk)
 {
-  if (host_depth_matches_server())
+  struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+  if (!host_screen)
+    return;
+
+  if (host_depth_matches_server(host_screen))
     {
       *rmsk = HostX.visual->red_mask;
       *gmsk = HostX.visual->green_mask;
       *bmsk = HostX.visual->blue_mask;
     }
-  else if (HostX.server_depth == 16)
+  else if (host_screen->server_depth == 16)
     {
       /* Assume 16bpp 565 */
       *rmsk = 0xf800;
@@ -423,9 +523,9 @@ hostx_get_visual_masks (CARD32 *rmsk,
 }
 
 void
-hostx_set_cmap_entry(unsigned char idx, 
-		     unsigned char r, 
-		     unsigned char g, 
+hostx_set_cmap_entry(unsigned char idx,
+		     unsigned char r,
+		     unsigned char g,
 		     unsigned char b)
 {
   /* XXX Will likely break for 8 on 16, not sure if this is correct */
@@ -445,15 +545,25 @@ hostx_set_cmap_entry(unsigned char idx,
  * by fakexa for storing offscreen pixmap data.
  */
 void*
-hostx_screen_init (int width, int height, int buffer_height)
+hostx_screen_init (EphyrScreenInfo screen,
+                   int width, int height,
+                   int buffer_height)
 {
   int         bitmap_pad;
   Bool        shm_success = False;
   XSizeHints *size_hints;
 
-  EPHYR_DBG("mark");
+  struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+  if (!host_screen)
+    {
+      fprintf (stderr, "%s: Error in accessing hostx data\n", __func__ );
+      exit(1);
+    }
 
-  if (HostX.ximg != NULL)
+  EPHYR_DBG ("host_screen=%p wxh=%dx%d, buffer_height=%d",
+             host_screen, width, height, buffer_height);
+
+  if (host_screen->ximg != NULL)
     {
       /* Free up the image data if previously used
        * i.ie called by server reset
@@ -461,47 +571,48 @@ hostx_screen_init (int width, int height, int buffer_height)
 
       if (HostX.have_shm)
 	{
-	  XShmDetach(HostX.dpy, &HostX.shminfo);
-	  XDestroyImage (HostX.ximg);
-	  shmdt(HostX.shminfo.shmaddr);
-	  shmctl(HostX.shminfo.shmid, IPC_RMID, 0);
+	  XShmDetach(HostX.dpy, &host_screen->shminfo);
+	  XDestroyImage (host_screen->ximg);
+	  shmdt(host_screen->shminfo.shmaddr);
+	  shmctl(host_screen->shminfo.shmid, IPC_RMID, 0);
 	}
       else
 	{
-	  if (HostX.ximg->data) 
+	  if (host_screen->ximg->data) 
 	    {
-	      free(HostX.ximg->data);
-	      HostX.ximg->data = NULL;
+	      free(host_screen->ximg->data);
+	      host_screen->ximg->data = NULL;
 	    } 
 
-	  XDestroyImage(HostX.ximg);
+	  XDestroyImage(host_screen->ximg);
 	}
     }
 
   if (HostX.have_shm)
     {
-      HostX.ximg = XShmCreateImage(HostX.dpy, HostX.visual, HostX.depth, 
-				   ZPixmap, NULL, &HostX.shminfo,
-				   width, buffer_height );
-	  
-      HostX.shminfo.shmid = shmget(IPC_PRIVATE,
-				   HostX.ximg->bytes_per_line * buffer_height,
-				   IPC_CREAT|0777);
-      HostX.shminfo.shmaddr = HostX.ximg->data = shmat(HostX.shminfo.shmid,
-						       0, 0);
-
-      if (HostX.ximg->data == (char *)-1)
+      host_screen->ximg = XShmCreateImage (HostX.dpy, HostX.visual, HostX.depth,
+                                           ZPixmap, NULL, &host_screen->shminfo,
+                                           width, buffer_height );
+
+      host_screen->shminfo.shmid =
+                      shmget(IPC_PRIVATE,
+                             host_screen->ximg->bytes_per_line * buffer_height,
+                             IPC_CREAT|0777);
+      host_screen->ximg->data = shmat(host_screen->shminfo.shmid, 0, 0);
+      host_screen->shminfo.shmaddr = host_screen->ximg->data;
+
+      if (host_screen->ximg->data == (char *)-1)
 	{
 	  EPHYR_DBG("Can't attach SHM Segment, falling back to plain XImages");
 	  HostX.have_shm = False;
-	  XDestroyImage(HostX.ximg);
-	  shmctl(HostX.shminfo.shmid, IPC_RMID, 0);
+	  XDestroyImage(host_screen->ximg);
+	  shmctl(host_screen->shminfo.shmid, IPC_RMID, 0);
 	}
       else
 	{
-	  EPHYR_DBG("SHM segment attached");
-	  HostX.shminfo.readOnly = False;
-	  XShmAttach(HostX.dpy, &HostX.shminfo);
+	  EPHYR_DBG("SHM segment attached %p", host_screen->shminfo.shmaddr);
+	  host_screen->shminfo.readOnly = False;
+	  XShmAttach(HostX.dpy, &host_screen->shminfo);
 	  shm_success = True;
 	}
     }
@@ -509,63 +620,74 @@ hostx_screen_init (int width, int height, int buffer_height)
   if (!shm_success)
     {
       bitmap_pad = ( HostX.depth > 16 )? 32 : (( HostX.depth > 8 )? 16 : 8 );
-	  
-      HostX.ximg = XCreateImage( HostX.dpy, 
-				 HostX.visual, 
-				 HostX.depth, 
-				 ZPixmap, 0, 0,
-				 width, 
-				 buffer_height, 
-				 bitmap_pad, 
-				 0);
-
-      HostX.ximg->data = malloc( HostX.ximg->bytes_per_line * buffer_height );
-    }
 
+      EPHYR_DBG("Creating image %dx%d for screen host_screen=%p\n",
+                width, buffer_height, host_screen );
+      host_screen->ximg = XCreateImage (HostX.dpy,
+                                        HostX.visual,
+                                        HostX.depth,
+                                        ZPixmap, 0, 0,
+                                        width,
+                                        buffer_height,
+                                        bitmap_pad,
+                                        0);
+
+      host_screen->ximg->data =
+              malloc (host_screen->ximg->bytes_per_line * buffer_height);
+    }
 
-  XResizeWindow(HostX.dpy, HostX.win, width, height);
+  XResizeWindow (HostX.dpy, host_screen->win, width, height);
 
   /* Ask the WM to keep our size static */
   size_hints = XAllocSizeHints();
   size_hints->max_width = size_hints->min_width = width;
   size_hints->max_height = size_hints->min_height = height;
   size_hints->flags = PMinSize|PMaxSize;
-  XSetWMNormalHints(HostX.dpy, HostX.win, size_hints);
+  XSetWMNormalHints(HostX.dpy, host_screen->win, size_hints);
   XFree(size_hints);
 
-  XMapWindow(HostX.dpy, HostX.win);
+  XMapWindow(HostX.dpy, host_screen->win);
 
   XSync(HostX.dpy, False);
 
-  HostX.win_width  = width;
-  HostX.win_height = height;
+  host_screen->win_width  = width;
+  host_screen->win_height = height;
 
-  if (host_depth_matches_server())
+  if (host_depth_matches_server(host_screen))
     {
       EPHYR_DBG("Host matches server");
-      return HostX.ximg->data;
+      return host_screen->ximg->data;
     }
   else
     {
-      EPHYR_DBG("server bpp %i", HostX.server_depth>>3);
-      HostX.fb_data = malloc(width*buffer_height*(HostX.server_depth>>3));
-      return HostX.fb_data;
+      EPHYR_DBG("server bpp %i", host_screen->server_depth>>3);
+      host_screen->fb_data = malloc(width*buffer_height*(host_screen->server_depth>>3));
+      return host_screen->fb_data;
     }
 }
 
+static void hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
+                                    int x,     int y,
+                                    int width, int height);
+
 void
-hostx_paint_rect(int sx,    int sy,
-		 int dx,    int dy, 
-		 int width, int height)
+hostx_paint_rect (EphyrScreenInfo screen,
+                  int sx,    int sy,
+                  int dx,    int dy,
+                  int width, int height)
 {
-  /* 
+  struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+  EPHYR_DBG ("painting in screen %d\n", host_screen->mynum) ;
+
+  /*
    *  Copy the image data updated by the shadow layer
    *  on to the window
    */
 
   if (HostXWantDamageDebug)
     {
-      hostx_paint_debug_rect(dx, dy, width, height);
+      hostx_paint_debug_rect(host_screen, dx, dy, width, height);
     }
 
   /* 
@@ -580,22 +702,23 @@ hostx_paint_rect(int sx,    int sy,
    *       ... and it will be slower than the matching depth case.
    */
 
-  if (!host_depth_matches_server())
+  if (!host_depth_matches_server(host_screen))
     {
-      int            x,y,idx, bytes_per_pixel = (HostX.server_depth>>3);
+      int            x,y,idx, bytes_per_pixel = (host_screen->server_depth>>3);
       unsigned char  r,g,b;
       unsigned long  host_pixel;
 
+      EPHYR_DBG("Unmatched host depth host_screen=%p\n", host_screen);
       for (y=sy; y<sy+height; y++)
 	for (x=sx; x<sx+width; x++)
 	  {
-	    idx = (HostX.win_width*y*bytes_per_pixel)+(x*bytes_per_pixel);
-	    
-	    switch (HostX.server_depth)
+	    idx = (host_screen->win_width*y*bytes_per_pixel)+(x*bytes_per_pixel);
+
+	    switch (host_screen->server_depth)
 	      {
 	      case 16:
 		{
-		  unsigned short pixel = *(unsigned short*)(HostX.fb_data+idx);
+		  unsigned short pixel = *(unsigned short*)(host_screen->fb_data+idx);
 
 		  r = ((pixel & 0xf800) >> 8);
 		  g = ((pixel & 0x07e0) >> 3);
@@ -603,13 +726,13 @@ hostx_paint_rect(int sx,    int sy,
 
 		  host_pixel = (r << 16) | (g << 8) | (b);
 		  
-		  XPutPixel(HostX.ximg, x, y, host_pixel);
+		  XPutPixel(host_screen->ximg, x, y, host_pixel);
 		  break;
 		}
 	      case 8:
 		{
-		  unsigned char pixel = *(unsigned char*)(HostX.fb_data+idx);
-		  XPutPixel(HostX.ximg, x, y, HostX.cmap[pixel]);
+		  unsigned char pixel = *(unsigned char*)(host_screen->fb_data+idx);
+		  XPutPixel(host_screen->ximg, x, y, HostX.cmap[pixel]);
 		  break;
 		}
 	      default:
@@ -620,21 +743,23 @@ hostx_paint_rect(int sx,    int sy,
 
   if (HostX.have_shm)
     {
-      XShmPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg, 
-		       sx, sy, dx, dy, width, height, False);
+      XShmPutImage (HostX.dpy, host_screen->win,
+                    HostX.gc, host_screen->ximg,
+                    sx, sy, dx, dy, width, height, False);
     }
   else
     {
-      XPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg, 
-		sx, sy, dx, dy, width, height);
+      XPutImage (HostX.dpy, host_screen->win, HostX.gc, host_screen->ximg, 
+                 sx, sy, dx, dy, width, height);
     }
 
-  XSync(HostX.dpy, False);
+  XSync (HostX.dpy, False);
 }
 
-void
-hostx_paint_debug_rect(int x,     int y, 
-		       int width, int height)
+static void
+hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
+                        int x,     int y,
+                        int width, int height)
 {
   struct timespec tspec;
 
@@ -646,8 +771,8 @@ hostx_paint_debug_rect(int x,     int y,
 
   /* fprintf(stderr, "Xephyr updating: %i+%i %ix%i\n", x, y, width, height); */
 
-  XFillRectangle(HostX.dpy, HostX.win, HostX.gc, x, y, width,height); 
-  XSync(HostX.dpy, False);
+  XFillRectangle (HostX.dpy, host_screen->win, HostX.gc, x, y, width,height);
+  XSync (HostX.dpy, False);
 
   /* nanosleep seems to work better than usleep for me... */
   nanosleep(&tspec, NULL);
@@ -660,14 +785,14 @@ hostx_load_keymap(void)
   int              host_width, min_keycode, max_keycode, width;
   int              i,j;
 
-  XDisplayKeycodes(HostX.dpy, &min_keycode, &max_keycode);
+  XDisplayKeycodes (HostX.dpy, &min_keycode, &max_keycode);
 
-  EPHYR_DBG("min: %d, max: %d", min_keycode, max_keycode);
+  EPHYR_DBG ("min: %d, max: %d", min_keycode, max_keycode);
 
-  keymap = XGetKeyboardMapping(HostX.dpy, 
-			       min_keycode,
-			       max_keycode - min_keycode + 1,
-			       &host_width);
+  keymap = XGetKeyboardMapping (HostX.dpy,
+			        min_keycode,
+			        max_keycode - min_keycode + 1,
+			        &host_width);
 
   /* Try and copy the hosts keymap into our keymap to avoid loads
    * of messing around.
@@ -688,7 +813,7 @@ hostx_load_keymap(void)
       ephyrKeySyms.map[(i*width)+j] = (CARD32) keymap[(i*host_width) + j];
 
   EPHYR_DBG("keymap width, host:%d kdrive:%d", host_width, width);
-  
+
   ephyrKeySyms.minKeyCode  = min_keycode;
   ephyrKeySyms.maxKeyCode  = max_keycode;
   ephyrKeySyms.mapWidth    = width;
@@ -696,11 +821,26 @@ hostx_load_keymap(void)
   XFree(keymap);
 }
 
+static struct EphyrHostScreen *
+host_screen_from_window (Window w)
+{
+  int index;
+
+  for (index = 0 ; index < HostX.n_screens ; index++)
+    {
+      if (HostX.screens[index].win == w)
+        {
+          return &HostX.screens[index];
+        }
+    }
+  return NULL;
+}
+
 int
 hostx_get_event(EphyrHostXEvent *ev)
 {
   XEvent      xev;
-  static Bool grabbed;
+  static int  grabbed_screen = -1;
 
   if (XPending(HostX.dpy))
     {
@@ -710,15 +850,27 @@ hostx_get_event(EphyrHostXEvent *ev)
 	{
 	case Expose:
 	  /* Not so great event compression, but works ok */
-	  while (XCheckTypedWindowEvent(HostX.dpy, xev.xexpose.window, 
+	  while (XCheckTypedWindowEvent(HostX.dpy, xev.xexpose.window,
 					Expose, &xev));
-	  hostx_paint_rect(0, 0, 0, 0, HostX.win_width, HostX.win_height);
+	  {
+	    struct EphyrHostScreen *host_screen =
+                host_screen_from_window (xev.xexpose.window);
+	    hostx_paint_rect (host_screen->info, 0, 0, 0, 0,
+                              host_screen->win_width,
+                              host_screen->win_height);
+	  }
 	  return 0;
 
 	case MotionNotify:
-	  ev->type = EPHYR_EV_MOUSE_MOTION;
-	  ev->data.mouse_motion.x = xev.xmotion.x; 
-	  ev->data.mouse_motion.y = xev.xmotion.y;
+	  {
+	    struct EphyrHostScreen *host_screen =
+                host_screen_from_window (xev.xmotion.window);
+
+	    ev->type = EPHYR_EV_MOUSE_MOTION;
+	    ev->data.mouse_motion.x = xev.xmotion.x; 
+	    ev->data.mouse_motion.y = xev.xmotion.y;
+	    ev->data.mouse_motion.screen = (host_screen ? host_screen->mynum : -1);
+	  }
 	  return 1;
 
 	case ButtonPress:
@@ -750,29 +902,35 @@ hostx_get_event(EphyrHostXEvent *ev)
 	       || XKeycodeToKeysym(HostX.dpy,xev.xkey.keycode,0) == XK_Shift_R)
 	      && (xev.xkey.state & ControlMask))
 	    {
-	      if (grabbed) 
+	      struct EphyrHostScreen *host_screen =
+                  host_screen_from_window (xev.xexpose.window);
+
+	      if (grabbed_screen != -1)
 		{
 		  XUngrabKeyboard (HostX.dpy, CurrentTime);
 		  XUngrabPointer (HostX.dpy, CurrentTime);
-		  grabbed = False;
-		  hostx_set_win_title("( ctrl+shift grabs mouse and keyboard )");
-		} 
-	      else 
+		  grabbed_screen = -1;
+		  hostx_set_win_title (host_screen->info,
+                                       "(ctrl+shift grabs mouse and keyboard)");
+		}
+	      else
 		{
 		  /* Attempt grab */
-		  if (XGrabKeyboard (HostX.dpy, HostX.win, True, 
+		  if (XGrabKeyboard (HostX.dpy, host_screen->win, True, 
 				     GrabModeAsync, 
 				     GrabModeAsync, 
 				     CurrentTime) == 0)
 		    {
-		      if (XGrabPointer (HostX.dpy, HostX.win, True, 
+		      if (XGrabPointer (HostX.dpy, host_screen->win, True, 
 					NoEventMask, 
 					GrabModeAsync, 
 					GrabModeAsync, 
-					HostX.win, None, CurrentTime) == 0)
+					host_screen->win, None, CurrentTime) == 0)
 			{
-			  grabbed = True;
-			  hostx_set_win_title("( ctrl+shift releases mouse and keyboard )");
+			  grabbed_screen = host_screen->mynum;
+			  hostx_set_win_title
+                                  (host_screen->info,
+                                   "(ctrl+shift releases mouse and keyboard)");
 			}
 		      else 	/* Failed pointer grabm  ungrab keyboard */
 			XUngrabKeyboard (HostX.dpy, CurrentTime);
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 4d5f37f..93765d0 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -40,8 +40,8 @@
 
 typedef struct EphyrHostXVars  EphyrHostXVars;
 typedef struct EphyrHostXEvent EphyrHostXEvent;
-
-typedef enum EphyrHostXEventType 
+typedef void* EphyrScreenInfo ;
+typedef enum EphyrHostXEventType
 {
   EPHYR_EV_MOUSE_MOTION,
   EPHYR_EV_MOUSE_PRESS,
@@ -68,6 +68,7 @@ struct EphyrHostXEvent
     struct mouse_motion { 	
       int x;
       int y;
+      int screen;
     } mouse_motion;
 
     struct mouse_down { 	
@@ -92,7 +93,7 @@ struct EphyrHostXEvent
 };
 
 int
-hostx_want_screen_size(int *width, int *height);
+hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
 
 int
 hostx_want_host_cursor(void);
@@ -107,7 +108,7 @@ int
 hostx_want_fullscreen(void);
 
 int
-hostx_want_preexisting_window(void);
+hostx_want_preexisting_window(EphyrScreenInfo screen);
 
 void
 hostx_use_preexisting_window(unsigned long win_id);
@@ -119,25 +120,32 @@ int
 hostx_init(void);
 
 void
+hostx_add_screen(EphyrScreenInfo screen, unsigned long win_id, int screen_num);
+
+void
 hostx_set_display_name(char *name);
 
 void
-hostx_set_win_title(char *extra_text);
+hostx_set_screen_number(EphyrScreenInfo screen, int number);
+
+void
+hostx_set_win_title(EphyrScreenInfo screen, char *extra_text);
 
 int
 hostx_get_depth (void);
 
 int
-hostx_get_server_depth (void);
+hostx_get_server_depth (EphyrScreenInfo screen);
 
 void
-hostx_set_server_depth(int depth);
+hostx_set_server_depth(EphyrScreenInfo screen, int depth);
 
 int
-hostx_get_bpp(void);
+hostx_get_bpp(void *info);
 
 void
-hostx_get_visual_masks (CARD32 *rmsk, 
+hostx_get_visual_masks (void   *info,
+			CARD32 *rmsk, 
 			CARD32 *gmsk, 
 			CARD32 *bmsk);
 void
@@ -147,15 +155,16 @@ hostx_set_cmap_entry(unsigned char idx,
 		     unsigned char b);
 
 void*
-hostx_screen_init (int width, int height, int buffer_height);
+hostx_screen_init (EphyrScreenInfo screen,
+                   int width, int height,
+                   int buffer_height);
 
 void
-hostx_paint_rect(int sx,    int sy,
-		 int dx,    int dy, 
+hostx_paint_rect(EphyrScreenInfo screen,
+		 int sx,    int sy,
+		 int dx,    int dy,
 		 int width, int height);
-void
-hostx_paint_debug_rect(int x,     int y, 
-		       int width, int height);
+
 
 void
 hostx_load_keymap(void);
diff --git a/hw/kdrive/ephyr/os.c b/hw/kdrive/ephyr/os.c
index 1a42495..b58daae 100644
--- a/hw/kdrive/ephyr/os.c
+++ b/hw/kdrive/ephyr/os.c
@@ -31,6 +31,14 @@
 static int
 EphyrInit (void)
 {
+  /*
+   * make sure at least one screen
+   * has been added to the system.
+   */
+  if (!KdCardInfoLast ())
+    {
+        processScreenArg ("640x480", NULL) ;
+    }
   return hostx_init();
 }
 
commit 81692b628f41cb64329f3cccc0503fb216a2b8e3
Author: Dodji Seketeli <dodji at openedhand.com>
Date:   Tue Oct 2 13:11:28 2007 +0200

    Fix #12650: "windows not receiving mouse events in multiple screens context"
    
    	* dix/events.c, include/dix.h:
    	  (UpdateSpriteForScreen): added this to update the mouse sprite context
    	   when we switch from a pScreen to another.
    	* mi/mipointer.c:
    	  (miPointerWarpCursor): as we are switching to a new pScreen,
    	   don't forget to update the mouse sprite context.

diff --git a/dix/events.c b/dix/events.c
index 7b4cab0..61dd534 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2352,6 +2352,61 @@ DefineInitialRootWindow(WindowPtr win)
 #endif
 }
 
+/**
+ * Update the mouse sprite info when the server switches from a pScreen to another.
+ * Otherwise, the pScreen of the mouse sprite is never updated when we switch
+ * from a pScreen to another. Never updating the pScreen of the mouse sprite
+ * implies that windows that are in pScreen whose pScreen->myNum >0 will never
+ * get pointer events. This is  because in CheckMotion(), sprite.hotPhys.pScreen
+ * always points to the first pScreen it has been set by
+ * DefineInitialRootWindow().
+ *
+ * Calling this function is useful for use cases where the server
+ * has more than one pScreen.
+ * This function is similar to DefineInitialRootWindow() but it does not
+ * reset the mouse pointer position.
+ * @param win must be the new pScreen we are switching to.
+ */
+void
+UpdateSpriteForScreen(ScreenPtr pScreen)
+{
+    WindowPtr win = NULL;
+    if (!pScreen)
+        return ;
+    win = WindowTable[pScreen->myNum];
+
+    sprite.hotPhys.pScreen = pScreen;
+    sprite.hot = sprite.hotPhys;
+    sprite.hotLimits.x2 = pScreen->width;
+    sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = win;
+    sprite.current = wCursor (win);
+    sprite.current->refcnt++;
+    spriteTraceGood = 1;
+    ROOT = win;
+    (*pScreen->CursorLimits) (pScreen,
+                              sprite.current,
+                              &sprite.hotLimits,
+                              &sprite.physLimits);
+    sprite.confined = FALSE;
+    (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+    (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+        sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+        sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+        sprite.hotLimits.x2 = PanoramiXPixWidth  - panoramiXdataPtr[0].x;
+        sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+        sprite.physLimits = sprite.hotLimits;
+        sprite.screen = pScreen;
+    }
+#endif
+}
+
 /*
  * This does not take any shortcuts, and even ignores its argument, since
  * it does not happen very often, and one has to walk up the tree since
diff --git a/include/dix.h b/include/dix.h
index c1d609a..6a67d14 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -415,6 +415,9 @@ extern int DeliverDeviceEvents(
 extern void DefineInitialRootWindow(
     WindowPtr /* win */);
 
+extern void UpdateSpriteForScreen(
+     ScreenPtr /* pScreen */);
+
 extern void WindowHasNewCursor(
     WindowPtr /* pWin */);
 
diff --git a/mi/mipointer.c b/mi/mipointer.c
index b86a26a..24ff4cc 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -262,6 +262,7 @@ miPointerWarpCursor (pScreen, x, y)
 	miPointer.y = y;
 	miPointer.pScreen = pScreen;
     }
+    UpdateSpriteForScreen (pScreen) ;
 }
 
 /*
commit dc90d500085dd74e90073be008fc514bd97b160a
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Oct 2 14:05:07 2007 +1000

    exa: increase minor version number for pixmap allocation hooks

diff --git a/exa/exa.h b/exa/exa.h
index 0eeb1f0..f852df4 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -39,7 +39,7 @@
 #include "fb.h"
 
 #define EXA_VERSION_MAJOR   2
-#define EXA_VERSION_MINOR   3
+#define EXA_VERSION_MINOR   4
 #define EXA_VERSION_RELEASE 0
 
 typedef struct _ExaOffscreenArea ExaOffscreenArea;
commit f15af2ae60bb8503c336bc3cba0560bd314a34bc
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Fri Aug 3 16:33:33 2007 +1000

    exa: only setup offscreen allocator if driver doesn't provide CreatePixmap

diff --git a/exa/exa.c b/exa/exa.c
index dfad0e7..3e8054d 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -755,22 +755,24 @@ exaDriverInit (ScreenPtr		pScreen,
 	return FALSE;
     }
 
-    if (!pScreenInfo->memoryBase) {
-	LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase must be "
-		   "non-zero\n", pScreen->myNum);
-	return FALSE;
-    }
+    if (!pScreenInfo->CreatePixmap) {
+	if (!pScreenInfo->memoryBase) {
+	    LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase "
+		       "must be non-zero\n", pScreen->myNum);
+	    return FALSE;
+	}
 
-    if (!pScreenInfo->memorySize) {
-	LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memorySize must be "
-		   "non-zero\n", pScreen->myNum);
-	return FALSE;
-    }
+	if (!pScreenInfo->memorySize) {
+	    LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memorySize must be "
+		       "non-zero\n", pScreen->myNum);
+	    return FALSE;
+	}
 
-    if (pScreenInfo->offScreenBase > pScreenInfo->memorySize) {
-	LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must be <= "
-		   "ExaDriverRec::memorySize\n", pScreen->myNum);
-	return FALSE;
+	if (pScreenInfo->offScreenBase > pScreenInfo->memorySize) {
+	    LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must "
+		       "be <= ExaDriverRec::memorySize\n", pScreen->myNum);
+	    return FALSE;
+	}
     }
 
     if (!pScreenInfo->PrepareSolid) {
@@ -881,8 +883,7 @@ exaDriverInit (ScreenPtr		pScreen,
     /*
      * Hookup offscreen pixmaps
      */
-    if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
-	pExaScr->info->offScreenBase < pExaScr->info->memorySize)
+    if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)
     {
 	if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex,
 				   sizeof (ExaPixmapPrivRec))) {
@@ -899,10 +900,15 @@ exaDriverInit (ScreenPtr		pScreen,
 
 	pExaScr->SavedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
 	pScreen->ModifyPixmapHeader = exaModifyPixmapHeader;
+	if (!pExaScr->info->CreatePixmap) {
+	    LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
+		       pScreen->myNum,
+		       pExaScr->info->memorySize - pExaScr->info->offScreenBase);
+	} else {
+	    LogMessage(X_INFO, "EXA(%d): Driver allocated offscreen pixmaps\n",
+		       pScreen->myNum);
 
-	LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %d bytes\n",
-		   pScreen->myNum,
-		   pExaScr->info->memorySize - pExaScr->info->offScreenBase);
+	}
     }
     else
     {
@@ -911,14 +917,16 @@ exaDriverInit (ScreenPtr		pScreen,
 	    return FALSE;
     }
 
-    DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
-                pExaScr->info->memorySize));
-    if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
-	if (!exaOffscreenInit (pScreen)) {
-            LogMessage(X_WARNING, "EXA(%d): Offscreen pixmap setup failed\n",
-                       pScreen->myNum);
-            return FALSE;
-        }
+    if (!pExaScr->info->CreatePixmap) {
+	DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
+		    pExaScr->info->memorySize));
+	if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
+	    if (!exaOffscreenInit (pScreen)) {
+		LogMessage(X_WARNING, "EXA(%d): Offscreen pixmap setup failed\n",
+			   pScreen->myNum);
+		return FALSE;
+	    }
+	}
     }
 
     LogMessage(X_INFO, "EXA(%d): Driver registered support for the following"
commit ffb58f4fa8d86e87f831430b8627f27d85f971a9
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Oct 2 14:03:39 2007 +1000

    exa: add hooks for drivers to take over pixmap allocation
    
    This adds hooks for the driver to access Create/DestroyPixmap and ModifyPixmapHe
    ader.
    
    It allocates a 0 sized pixmap using fb and calls the driver routine to do
    work of allocating the actual memory.
    
    ModifyPixmapHeader is mainly required for hooking the screen pixmap which
    isn't create by normal methods

diff --git a/exa/exa.c b/exa/exa.c
index bd0f4f7..dfad0e7 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -183,9 +183,18 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
 static Bool
 exaDestroyPixmap (PixmapPtr pPixmap)
 {
+    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
+    ExaScreenPriv(pScreen);
+
     if (pPixmap->refcnt == 1)
     {
 	ExaPixmapPriv (pPixmap);
+
+	if (pExaPixmap->driverPriv) {
+	    pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
+	    pExaPixmap->driverPriv = NULL;
+	}
+
 	if (pExaPixmap->area)
 	{
 	    DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
@@ -229,46 +238,86 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
 {
     PixmapPtr		pPixmap;
     ExaPixmapPrivPtr	pExaPixmap;
+    int                 driver_alloc = 0;
     int			bpp;
     ExaScreenPriv(pScreen);
 
     if (w > 32767 || h > 32767)
 	return NullPixmap;
 
-    pPixmap = fbCreatePixmap (pScreen, w, h, depth);
+    if (!pExaScr->info->CreatePixmap) {
+        pPixmap = fbCreatePixmap (pScreen, w, h, depth);
+    } else {
+        driver_alloc = 1;
+        pPixmap = fbCreatePixmap(pScreen, 0, 0, depth);
+    }
+
     if (!pPixmap)
-	return NULL;
+        return NULL;
+
     pExaPixmap = ExaGetPixmapPriv(pPixmap);
 
     bpp = pPixmap->drawable.bitsPerPixel;
 
-    /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
-    if (!w || !h)
-	pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
-    else
-	pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
-
-    pExaPixmap->area = NULL;
-
-    pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
-    pExaPixmap->sys_pitch = pPixmap->devKind;
-
-    pPixmap->devPrivate.ptr = NULL;
-    pExaPixmap->offscreen = FALSE;
-
-    pExaPixmap->fb_ptr = NULL;
-    if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
-	pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
-    else
-	pExaPixmap->fb_pitch = w * bpp / 8;
-    pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
-				     pExaScr->info->pixmapPitchAlign);
-    pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;
+    if (driver_alloc) {
+        size_t paddedWidth, datasize;
+        void *driver_priv;
+
+	paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
+        if (paddedWidth / 4 > 32767 || h > 32767)
+            return NullPixmap;
+
+        if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
+            pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
+        else
+            pExaPixmap->fb_pitch = w * bpp / 8;
+        pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
+                                         pExaScr->info->pixmapPitchAlign);
+        if (paddedWidth < pExaPixmap->fb_pitch)
+            paddedWidth = pExaPixmap->fb_pitch;
+
+        datasize = h * paddedWidth;
+
+        driver_priv = pExaScr->info->CreatePixmap(pScreen, datasize, 0);
+        if (!driver_priv) {
+             fbDestroyPixmap(pPixmap);
+             return NULL;
+        }
 
-    if (pExaPixmap->fb_pitch > 131071) {
-	fbDestroyPixmap(pPixmap);
-	return NULL;
+        (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
+                                       paddedWidth, NULL);
+         pExaPixmap->driverPriv = driver_priv;
+         pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+    } else {
+         pExaPixmap->driverPriv = NULL;
+         /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
+        if (!w || !h)
+	    pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+        else
+            pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
+
+        pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
+        pExaPixmap->sys_pitch = pPixmap->devKind;
+
+        pPixmap->devPrivate.ptr = NULL;
+        pExaPixmap->offscreen = FALSE;
+
+        pExaPixmap->fb_ptr = NULL;
+        if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
+            pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
+        else
+            pExaPixmap->fb_pitch = w * bpp / 8;
+        pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
+				         pExaScr->info->pixmapPitchAlign);
+        pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;
+
+        if (pExaPixmap->fb_pitch > 131071) {
+	     fbDestroyPixmap(pPixmap);
+	     return NULL;
+        }
     }
+ 
+    pExaPixmap->area = NULL;
 
     /* Set up damage tracking */
     pExaPixmap->pDamage = DamageCreate (NULL, NULL, DamageReportNone, TRUE,
@@ -315,6 +364,7 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
 {
     ExaScreenPrivPtr pExaScr;
     ExaPixmapPrivPtr pExaPixmap;
+    Bool ret;
 
     if (!pPixmap)
         return FALSE;
@@ -326,6 +376,12 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
 
     pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen);
 
+    if (pExaScr->info->ModifyPixmapHeader) {
+	ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
+						bitsPerPixel, devKind, pPixData);
+	if (ret == TRUE)
+	    return ret;
+    }
     return pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth,
 					    bitsPerPixel, devKind, pPixData);
 }
@@ -843,6 +899,7 @@ exaDriverInit (ScreenPtr		pScreen,
 
 	pExaScr->SavedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
 	pScreen->ModifyPixmapHeader = exaModifyPixmapHeader;
+
 	LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %d bytes\n",
 		   pScreen->myNum,
 		   pExaScr->info->memorySize - pExaScr->info->offScreenBase);
diff --git a/exa/exa.h b/exa/exa.h
index c7e39fa..0eeb1f0 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -702,6 +702,13 @@ typedef struct _ExaDriver {
      */
     int maxPitchBytes;
 
+    /* Hooks to allow driver to its own pixmap memory management */
+    void *(*CreatePixmap)(ScreenPtr pScreen, int size, int align);
+    void (*DestroyPixmap)(ScreenPtr pScreen, void *driverPriv);
+    Bool (*ModifyPixmapHeader)(PixmapPtr pPixmap, int width, int height,
+                              int depth, int bitsPerPixel, int devKind,
+                              pointer pPixData);
+
     /** @} */
 } ExaDriverRec, *ExaDriverPtr;
 
commit 31555af0005a0bc4d7ef785214696ac84681e29f
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Oct 2 13:32:57 2007 +1000

    exa: add a pixmap private pointer for drivers to retrieve.

diff --git a/exa/exa.c b/exa/exa.c
index 518a5f1..bd0f4f7 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -74,6 +74,14 @@ exaGetPixmapOffset(PixmapPtr pPix)
 	    (unsigned long)pExaScr->info->memoryBase);
 }
 
+void *
+exaGetPixmapDriverPrivate(PixmapPtr pPix)
+{
+    ExaPixmapPriv(pPix);
+
+    return pExaPixmap->driverPriv;
+}
+
 /**
  * exaGetPixmapPitch() returns the pitch (in bytes) of the given pixmap.
  *
diff --git a/exa/exa.h b/exa/exa.h
index 491e6b1..c7e39fa 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -773,6 +773,9 @@ exaMoveInPixmap (PixmapPtr pPixmap);
 void
 exaMoveOutPixmap (PixmapPtr pPixmap);
 
+void *
+exaGetPixmapDriverPrivate(PixmapPtr p);
+
 /**
  * Returns TRUE if the given planemask covers all the significant bits in the
  * pixel values for pDrawable.
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index a26933d..523a76f 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -192,6 +192,10 @@ typedef struct {
      * damage, which may be overreported) of a pixmap's system and FB copies.
      */
     RegionRec	    validSys, validFB;
+    /**
+     * Driver private storage per EXA pixmap
+     */
+    void *driverPriv;
 } ExaPixmapPrivRec, *ExaPixmapPrivPtr;
  
 typedef struct _ExaMigrationRec {
commit 2d93e69690d2c5d4a89a795ede6423796528e5df
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Thu Sep 27 16:47:06 2007 -0700

    Rework local client id finding code to be more uniform

diff --git a/configure.ac b/configure.ac
index de30430..5c5ff7d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,7 +179,7 @@ dnl Checks for library functions.
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \
 		strtol getopt getopt_long vsnprintf walkcontext backtrace \
-		getisax])
+		getisax getzoneid])
 AC_FUNC_ALLOCA
 dnl Old HAS_* names used in os/*.c.
 AC_CHECK_FUNC([getdtablesize],
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 69fab5e..563d343 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -136,6 +136,9 @@
 /* Define to 1 if you have the `getuid' function. */
 #undef HAVE_GETUID
 
+/* Define to 1 if you have the `getzoneid' function. */
+#undef HAVE_GETZONEID
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
diff --git a/include/os.h b/include/os.h
index 3d68947..d915267 100644
--- a/include/os.h
+++ b/include/os.h
@@ -323,6 +323,24 @@ extern int LocalClient(ClientPtr /* client */);
 
 extern int LocalClientCred(ClientPtr, int *, int *);
 
+#define LCC_UID_SET	(1 << 0)
+#define LCC_GID_SET	(1 << 1)
+#define LCC_PID_SET	(1 << 2)
+#define LCC_ZID_SET	(1 << 3)
+
+typedef struct {
+    int fieldsSet;	/* Bit mask of fields set */
+    int	euid;		/* Effective uid */
+    int egid;		/* Primary effective group id */
+    int nSuppGids;	/* Number of supplementary group ids */
+    int *pSuppGids;	/* Array of supplementary group ids */
+    int pid;		/* Process id */
+    int zoneid;		/* Only set on Solaris 10 & later */
+} LocalClientCredRec;
+
+extern int GetLocalClientCreds(ClientPtr, LocalClientCredRec **);
+extern void FreeLocalClientCreds(LocalClientCredRec *); 
+
 extern int ChangeAccessControl(ClientPtr /*client*/, int /*fEnabled*/);
 
 extern int GetAccessControl(void);
diff --git a/os/access.c b/os/access.c
index e194bb8..5b638c7 100644
--- a/os/access.c
+++ b/os/access.c
@@ -234,10 +234,6 @@ static Bool NewHost(int /*family*/,
 		    int /*len*/,
 		    int /* addingLocalHosts */);
 
-static int LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, 
-				    int **pSuppGids, int *nSuppGids);
-
-
 /* XFree86 bug #156: To keep track of which hosts were explicitly requested in
    /etc/X<display>.hosts, we've added a requested field to the HOST struct,
    and a LocalHostRequested variable.  These default to FALSE, but are set
@@ -1383,38 +1379,51 @@ _X_EXPORT Bool LocalClient(ClientPtr client)
 
 /*
  * Return the uid and gid of a connected local client
- * or the uid/gid for nobody those ids cannot be determined
  * 
  * Used by XShm to test access rights to shared memory segments
  */
 int
 LocalClientCred(ClientPtr client, int *pUid, int *pGid)
 {
-    return LocalClientCredAndGroups(client, pUid, pGid, NULL, NULL);
+    LocalClientCredRec *lcc;
+    int ret = GetLocalClientCreds(client, &lcc);
+
+    if (ret == 0) {
+#ifdef HAVE_GETZONEID /* only local if in the same zone */
+	if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
+	    FreeLocalClientCreds(lcc);
+	    return -1;
+	}	    
+#endif
+	if ((lcc->fieldsSet & LCC_UID_SET) && (pUid != NULL))
+	    *pUid = lcc->euid;
+	if ((lcc->fieldsSet & LCC_GID_SET) && (pGid != NULL))
+	    *pGid = lcc->egid;
+	FreeLocalClientCreds(lcc);
+    }
+    return ret;
 }
 
 /*
  * Return the uid and all gids of a connected local client
- * or the uid/gid for nobody those ids cannot be determined
+ * Allocates a LocalClientCredRec - caller must call FreeLocalClientCreds
  * 
- * If the caller passes non-NULL values for pSuppGids & nSuppGids,
- * they are responsible for calling XFree(*pSuppGids) to release the
- * memory allocated for the supplemental group ids list.
- *
  * Used by localuser & localgroup ServerInterpreted access control forms below
+ * Used by AuthAudit to log who local connections came from
  */
-static int
-LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, 
-			 int **pSuppGids, int *nSuppGids)
+int
+GetLocalClientCreds(ClientPtr client, LocalClientCredRec **lccp)
 {
 #if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
     int fd;
     XtransConnInfo ci;
+    LocalClientCredRec *lcc;
 #ifdef HAS_GETPEEREID
     uid_t uid;
     gid_t gid;
 #elif defined(HAS_GETPEERUCRED)
     ucred_t *peercred = NULL;
+    const gid_t *gids;
 #elif defined(SO_PEERCRED)
     struct ucred peercred;
     socklen_t so_len = sizeof(peercred);
@@ -1433,57 +1442,65 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
     }
 #endif
 
-    if (pSuppGids != NULL)
-	*pSuppGids = NULL;
-    if (nSuppGids != NULL)
-	*nSuppGids = 0;
-
+    *lccp = Xcalloc(sizeof(LocalClientCredRec));
+    if (*lccp == NULL)
+	return -1;
+    lcc = *lccp;
+        
     fd = _XSERVTransGetConnectionNumber(ci);
 #ifdef HAS_GETPEEREID
-    if (getpeereid(fd, &uid, &gid) == -1) 
-	    return -1;
-    if (pUid != NULL)
-	    *pUid = uid;
-    if (pGid != NULL)
-	    *pGid = gid;
+    if (getpeereid(fd, &uid, &gid) == -1) {
+	FreeLocalClientCreds(lcc);
+	return -1;
+    }
+    lcc->euid = uid;
+    lcc->egid = gid;
+    lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
     return 0;
 #elif defined(HAS_GETPEERUCRED)
-    if (getpeerucred(fd, &peercred) < 0)
+    if (getpeerucred(fd, &peercred) < 0) {
+	FreeLocalClientCreds(lcc);
     	return -1;
-#ifdef sun /* Ensure process is in the same zone */
-    if (getzoneid() != ucred_getzoneid(peercred)) {
-	ucred_free(peercred);
-	return -1;
     }
-#endif
-    if (pUid != NULL)
-	*pUid = ucred_geteuid(peercred);
-    if (pGid != NULL)
-	*pGid = ucred_getegid(peercred);
-    if (pSuppGids != NULL && nSuppGids != NULL) {
-	const gid_t *gids;
-	*nSuppGids = ucred_getgroups(peercred, &gids);
-	if (*nSuppGids > 0) {
-	    *pSuppGids = xalloc(sizeof(int) * (*nSuppGids));
-	    if (*pSuppGids == NULL) {
-		*nSuppGids = 0;
-	    } else {
-		int i;
-		for (i = 0 ; i < *nSuppGids; i++) {
-		    (*pSuppGids)[i] = (int) gids[i];
-		}
+    lcc->euid = ucred_geteuid(peercred);
+    if (lcc->euid != -1)
+	lcc->fieldsSet |= LCC_UID_SET;
+    lcc->egid = ucred_getegid(peercred);
+    if (lcc->egid != -1)
+	lcc->fieldsSet |= LCC_GID_SET;
+    lcc->pid = ucred_getpid(peercred);
+    if (lcc->pid != -1)
+	lcc->fieldsSet |= LCC_PID_SET;
+#ifdef HAVE_GETZONEID
+    lcc->zoneid = ucred_getzoneid(peercred);
+    if (lcc->zoneid != -1)
+	lcc->fieldsSet |= LCC_ZID_SET;
+#endif
+    lcc->nSuppGids = ucred_getgroups(peercred, &gids);
+    if (lcc->nSuppGids > 0) {
+	lcc->pSuppGids = Xcalloc((lcc->nSuppGids) * sizeof(int));
+	if (lcc->pSuppGids == NULL) {
+	    lcc->nSuppGids = 0;
+	} else {
+	    int i;
+	    for (i = 0 ; i < lcc->nSuppGids; i++) {
+		(lcc->pSuppGids)[i] = (int) gids[i];
 	    }
 	}
+    } else {
+	lcc->nSuppGids = 0;
     }
     ucred_free(peercred);
     return 0;
 #elif defined(SO_PEERCRED)
-    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) 
-	    return -1;
-    if (pUid != NULL)
-	    *pUid = peercred.uid;
-    if (pGid != NULL)
-	    *pGid = peercred.gid;
+    if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) {
+	FreeLocalClientCreds(lcc);
+	return -1;
+    }
+    lcc->euid = peercred.uid;
+    lcc->egid = peercred.gid;
+    lcc->pid = peercred.pid;
+    lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
     return 0;
 #endif
 #else
@@ -1493,6 +1510,17 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
 #endif
 }
 
+void
+FreeLocalClientCreds(LocalClientCredRec *lcc)
+{
+    if (lcc != NULL) {
+	if (lcc->nSuppGids > 0) {
+	    Xfree(lcc->pSuppGids);
+	}
+	Xfree(lcc);
+    }
+}
+
 static Bool
 AuthorizedClient(ClientPtr client)
 {
@@ -2321,38 +2349,48 @@ static Bool
 siLocalCredAddrMatch(int family, pointer addr, int len,
   const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
 {
-    int connUid, connGid, *connSuppGids, connNumSuppGids, siAddrId;
+    int siAddrId;
+    LocalClientCredRec *lcc;
     siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
 
-    if (LocalClientCredAndGroups(client, &connUid, &connGid,
-      &connSuppGids, &connNumSuppGids) == -1) {
+    if (GetLocalClientCreds(client, &lcc) == -1) {
 	return FALSE;
     }
 
+#ifdef HAVE_GETZONEID /* Ensure process is in the same zone */
+    if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
+	FreeLocalClientCreds(lcc);
+	return FALSE;
+    }
+#endif
+
     if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
+	FreeLocalClientCreds(lcc);
 	return FALSE;
     }
 
     if (lcPriv->credType == LOCAL_USER) {
-	if (connUid == siAddrId) {
+	if ((lcc->fieldsSet & LCC_UID_SET) && (lcc->euid == siAddrId)) {
+	    FreeLocalClientCreds(lcc);
 	    return TRUE;
 	}
     } else {
-	if (connGid == siAddrId) {
+	if ((lcc->fieldsSet & LCC_GID_SET) && (lcc->egid == siAddrId)) {
+	    FreeLocalClientCreds(lcc);
 	    return TRUE;
 	}
-	if (connSuppGids != NULL) {
+	if (lcc->pSuppGids != NULL) {
 	    int i;
 
-	    for (i = 0 ; i < connNumSuppGids; i++) {
-		if (connSuppGids[i] == siAddrId) {
-		    xfree(connSuppGids);
+	    for (i = 0 ; i < lcc->nSuppGids; i++) {
+		if (lcc->pSuppGids[i] == siAddrId) {
+		    FreeLocalClientCreds(lcc);
 		    return TRUE;
 		}
 	    }
-	    xfree(connSuppGids);
 	}
     }
+    FreeLocalClientCreds(lcc);
     return FALSE;
 }
 
diff --git a/os/connection.c b/os/connection.c
index d1bc4d0..70551a8 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -539,10 +539,8 @@ AuthAudit (ClientPtr client, Bool letin,
     char *out = addr;
     int client_uid;
     char client_uid_string[64];
-#ifdef HAS_GETPEERUCRED
-    ucred_t *peercred = NULL;
-#endif
-#if defined(HAS_GETPEERUCRED) || defined(XSERVER_DTRACE)    
+    LocalClientCredRec *lcc;
+#ifdef XSERVER_DTRACE
     pid_t client_pid = -1;
     zoneid_t client_zid = -1;
 #endif
@@ -583,23 +581,50 @@ AuthAudit (ClientPtr client, Bool letin,
 	    strcpy(out, "unknown address");
 	}
 
-#ifdef HAS_GETPEERUCRED
-    if (getpeerucred(((OsCommPtr)client->osPrivate)->fd, &peercred) >= 0) {
-	client_uid = ucred_geteuid(peercred);
-	client_pid = ucred_getpid(peercred);
-	client_zid = ucred_getzoneid(peercred);
-
-	ucred_free(peercred);
-	snprintf(client_uid_string, sizeof(client_uid_string),
-		 " (uid %ld, pid %ld, zone %ld)",
-		 (long) client_uid, (long) client_pid, (long) client_zid);
-    }
-#else    
-    if (LocalClientCred(client, &client_uid, NULL) != -1) {
-	snprintf(client_uid_string, sizeof(client_uid_string),
-		 " (uid %d)", client_uid);
-    }
+    if (GetLocalClientCreds(client, &lcc) != -1) {
+	int slen; /* length written to client_uid_string */
+
+	strcpy(client_uid_string, " ( ");
+	slen = 3;
+
+	if (lcc->fieldsSet & LCC_UID_SET) {
+	    snprintf(client_uid_string + slen,
+		     sizeof(client_uid_string) - slen,
+		     "uid=%ld ", (long) lcc->euid);
+	    slen = strlen(client_uid_string);
+	}
+
+	if (lcc->fieldsSet & LCC_GID_SET) {
+	    snprintf(client_uid_string + slen,
+		     sizeof(client_uid_string) - slen,
+		     "gid=%ld ", (long) lcc->egid);
+	    slen = strlen(client_uid_string);
+	}
+
+	if (lcc->fieldsSet & LCC_PID_SET) {
+#ifdef XSERVER_DTRACE	    
+	    client_pid = lcc->pid;
 #endif
+	    snprintf(client_uid_string + slen,
+		     sizeof(client_uid_string) - slen,
+		     "pid=%ld ", (long) lcc->pid);
+	    slen = strlen(client_uid_string);
+	}
+	
+	if (lcc->fieldsSet & LCC_ZID_SET) {
+#ifdef XSERVER_DTRACE
+	    client_zid = lcc->zoneid;
+#endif	    
+	    snprintf(client_uid_string + slen,
+		     sizeof(client_uid_string) - slen,
+		     "zoneid=%ld ", (long) lcc->zoneid);
+	    slen = strlen(client_uid_string);
+	}
+
+	snprintf(client_uid_string + slen, sizeof(client_uid_string) - slen,
+		 ")");
+	FreeLocalClientCreds(lcc);
+    }
     else {
 	client_uid_string[0] = '\0';
     }
commit c7ead3a68e5839cb92129e35b21f55007fba8445
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Thu Sep 27 16:13:28 2007 -0700

    xorgcfg needs $(DIX_CFLAGS) for pixman-1 include path

diff --git a/hw/xfree86/utils/xorgcfg/Makefile.am b/hw/xfree86/utils/xorgcfg/Makefile.am
index 309ed5c..e711303 100644
--- a/hw/xfree86/utils/xorgcfg/Makefile.am
+++ b/hw/xfree86/utils/xorgcfg/Makefile.am
@@ -33,7 +33,7 @@ INCLUDES = $(XORG_INCS) -I$(top_srcdir)/hw/xfree86/parser
 
 OPTIONSPATH=$(libdir)/X11
 
-xorgcfg_CFLAGS = $(XORG_CFLAGS) $(CURSESDEFINES) \
+xorgcfg_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(CURSESDEFINES) \
 	$(XORGCFG_DEP_CFLAGS) -DXKB_RULES_DIR=\"$(XKB_BASE_DIRECTORY)/rules\" \
 	-DPROJECT_ROOT=\"$(PROJECTROOT)\" -DOPTIONSPATH=\"$(OPTIONSPATH)\"
 xorgcfg_LDADD = $(XORGCFG_DEP_LIBS) ../../parser/libxf86config.a $(LOADERLIB) \
commit 62a9fb4cda988a896909a5620a68c51e46d0e403
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Thu Sep 27 16:12:29 2007 -0700

    Fix PCI rework build on Solaris (copy what BSD does)

diff --git a/hw/xfree86/os-support/bus/ix86Pci.c b/hw/xfree86/os-support/bus/ix86Pci.c
index bbc4847..e542463 100644
--- a/hw/xfree86/os-support/bus/ix86Pci.c
+++ b/hw/xfree86/os-support/bus/ix86Pci.c
@@ -223,6 +223,20 @@ static pciBusInfo_t ix86Pci0 = {
 /* bridge      */	NULL
 };
 
+_X_EXPORT pointer
+xf86MapDomainMemory(int ScreenNum, int Flags, struct pci_device *dev,
+                    ADDRESS Base, unsigned long Size)
+{
+    return xf86MapVidMem(ScreenNum, Flags, Base, Size);
+}
+
+IOADDRESS
+xf86MapLegacyIO(struct pci_device *dev)
+{
+    (void)dev;
+    return 0;
+}
+
 static Bool
 ix86PciBusCheck(void)
 {
diff --git a/hw/xfree86/os-support/shared/stdResource.c b/hw/xfree86/os-support/shared/stdResource.c
index 7229d55..c144211 100644
--- a/hw/xfree86/os-support/shared/stdResource.c
+++ b/hw/xfree86/os-support/shared/stdResource.c
@@ -44,7 +44,7 @@
 #include "bus/Pci.h"
 
 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
-	defined(__DragonFly__)
+	defined(__DragonFly__) || defined(__sun)
 #define xf86StdAccResFromOS xf86AccResFromOS
 #endif
 
commit cfe549d1ba28396c44af94133d8c1d323e3c7086
Author: Tilman Sauerbeck <tilman at code-monkey.de>
Date:   Thu Sep 27 22:36:52 2007 +0200

    EXA: Added back the maxPitchPixels initialization code.
    
    This doesn't add real value yet, but it will be useful once I add code
    that splits large render operations into smaller parts if necessary.

diff --git a/exa/exa.c b/exa/exa.c
index 8d70558..518a5f1 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -726,6 +726,21 @@ exaDriverInit (ScreenPtr		pScreen,
 		   "non-NULL\n", pScreen->myNum);
 	return FALSE;
     }
+
+    /* If the driver doesn't set any max pitch values, we'll just assume
+     * that there's a limitation by pixels, and that it's the same as
+     * maxX.
+     *
+     * We want maxPitchPixels or maxPitchBytes to be set so we can check
+     * pixmaps against the max pitch in exaCreatePixmap() -- it matters
+     * whether a pixmap is rejected because of its pitch or
+     * because of its width.
+     */
+    if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes)
+    {
+        pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
+    }
+
 #ifdef RENDER
     ps = GetPictureScreenIfSet(pScreen);
 #endif
commit c11a27ef85674f1e77ffa7f083646b848e1dc0b8
Author: Alan Hourihane <alanh at tungstengraphics.com>
Date:   Thu Sep 27 14:54:40 2007 +0100

    Add the FB_ACCESS_WRAPPER checks

diff --git a/fb/fbarc.c b/fb/fbarc.c
index faf2628..f89b81c 100644
--- a/fb/fbarc.c
+++ b/fb/fbarc.c
@@ -75,7 +75,9 @@ fbPolyArc (DrawablePtr	pDrawable,
 	    
 	    cclip = fbGetCompositeClip (pGC);
 	    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+#ifdef FB_ACCESS_WRAPPER
 	    wrapped = 1;
+#endif
 	    while (narcs--)
 	    {
 		if (miCanZeroArc (parcs))
@@ -99,34 +101,42 @@ fbPolyArc (DrawablePtr	pDrawable,
 		    box.y2 = y2;
 		    if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
 			(RECT_IN_REGION(pDrawable->pScreen, cclip, &box) == rgnIN) ) {
+#ifdef FB_ACCESS_WRAPPER
 			if (!wrapped) {
 			    fbPrepareAccess (pDrawable);
 			    wrapped = 1;
 			}
+#endif
 			(*arc) (dst, dstStride, dstBpp, 
 				parcs, pDrawable->x + dstXoff, pDrawable->y + dstYoff, 
 				pPriv->and, pPriv->xor);
 		    } else {
+#ifdef FB_ACCESS_WRAPPER
 		    	if (wrapped) {
 	    			fbFinishAccess (pDrawable);
 				wrapped = 0;
 			}
+#endif
 			miZeroPolyArc(pDrawable, pGC, 1, parcs);
 		    }
 		}
 		else {
+#ifdef FB_ACCESS_WRAPPER
 		    if (wrapped) {
 	    		fbFinishAccess (pDrawable);
 			wrapped = 0;
 		    }
+#endif
 		    miPolyArc(pDrawable, pGC, 1, parcs);
 		}
 		parcs++;
 	    }
+#ifdef FB_ACCESS_WRAPPER
 	    if (wrapped) {
 		fbFinishAccess (pDrawable);
 		wrapped = 0;
 	    }
+#endif
 	}
 	else
 #endif
commit e0bb33b3d2e4f54cf20853cde9a1664a7dbd0dc7
Author: Alan Hourihane <alanh at tungstengraphics.com>
Date:   Thu Sep 27 14:50:28 2007 +0100

    Fix bug #12286

diff --git a/fb/fbarc.c b/fb/fbarc.c
index 3f46bd4..faf2628 100644
--- a/fb/fbarc.c
+++ b/fb/fbarc.c
@@ -71,9 +71,11 @@ fbPolyArc (DrawablePtr	pDrawable,
 	    BoxRec	box;
 	    int		x2, y2;
 	    RegionPtr	cclip;
+	    int		wrapped = 0;
 	    
 	    cclip = fbGetCompositeClip (pGC);
 	    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+	    wrapped = 1;
 	    while (narcs--)
 	    {
 		if (miCanZeroArc (parcs))
@@ -96,18 +98,35 @@ fbPolyArc (DrawablePtr	pDrawable,
 		    y2 = box.y1 + (int)parcs->height + 1;
 		    box.y2 = y2;
 		    if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
-			(RECT_IN_REGION(pDrawable->pScreen, cclip, &box) == rgnIN) )
+			(RECT_IN_REGION(pDrawable->pScreen, cclip, &box) == rgnIN) ) {
+			if (!wrapped) {
+			    fbPrepareAccess (pDrawable);
+			    wrapped = 1;
+			}
 			(*arc) (dst, dstStride, dstBpp, 
 				parcs, pDrawable->x + dstXoff, pDrawable->y + dstYoff, 
 				pPriv->and, pPriv->xor);
-		    else
+		    } else {
+		    	if (wrapped) {
+	    			fbFinishAccess (pDrawable);
+				wrapped = 0;
+			}
 			miZeroPolyArc(pDrawable, pGC, 1, parcs);
+		    }
 		}
-		else
+		else {
+		    if (wrapped) {
+	    		fbFinishAccess (pDrawable);
+			wrapped = 0;
+		    }
 		    miPolyArc(pDrawable, pGC, 1, parcs);
+		}
 		parcs++;
 	    }
-	    fbFinishAccess (pDrawable);
+	    if (wrapped) {
+		fbFinishAccess (pDrawable);
+		wrapped = 0;
+	    }
 	}
 	else
 #endif
commit 6d5c1e0d896666bcb2b3c1de7bfa424f140be364
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Sep 27 13:04:41 2007 +0200

    EXA: Remove bogus pitch checks.
    
    exaCreatePixmap should handle all cases correctly.

diff --git a/exa/exa.c b/exa/exa.c
index ae6b70f..8d70558 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -726,40 +726,6 @@ exaDriverInit (ScreenPtr		pScreen,
 		   "non-NULL\n", pScreen->myNum);
 	return FALSE;
     }
-
-    /* If the driver doesn't set any max pitch values, we'll just assume
-     * that there's a limitation by pixels, and that it's the same as
-     * maxX.
-     */
-    if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes)
-    {
-        pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
-    }
-
-    /* If set, maxPitchPixels must not be smaller than maxX. */
-    if (pScreenInfo->maxPitchPixels &&
-        pScreenInfo->maxPitchPixels < pScreenInfo->maxX)
-    {
-        LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::maxPitchPixels "
-                   "is smaller than ExaDriverRec::maxX\n",
-                   pScreen->myNum);
-	return FALSE;
-    }
-
-    /* If set, maxPitchBytes must not be smaller than maxX * 4.
-     * This is to ensure that a 32bpp pixmap with the maximum width
-     * can be handled wrt the pitch.
-     */
-    if (pScreenInfo->maxPitchBytes &&
-        pScreenInfo->maxPitchBytes < (pScreenInfo->maxX * 4))
-    {
-        LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::maxPitchBytes "
-                   "doesn't allow a 32bpp pixmap with width equal to "
-                   "ExaDriverRec::maxX\n",
-                   pScreen->myNum);
-	return FALSE;
-    }
-
 #ifdef RENDER
     ps = GetPictureScreenIfSet(pScreen);
 #endif
commit 598698678b07cb3a9406a9ee98bd3186366949e7
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Sep 27 13:07:09 2007 +0200

    EXA: Punt for all fallbacks in exaFillRegion*.
    
    Now that PaintWindow is gone, all callers already handle fallbacks.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 9089535..abe5c20 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1098,6 +1098,7 @@ exaFillRegionSolid (DrawablePtr	pDrawable,
     ExaPixmapPriv (pPixmap);
     int xoff, yoff;
     ExaMigrationRec pixmaps[1];
+    Bool ret = FALSE;
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
@@ -1110,12 +1111,12 @@ exaFillRegionSolid (DrawablePtr	pDrawable,
 
     if (pExaPixmap->accel_blocked)
     {
-	goto fallback;
+	goto out;
     } else {
 	exaDoMigration (pixmaps, 1, TRUE);
     }
 
-    if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
+    if (exaPixmapIsOffscreen (pPixmap) &&
 	(*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
     {
 	int nbox;
@@ -1152,24 +1153,13 @@ exaFillRegionSolid (DrawablePtr	pDrawable,
 			 pRegion);
 	}
 
-	REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
-	return TRUE;
+	ret = TRUE;
     }
 
-fallback:
-    if (alu != GXcopy || !EXA_PM_IS_SOLID(pDrawable, planemask)) {
-	REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
-	return FALSE;
-    }
-    EXA_FALLBACK(("to %p (%c)\n", pDrawable,
-		  exaDrawableLocation(pDrawable)));
-    exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
+out:
     REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
-    fbFillRegionSolid (pDrawable, pRegion, 0,
-		       fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 
-    return TRUE;
+    return ret;
 }
 
 /* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
@@ -1192,6 +1182,7 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
     ExaMigrationRec pixmaps[2];
     int nbox = REGION_NUM_RECTS (pRegion);
     BoxPtr pBox = REGION_RECTS (pRegion);
+    Bool ret = FALSE;
 
     tileWidth = pTile->drawable.width;
     tileHeight = pTile->drawable.height;
@@ -1221,7 +1212,7 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
 
     if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked)
     {
-	goto fallback;
+	goto out;
     } else {
 	exaDoMigration (pixmaps, 2, TRUE);
     }
@@ -1229,7 +1220,7 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
     pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
 
     if (!pPixmap || !exaPixmapIsOffscreen(pTile))
-	goto fallback;
+	goto out;
 
     if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask))
     {
@@ -1272,27 +1263,14 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
 	}
 	(*pExaScr->info->DoneCopy) (pPixmap);
 	exaMarkSync(pDrawable->pScreen);
-	REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
-	return TRUE;
-    }
 
-fallback:
-    if (alu != GXcopy || pPatOrg->x != 0 || pPatOrg->y != 0 ||
-	!EXA_PM_IS_SOLID(pDrawable, planemask)) {
-	REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
-	return FALSE;
+	ret = TRUE;
     }
-    EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
-		  exaDrawableLocation(&pTile->drawable),
-		  exaDrawableLocation(pDrawable)));
-    exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
+
+out:
     REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
-    exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
-    fbFillRegionTiled (pDrawable, pRegion, pTile);
-    exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
-    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 
-    return TRUE;
+    return ret;
 }
 
 
commit 006f6525057970a74382132237b2131286ad147c
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Sep 27 13:08:41 2007 +0200

    EXA: Make sure tile offsets passed to drivers are never negative.
    
    Thanks to Björn Steinbrink for pointing out the problem on IRC.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 142d556..9089535 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1239,7 +1239,8 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
 	    int dstY = pBox->y1;
 	    int tileY;
 
-	    tileY = (dstY - yoff - pDrawable->y - pPatOrg->y) % tileHeight;
+	    modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY);
+
 	    while (height > 0) {
 		int width = pBox->x2 - pBox->x1;
 		int dstX = pBox->x1;
@@ -1250,7 +1251,9 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
 		    h = height;
 		height -= h;
 
-		tileX = (dstX - xoff - pDrawable->x - pPatOrg->x) % tileWidth;
+		modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth,
+			tileX);
+
 		while (width > 0) {
 		    int w = tileWidth - tileX;
 		    if (w > width)
commit da7d9aa1fb60e13a59c9f842fed7aefc5b97c195
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Sep 27 13:08:40 2007 +0200

    EXA: Tile offscreen pixmap coordinate offsets are always 0.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 76dbc72..142d556 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1187,7 +1187,7 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
     PixmapPtr pPixmap;
     ExaPixmapPrivPtr pExaPixmap;
     ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile);
-    int xoff, yoff, tileXoff, tileYoff;
+    int xoff, yoff;
     int tileWidth, tileHeight;
     ExaMigrationRec pixmaps[2];
     int nbox = REGION_NUM_RECTS (pRegion);
@@ -1228,15 +1228,10 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
 
     pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
 
-    if (!pPixmap)
-	goto fallback;
-
-    if (!exaPixmapIsOffscreen(pTile))
+    if (!pPixmap || !exaPixmapIsOffscreen(pTile))
 	goto fallback;
 
-    if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile,
-							     &tileXoff, &tileYoff),
-				       pPixmap, 0, 0, alu, planemask))
+    if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask))
     {
 	while (nbox--)
 	{
@@ -1262,9 +1257,8 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
 			w = width;
 		    width -= w;
 
-		    (*pExaScr->info->Copy) (pPixmap,
-					    tileX + tileXoff, tileY + tileYoff,
-					    dstX, dstY, w, h);
+		    (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY,
+					    w, h);
 		    dstX += w;
 		    tileX = 0;
 		}
commit d6f4764bf5f3a601a0034ded039857e8ea5563b2
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Sep 27 13:08:40 2007 +0200

    EXA: Remove some clearly bogus code from exaCopyNtoN.
    
    Not sure what I was thinking when I wrote this... it would cause the box
    coordinates to be off for exaCopyNtoNTwoDir or fallbacks.
    
    Thanks to Tilman Sauerbeck for pointing out the problem on IRC and testing the
    fix.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 90595d4..76dbc72 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -508,14 +508,6 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
 
 	    region  = RECTS_TO_REGION(pScreen, nbox, rects, CT_YXBANDED);
 	    DEALLOCATE_LOCAL(rects);
-
-	    if (region) {
-		src_off_x -= dst_off_x;
-		src_off_y -= dst_off_y;
-		dst_off_x = dst_off_y = 0;
-		pbox = REGION_RECTS(region);
-		nbox = REGION_NUM_RECTS(region);
-	    }
 	}
     }
 
commit c7d6d1f589d729fa689d22d82fe30afbc6e1cacb
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Sep 27 13:08:40 2007 +0200

    EXA: Punt on fallback case not handled correctly in exaFillRegionTiled.
    
    Fixes http://bugs.freedesktop.org/show_bug.cgi?id=12520 .

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 028d936..90595d4 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1288,7 +1288,8 @@ exaFillRegionTiled (DrawablePtr	pDrawable,
     }
 
 fallback:
-    if (alu != GXcopy || !EXA_PM_IS_SOLID(pDrawable, planemask)) {
+    if (alu != GXcopy || pPatOrg->x != 0 || pPatOrg->y != 0 ||
+	!EXA_PM_IS_SOLID(pDrawable, planemask)) {
 	REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
 	return FALSE;
     }
commit 1d938a80fd4fa58d1791c146b6b5c2dfe148dce7
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Wed Sep 26 19:42:46 2007 -0700

    Remove unused pciAddrHostToBus functions from ix86Pci.c
    
    Matches linuxPci.c changes made in 8279444a54f38c5e2e5d4c2d936a10d74990e0be
    Fixes compiler errors:
     "ix86Pci.c", line 194: too many struct/union initializers
     "ix86Pci.c", line 204: too many struct/union initializers
     "ix86Pci.c", line 214: too many struct/union initializers

diff --git a/hw/xfree86/os-support/bus/ix86Pci.c b/hw/xfree86/os-support/bus/ix86Pci.c
index 3ed4f14..bbc4847 100644
--- a/hw/xfree86/os-support/bus/ix86Pci.c
+++ b/hw/xfree86/os-support/bus/ix86Pci.c
@@ -188,8 +188,8 @@ static pciBusFuncs_t ix86Funcs0 = {
 /* pciReadLong      */	ix86PciReadLongSetup,
 /* pciWriteLong     */	ix86PciWriteLongSetup,
 /* pciSetBitsLong   */	ix86PciSetBitsLongSetup,
-#endif
 /* pciAddrHostToBus */	pciAddrNOOP,
+#endif
 /* pciAddrBusToHost */	pciAddrNOOP
 };
 
@@ -198,8 +198,8 @@ static pciBusFuncs_t ix86Funcs1 = {
 /* pciReadLong      */	ix86PciReadLongCFG1,
 /* pciWriteLong     */	ix86PciWriteLongCFG1,
 /* pciSetBitsLong   */	ix86PciSetBitsLongCFG1,
-#endif
 /* pciAddrHostToBus */	pciAddrNOOP,
+#endif
 /* pciAddrBusToHost */	pciAddrNOOP
 };
 
@@ -208,8 +208,8 @@ static pciBusFuncs_t ix86Funcs2 = {
 /* pciReadLong      */	ix86PciReadLongCFG2,
 /* pciWriteLong     */	ix86PciWriteLongCFG2,
 /* pciSetBitsLong   */	ix86PciSetBitsLongCFG2,
-#endif
 /* pciAddrHostToBus */	pciAddrNOOP,
+#endif
 /* pciAddrBusToHost */	pciAddrNOOP
 };
 


More information about the xorg-commit mailing list