[Xquartz-changes] xserver: Branch 'master' - 39 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Fri Apr 30 16:22:50 PDT 2010


Rebased ref, commits from common ancestor:
commit c96fd9e2bbb49b4437f221561a168559b2a72273
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Tue Apr 27 13:14:47 2010 -0700

    XQuartz GLX: Change around includes for better compatability with different OS versions
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 70558ed..ad9ebbd 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -42,6 +42,8 @@
 #define GL_GLEXT_WUNDEF_SUPPORT
 
 #include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
 #include <OpenGL/CGLContext.h>
 
 /* These next few GL_EXT pre-processing blocks are to explicitly define 
diff --git a/hw/xquartz/GL/visualConfigs.c b/hw/xquartz/GL/visualConfigs.c
index bef27f0..cecc902 100644
--- a/hw/xquartz/GL/visualConfigs.c
+++ b/hw/xquartz/GL/visualConfigs.c
@@ -35,9 +35,10 @@
 #include "dri.h"
 
 #include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
 #include <OpenGL/CGLContext.h>
 
-#include <GL/gl.h>
 #include <GL/glxproto.h>
 #include <windowstr.h>
 #include <resource.h>
commit 41e77bfcc381568ed125996a50f7ea80b13edcef
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Wed Apr 21 08:38:53 2010 -0700

    rootless: Add some sanity checking to miPaintWindow
    
    This avoids painting the root window when it isn't actually drawable.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/mi/miexpose.c b/mi/miexpose.c
index 1c9c3a4..f52b492 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -552,6 +552,9 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     DrawablePtr	drawable = &pWin->drawable;
 
 #ifdef ROOTLESS
+    if(!drawable || drawable->type == UNDRAWABLE_WINDOW)
+	return;
+
     if(IsFramedWindow(pWin)) {
         RootlessStartDrawing(pWin);
         RootlessDamageRegion(pWin, prgn);
commit cb5794ba577b230f6f89564d4f0f753099869d65
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sun Apr 18 01:22:27 2010 -0700

    rootless: Remove an unneeded comment
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c
index e78e2c8..55c7b96 100644
--- a/miext/rootless/rootlessWindow.c
+++ b/miext/rootless/rootlessWindow.c
@@ -1553,10 +1553,6 @@ RootlessDisableRoot (ScreenPtr pScreen)
 	return;
            
     RootlessDestroyFrame (pRoot, winRec);
-    /* 
-     * gstaplin: I fixed the usage of this DeleteProperty so that it would compile.
-     * QUESTION: Where is this xa_native_window_id set?
-     */
     DeleteProperty (serverClient, pRoot, xa_native_window_id ());
 }
 
commit a578897efc24035e408e42fe1232ee52805460b3
Author: Oliver McFadden <oliver.mcfadden at nokia.com>
Date:   Thu Apr 22 10:29:44 2010 +0300

    x-list.c: null-returning function malloc() was called without checking
    
    Signed-off-by: Oliver McFadden <oliver.mcfadden at nokia.com>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/xpr/x-list.c b/hw/xquartz/xpr/x-list.c
index 3596dd3..77c9309 100644
--- a/hw/xquartz/xpr/x-list.c
+++ b/hw/xquartz/xpr/x-list.c
@@ -97,6 +97,7 @@ X_PFX (list_prepend) (x_list *lst, void *data)
         int i;
 
         b = malloc (sizeof (x_list_block));
+        assert(b != NULL);
 
         for (i = 0; i < NODES_PER_BLOCK - 1; i++)
             b->l[i].next = &(b->l[i+1]);
commit 5623908aeef70e5083f3b49986c7547ed044fedd
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Wed Apr 28 12:37:08 2010 -0700

    dix: Improve documentation of the DIX private data functions.
    
    The functions exported by the devPrivates code were poorly documented.  I tried
    to spruce it up a little.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/privates.h b/include/privates.h
index 3c5c321..e6f788d 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -24,32 +24,71 @@ struct _Private;
 typedef struct _Private PrivateRec;
 
 /*
- * Request pre-allocated private space for your driver/module.
- * Calling this is not necessary if only a pointer by itself is needed.
+ * Request pre-allocated private space for your driver/module.  This function
+ * increases the amount of space allocated automatically when dixLookupPrivate
+ * is called on a PrivateRec that does not yet have a value associated with
+ * 'key'.
+ *
+ * This function will only increase the reserved size: if a size was previously
+ * requested, then dixRequestPrivate causes later calls to dixLookupPrivate to
+ * allocate the maximum of the old size and 'size'.  Requested sizes are reset
+ * to 0 by dixResetPrivates, which is called before each server generation.
+ *
+ * If dixRequestPrivate is not called with a nonzero size for 'key', then the
+ * module responsible for 'key' must manage the associated pointer itself with
+ * dixSetPrivate.
+ *
+ * dixRequestPrivate returns FALSE if it cannot store the requested size.
  */
 extern _X_EXPORT int
 dixRequestPrivate(const DevPrivateKey key, unsigned size);
 
 /*
- * Allocates a new private and attaches it to an existing object.
+ * Allocates space for an association of 'key' with a value in 'privates'.
+ *
+ * If a nonzero size was requested with dixRequestPrivate, then
+ * dixAllocatePrivate also allocates the requested amount of memory and
+ * associates the pointer to that memory with 'key' in 'privates'.  The
+ * allocated memory is initialized to zero.  This memory can only be freed by
+ * dixFreePrivates.
+ *
+ * If dixRequestPrivate was never called with a nonzero size, then
+ * dixAllocatePrivate associates NULL with 'key' in 'privates'.
+ *
+ * dixAllocatePrivate returns a pointer to the value associated with 'key' in
+ * 'privates', unless a memory allocation fails, in which case it returns NULL.
  */
 extern _X_EXPORT pointer *
 dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key);
 
 /*
  * Look up a private pointer.
+ *
+ * If no value is currently associated with 'key' in 'privates', then
+ * dixLookupPrivate calls dixAllocatePrivate and returns the resulting
+ * associated value.
+ *
+ * dixLookupPrivate returns NULL if a memory allocation fails.
  */
 extern _X_EXPORT pointer
 dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key);
 
 /*
- * Look up the address of a private pointer.
+ * Look up the address of a private pointer.  If 'key' is not associated with a
+ * value in 'privates', then dixLookupPrivateAddr calls dixAllocatePrivate and
+ * returns a pointer to the resulting associated value.
+ *
+ * dixLookupPrivateAddr returns NULL if 'key' was not previously associated in
+ * 'privates' and a memory allocation fails.
  */
 extern _X_EXPORT pointer *
 dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key);
 
 /*
- * Set a private pointer.
+ * Associate 'val' with 'key' in 'privates' so that later calls to
+ * dixLookupPrivate(privates, key) will return 'val'.
+ *
+ * dixSetPrivate returns FALSE if a memory allocation fails.
  */
 extern _X_EXPORT int
 dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val);
@@ -63,22 +102,33 @@ typedef struct _PrivateCallback {
     pointer *value;	/* address of private pointer */
 } PrivateCallbackRec;
 
+/*
+ * Register a function to be called when dixAllocPrivate successfully associates
+ * 'key' with a new PrivateRec.
+ */
 extern _X_EXPORT int
 dixRegisterPrivateInitFunc(const DevPrivateKey key, 
 			   CallbackProcPtr callback, pointer userdata);
 
+/*
+ * Register a function to be called when dixFreePrivates unassociates 'key' with
+ * a PrivateRec.
+ */
 extern _X_EXPORT int
 dixRegisterPrivateDeleteFunc(const DevPrivateKey key,
 			     CallbackProcPtr callback, pointer userdata);
 
 /*
- * Frees private data.
+ * Unassociates all keys from 'privates', calls the callbacks registered with
+ * dixRegisterPrivateDeleteFunc, and frees all private data automatically
+ * allocated via dixRequestPrivate.
  */
 extern _X_EXPORT void
 dixFreePrivates(PrivateRec *privates);
 
 /*
- * Resets the subsystem, called from the main loop.
+ * Resets the privates subsystem.  dixResetPrivates is called from the main loop
+ * before each server generation.  This function must only be called by main().
  */
 extern _X_EXPORT int
 dixResetPrivates(void);
commit 986d46144b183a36b4e98aed95eca0c55a8b4251
Merge: a974c8e... b5b8f91...
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Apr 30 12:40:53 2010 -0700

    Merge remote branch 'jamey/for-keith'
    
    Conflicts:
    	hw/xfree86/common/xf86xv.c

commit a974c8e7cba40c8d7d1b91e07de8c414627b71a2
Merge: 6581bc4... 02e8622...
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Apr 30 12:33:00 2010 -0700

    Merge remote branch 'whot/for-keith'

commit 6581bc4591746c906d97f8b868f946c47bc6d756
Merge: 0e91e19... d073e51...
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Apr 30 12:29:52 2010 -0700

    Merge remote branch 'yselkowitz/master'

commit 0e91e19f783d21198fc2e210203e0f10040a9cd0
Merge: 81a081c... edbc56c...
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Apr 30 12:27:51 2010 -0700

    Merge remote branch 'vignatti/for-keith'

commit 02e86221b851e5423a95782aa7e297ea051022ca
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 29 09:48:37 2010 +1000

    xfree86: a missing input driver is not an error.
    
    We call NIDR on all devices that make it through the config backend.
    Including some that have no driver assigned to them (/dev/input/mouse0 for
    example). Those ones then simply get ignored by NIDR, but this should not be
    noted as an error in the log file.
    
    X_INFO is sufficient, and it may just prevent some bugreports.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Dan Nicholson <dbn.lists at gmail.com>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index dba3370..a1a5527 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -825,7 +825,7 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
     }
 
     if (!idev->driver || !idev->identifier) {
-        xf86Msg(X_ERROR, "No input driver/identifier specified (ignoring)\n");
+        xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n");
         rval = BadRequest;
         goto unwind;
     }
commit 262c2c9031ea60cbe738ed80ddb7faa1b888d137
Author: Rami Ylimäki <ext-rami.ylimaki at nokia.com>
Date:   Tue Apr 27 14:04:47 2010 +0300

    test: Fix linking of wrapped functions in XI2 tests.
    
    Running "make check" will lead to build problems in
    scratchbox. Building the first test that wraps dixLookupWindow fails
    because symbol __real_dixLookupWindow can't be resolved. Defining
    wrapping options as linker options instead of compiler options makes
    everything build nicely in scratchbox.
    
    Signed-off-by: Rami Ylimäki <ext-rami.ylimaki at nokia.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/xi2/Makefile.am b/test/xi2/Makefile.am
index 0e2de6b..d8dc7e9 100644
--- a/test/xi2/Makefile.am
+++ b/test/xi2/Makefile.am
@@ -31,14 +31,14 @@ protocol_xiquerypointer_LDADD=$(TEST_LDADD)
 protocol_xiwarppointer_LDADD=$(TEST_LDADD)
 protocol_eventconvert_LDADD=$(TEST_LDADD)
 
-protocol_xiqueryversion_CFLAGS=$(AM_CFLAGS) -Wl,-wrap,WriteToClient
-protocol_xiquerydevice_CFLAGS=$(AM_CFLAGS) -Wl,-wrap,WriteToClient
-protocol_xiselectevents_CFLAGS=$(AM_CFLAGS) -Wl,-wrap,dixLookupWindow -Wl,-wrap,XISetEventMask
-protocol_xigetselectedevents_CFLAGS=$(AM_CFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupWindow -Wl,-wrap,AddResource
-protocol_xisetclientpointer_CFLAGS=$(AM_CFLAGS) -Wl,-wrap,dixLookupClient
-protocol_xigetclientpointer_CFLAGS=$(AM_CFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupClient
-protocol_xiquerypointer_CFLAGS=$(AM_CFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupWindow
-protocol_xiwarppointer_CFLAGS=$(AM_CFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupWindow
+protocol_xiqueryversion_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient
+protocol_xiquerydevice_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient
+protocol_xiselectevents_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,dixLookupWindow -Wl,-wrap,XISetEventMask
+protocol_xigetselectedevents_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupWindow -Wl,-wrap,AddResource
+protocol_xisetclientpointer_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,dixLookupClient
+protocol_xigetclientpointer_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupClient
+protocol_xiquerypointer_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupWindow
+protocol_xiwarppointer_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupWindow
 
 protocol_xiqueryversion_SOURCES=$(COMMON_SOURCES) protocol-xiqueryversion.c
 protocol_xiquerydevice_SOURCES=$(COMMON_SOURCES) protocol-xiquerydevice.c
commit b5b8f91b82d7b150c926dd3fecee6c3aafff6e39
Author: Jamey Sharp <jamey at minilop.net>
Date:   Thu Apr 22 21:35:17 2010 -0700

    xfree86: use screen privates for Xv offscreen images.
    
    This replaces a globally-allocated array that depended on MAXSCREENS.
    
    Signed-off-by: Jamey Sharp <jamey at minilop.net>
    Acked-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index bdcc4fc..2cc2f60 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -186,7 +186,9 @@ typedef struct {
    int num;
 } OffscreenImageRec;
 
-static OffscreenImageRec OffscreenImages[MAXSCREENS];
+static int OffscreenPrivateKeyIndex;
+static DevPrivateKey OffscreenPrivateKey = &OffscreenPrivateKeyIndex;
+#define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey))
 
 Bool
 xf86XVRegisterOffscreenImages(
@@ -194,9 +196,18 @@ xf86XVRegisterOffscreenImages(
     XF86OffscreenImagePtr images,
     int num
 ){
-    OffscreenImages[pScreen->myNum].num = num;
-    OffscreenImages[pScreen->myNum].images = images;
-
+    OffscreenImageRec *OffscreenImage;
+    /* This function may be called before xf86XVScreenInit, so there's
+     * no better place than this to call dixRequestPrivate to ensure we
+     * have space reserved. After the first call it is a no-op. */
+    if(!dixRequestPrivate(OffscreenPrivateKey, sizeof(OffscreenImageRec)) ||
+       !(OffscreenImage = GetOffscreenImage(pScreen)))
+        /* Every X.org driver assumes this function always succeeds, so
+         * just die on allocation failure. */
+        FatalError("Could not allocate private storage for XV offscreen images.\n");
+
+    OffscreenImage->num = num;
+    OffscreenImage->images = images;
     return TRUE;
 }
 
@@ -205,8 +216,9 @@ xf86XVQueryOffscreenImages(
    ScreenPtr pScreen,
    int *num
 ){
-   *num = OffscreenImages[pScreen->myNum].num;
-   return OffscreenImages[pScreen->myNum].images;
+    OffscreenImageRec *OffscreenImage = GetOffscreenImage(pScreen);
+    *num = OffscreenImage->num;
+    return OffscreenImage->images;
 }
 
 
@@ -1177,9 +1189,6 @@ xf86XVCloseScreen(int i, ScreenPtr pScreen)
   XvAdaptorPtr pa;
   int c;
 
-  /* Clear offscreen images */
-  memset(&OffscreenImages[pScreen->myNum], 0, sizeof(OffscreenImages[0]));
-
   if(!ScreenPriv) return TRUE;
 
   if(ScreenPriv->videoGC) {
commit a1c2acfe798c57e5be7e5f6c111a6ce91400487a
Author: Jamey Sharp <jamey at minilop.net>
Date:   Wed Apr 21 18:05:45 2010 -0700

    xfree86: use screen privates for exclusive DGA clients.
    
    Most DGA requests allow at most one client to be using DGA on each
    screen. Instead of keeping track of the current client in a
    MAXSCREEN-sized array, track it in a per-screen private.
    
    Signed-off-by: Jamey Sharp <jamey at minilop.net>
    Acked-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>

diff --git a/hw/xfree86/dixmods/extmod/xf86dga2.c b/hw/xfree86/dixmods/extmod/xf86dga2.c
index 5367bcc..0385514 100644
--- a/hw/xfree86/dixmods/extmod/xf86dga2.c
+++ b/hw/xfree86/dixmods/extmod/xf86dga2.c
@@ -57,12 +57,12 @@ static void XDGAResetProc(ExtensionEntry *extEntry);
 
 static void DGAClientStateChange (CallbackListPtr*, pointer, pointer);
 
-static ClientPtr DGAClients[MAXSCREENS];
-
 unsigned char DGAReqCode = 0;
 int DGAErrorBase;
 int DGAEventBase;
 
+static int DGAScreenPrivateKeyIndex;
+static DevPrivateKey DGAScreenPrivateKey = &DGAScreenPrivateKeyIndex;
 static int DGAClientPrivateKeyIndex;
 static DevPrivateKey DGAClientPrivateKey = &DGAClientPrivateKeyIndex;
 static int DGACallbackRefCount = 0;
@@ -73,6 +73,11 @@ typedef struct {
     int		minor;
 } DGAPrivRec, *DGAPrivPtr;
 
+#define DGA_GETCLIENT(idx) ((ClientPtr) \
+    dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey))
+#define DGA_SETCLIENT(idx,p) \
+    dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p)
+
 #define DGA_GETPRIV(c) ((DGAPrivPtr) \
     dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
 #define DGA_SETPRIV(c,p) \
@@ -93,9 +98,6 @@ XFree86DGAExtensionInit(INITARGS)
 				StandardMinorOpcode))) {
 	int i;
 
-	for(i = 0; i < MAXSCREENS; i++)
-	     DGAClients[i] = NULL;
-
 	DGAReqCode = (unsigned char)extEntry->base;
 	DGAErrorBase = extEntry->errorBase;
 	DGAEventBase = extEntry->eventBase;
@@ -282,7 +284,7 @@ DGAClientStateChange (
     int i;
 
     for(i = 0; i < screenInfo.numScreens; i++) {
-	if(DGAClients[i] == pci->client) {
+	if(DGA_GETCLIENT(i) == pci->client) {
 	   client = pci->client;
 	   break;
 	}
@@ -294,7 +296,7 @@ DGAClientStateChange (
 	XDGAModeRec mode;
 	PixmapPtr pPix;
 
-	DGAClients[i] = NULL;
+	DGA_SETCLIENT(i, NULL);
 	DGASelectInput(i, NULL, 0);
 	DGASetMode(i, 0, &mode, &pPix);
 
@@ -311,10 +313,12 @@ ProcXDGASetMode(ClientPtr client)
     XDGAModeRec mode;
     xXDGAModeInfo info;
     PixmapPtr pPix;
+    ClientPtr owner;
     int size;
 
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
+    owner = DGA_GETCLIENT(stuff->screen);
 
     REQUEST_SIZE_MATCH(xXDGASetModeReq);
     rep.type = X_Reply;
@@ -326,16 +330,15 @@ ProcXDGASetMode(ClientPtr client)
     if (!DGAAvailable(stuff->screen))
         return DGAErrorBase + XF86DGANoDirectVideoMode;
 
-    if(DGAClients[stuff->screen] &&
-      (DGAClients[stuff->screen] != client))
+    if(owner && owner != client)
         return DGAErrorBase + XF86DGANoDirectVideoMode;
 
     if(!stuff->mode) {
-	if(DGAClients[stuff->screen]) {
+	if(owner) {
 	  if(--DGACallbackRefCount == 0)
 	    DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
 	}
-	DGAClients[stuff->screen] = NULL;
+	DGA_SETCLIENT(stuff->screen, NULL);
 	DGASelectInput(stuff->screen, NULL, 0);
 	DGASetMode(stuff->screen, 0, &mode, &pPix);
 	WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
@@ -345,12 +348,12 @@ ProcXDGASetMode(ClientPtr client)
     if(Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
 	return BadValue;
 
-    if(!DGAClients[stuff->screen]) {
+    if(!owner) {
 	if(DGACallbackRefCount++ == 0)
 	   AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
     }
 
-    DGAClients[stuff->screen] = client;
+    DGA_SETCLIENT(stuff->screen, client);
 
     if(pPix) {
 	if(AddResource(stuff->pid, RT_PIXMAP, (pointer)(pPix))) {
@@ -405,7 +408,7 @@ ProcXDGASetViewport(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGASetViewportReq);
@@ -425,7 +428,7 @@ ProcXDGAInstallColormap(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
@@ -451,12 +454,12 @@ ProcXDGASelectInput(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGASelectInputReq);
 
-    if(DGAClients[stuff->screen] == client)
+    if(DGA_GETCLIENT(stuff->screen) == client)
 	DGASelectInput(stuff->screen, client, stuff->mask);
 
     return (client->noClientException);
@@ -471,7 +474,7 @@ ProcXDGAFillRectangle(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
@@ -491,7 +494,7 @@ ProcXDGACopyArea(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGACopyAreaReq);
@@ -512,7 +515,7 @@ ProcXDGACopyTransparentArea(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq);
@@ -534,7 +537,7 @@ ProcXDGAGetViewportStatus(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq);
@@ -557,7 +560,7 @@ ProcXDGASync(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGASyncReq);
@@ -602,7 +605,7 @@ ProcXDGAChangePixmapMode(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
@@ -633,7 +636,7 @@ ProcXDGACreateColormap(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGACreateColormapReq);
@@ -713,18 +716,19 @@ ProcXF86DGADirectVideo(ClientPtr client)
     int num;
     PixmapPtr pix;
     XDGAModeRec mode;
+    ClientPtr owner;
     REQUEST(xXF86DGADirectVideoReq);
 
     if (stuff->screen > screenInfo.numScreens)
 	return BadValue;
+    owner = DGA_GETCLIENT(stuff->screen);
 
     REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
 
     if (!DGAAvailable(stuff->screen))
 	return DGAErrorBase + XF86DGANoDirectVideoMode;
 
-    if (DGAClients[stuff->screen] &&
-        (DGAClients[stuff->screen] != client))
+    if (owner && owner != client)
         return DGAErrorBase + XF86DGANoDirectVideoMode;
 
     if (stuff->enable & XF86DGADirectGraphics) {
@@ -743,19 +747,19 @@ ProcXF86DGADirectVideo(ClientPtr client)
     /* We need to track the client and attach the teardown callback */
     if (stuff->enable &
 	(XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) {
-	if (!DGAClients[stuff->screen]) {
+	if (!owner) {
 	    if (DGACallbackRefCount++ == 0)
 		AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
 	}
 
-	DGAClients[stuff->screen] = client;
+	DGA_SETCLIENT(stuff->screen, client);
     } else {
-	if (DGAClients[stuff->screen]) {
+	if (owner) {
 	    if (--DGACallbackRefCount == 0)
 		DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
 	}
 
-	DGAClients[stuff->screen] = NULL;
+	DGA_SETCLIENT(stuff->screen, NULL);
     }
 
     return (client->noClientException);
@@ -800,7 +804,7 @@ ProcXF86DGASetViewPort(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
 	return BadValue;
 
-    if (DGAClients[stuff->screen] != client)
+    if (DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
@@ -864,7 +868,7 @@ ProcXF86DGAInstallColormap(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
 	return BadValue;
 
-    if (DGAClients[stuff->screen] != client)
+    if (DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq);
@@ -913,7 +917,7 @@ ProcXF86DGAViewPortChanged(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
 	return BadValue;
 
-    if (DGAClients[stuff->screen] != client)
+    if (DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq);
commit f9e3a2955d2ca73604c68fc9d51405581b832edb
Author: Jamey Sharp <jamey at minilop.net>
Date:   Mon Apr 26 18:23:27 2010 -0700

    Make Xvfb independent of MAXSCREENS.
    
    If a -screen option specifies a screen number higher than any previously
    specified, reallocate the vfb-private array of screen-info structs.
    
    If built with a DIX that still has a MAXSCREENS limit, asking for too
    many screens won't be detected until InitOutput calls AddScreen.
    
    Signed-off-by: Jamey Sharp <jamey at minilop.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index f710828..2985787 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -104,7 +104,7 @@ typedef struct
 } vfbScreenInfo, *vfbScreenInfoPtr;
 
 static int vfbNumScreens;
-static vfbScreenInfo vfbScreens[MAXSCREENS];
+static vfbScreenInfo *vfbScreens;
 static vfbScreenInfo defaultScreenInfo = {
     .width  = VFB_DEFAULT_WIDTH,
     .height = VFB_DEFAULT_HEIGHT,
@@ -280,7 +280,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
 	int screenNum;
 	CHECK_FOR_REQUIRED_ARGUMENTS(2);
 	screenNum = atoi(argv[i+1]);
-	if (screenNum < 0 || screenNum >= MAXSCREENS)
+	if (screenNum < 0)
 	{
 	    ErrorF("Invalid screen number %d\n", screenNum);
 	    UseMsg();
@@ -288,8 +288,14 @@ ddxProcessArgument(int argc, char *argv[], int i)
 		       screenNum);
 	}
 
-	for (; vfbNumScreens <= screenNum; ++vfbNumScreens)
-	    vfbScreens[vfbNumScreens] = defaultScreenInfo;
+	if (vfbNumScreens <= screenNum)
+	{
+	    vfbScreens = xrealloc(vfbScreens, sizeof(*vfbScreens) * (screenNum + 1));
+	    if (!vfbScreens)
+		FatalError("Not enough memory for screen %d\n", screenNum);
+	    for (; vfbNumScreens <= screenNum; ++vfbNumScreens)
+		vfbScreens[vfbNumScreens] = defaultScreenInfo;
+	}
 
 	if (3 != sscanf(argv[i+2], "%dx%dx%d",
 			&vfbScreens[screenNum].width,
@@ -953,7 +959,7 @@ InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
 
     if (vfbNumScreens < 1)
     {
-	vfbScreens[0] = defaultScreenInfo;
+	vfbScreens = &defaultScreenInfo;
 	vfbNumScreens = 1;
     }
     for (i = 0; i < vfbNumScreens; i++)
commit 20e84b0b44e8b3b40a3ecab5b2e64a27de247b16
Author: Jamey Sharp <jamey at minilop.net>
Date:   Mon Apr 26 18:09:23 2010 -0700

    Xvfb: Simplify screen option processing.
    
    Inspired by Jon Turney's "Xwin: Simplify screen option processing"
    patch, which does something similar for the Xwin server.
    
    Besides making the code more readable, this eliminates most of Xvfb's
    references to MAXSCREENS.
    
    Signed-off-by: Jamey Sharp <jamey at minilop.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index 6d827eb..f710828 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -105,6 +105,14 @@ typedef struct
 
 static int vfbNumScreens;
 static vfbScreenInfo vfbScreens[MAXSCREENS];
+static vfbScreenInfo defaultScreenInfo = {
+    .width  = VFB_DEFAULT_WIDTH,
+    .height = VFB_DEFAULT_HEIGHT,
+    .depth  = VFB_DEFAULT_DEPTH,
+    .blackPixel = VFB_DEFAULT_BLACKPIXEL,
+    .whitePixel = VFB_DEFAULT_WHITEPIXEL,
+    .lineBias = VFB_DEFAULT_LINEBIAS,
+};
 static Bool vfbPixmapDepths[33];
 #ifdef HAS_MMAP
 static char *pfbdir = NULL;
@@ -112,7 +120,6 @@ static char *pfbdir = NULL;
 typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
 static fbMemType fbmemtype = NORMAL_MEMORY_FB;
 static char needswap = 0;
-static int lastScreen = -1;
 static Bool Render = TRUE;
 
 #define swapcopy16(_dst, _src) \
@@ -133,24 +140,6 @@ vfbInitializePixmapDepths(void)
 	vfbPixmapDepths[i] = FALSE;
 }
 
-static void
-vfbInitializeDefaultScreens(void)
-{
-    int i;
-
-    for (i = 0; i < MAXSCREENS; i++)
-    {
-	vfbScreens[i].width  = VFB_DEFAULT_WIDTH;
-	vfbScreens[i].height = VFB_DEFAULT_HEIGHT;
-	vfbScreens[i].depth  = VFB_DEFAULT_DEPTH;
-	vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL;
-	vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL;
-	vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS;
-	vfbScreens[i].pfbMemory = NULL;
-    }
-    vfbNumScreens = 1;
-}
-
 static int
 vfbBitsPerPixel(int depth)
 {
@@ -265,14 +254,20 @@ int
 ddxProcessArgument(int argc, char *argv[], int i)
 {
     static Bool firstTime = TRUE;
+    static int lastScreen = -1;
+    vfbScreenInfo *currentScreen;
 
     if (firstTime)
     {
-	vfbInitializeDefaultScreens();
 	vfbInitializePixmapDepths();
         firstTime = FALSE;
     }
 
+    if (lastScreen == -1)
+	currentScreen = &defaultScreenInfo;
+    else
+	currentScreen = &vfbScreens[lastScreen];
+
 #define CHECK_FOR_REQUIRED_ARGUMENTS(num) \
     if (((i + num) >= argc) || (!argv[i + num])) {                      \
       ErrorF("Required argument to %s not specified\n", argv[i]);       \
@@ -292,6 +287,10 @@ ddxProcessArgument(int argc, char *argv[], int i)
 	    FatalError("Invalid screen number %d passed to -screen\n",
 		       screenNum);
 	}
+
+	for (; vfbNumScreens <= screenNum; ++vfbNumScreens)
+	    vfbScreens[vfbNumScreens] = defaultScreenInfo;
+
 	if (3 != sscanf(argv[i+2], "%dx%dx%d",
 			&vfbScreens[screenNum].width,
 			&vfbScreens[screenNum].height,
@@ -303,8 +302,6 @@ ddxProcessArgument(int argc, char *argv[], int i)
 		   argv[i+2], screenNum);
 	}
 
-	if (screenNum >= vfbNumScreens)
-	    vfbNumScreens = screenNum + 1;
 	lastScreen = screenNum;
 	return 3;
     }
@@ -346,61 +343,22 @@ ddxProcessArgument(int argc, char *argv[], int i)
 
     if (strcmp (argv[i], "-blackpixel") == 0)	/* -blackpixel n */
     {
-	Pixel pix;
 	CHECK_FOR_REQUIRED_ARGUMENTS(1);
-	pix = atoi(argv[++i]);
-	if (-1 == lastScreen)
-	{
-	    int i;
-	    for (i = 0; i < MAXSCREENS; i++)
-	    {
-		vfbScreens[i].blackPixel = pix;
-	    }
-	}
-	else
-	{
-	    vfbScreens[lastScreen].blackPixel = pix;
-	}
+	currentScreen->blackPixel = atoi(argv[++i]);
 	return 2;
     }
 
     if (strcmp (argv[i], "-whitepixel") == 0)	/* -whitepixel n */
     {
-	Pixel pix;
 	CHECK_FOR_REQUIRED_ARGUMENTS(1);
-	pix = atoi(argv[++i]);
-	if (-1 == lastScreen)
-	{
-	    int i;
-	    for (i = 0; i < MAXSCREENS; i++)
-	    {
-		vfbScreens[i].whitePixel = pix;
-	    }
-	}
-	else
-	{
-	    vfbScreens[lastScreen].whitePixel = pix;
-	}
+	currentScreen->whitePixel = atoi(argv[++i]);
 	return 2;
     }
 
     if (strcmp (argv[i], "-linebias") == 0)	/* -linebias n */
     {
-	unsigned int linebias;
 	CHECK_FOR_REQUIRED_ARGUMENTS(1);
-	linebias = atoi(argv[++i]);
-	if (-1 == lastScreen)
-	{
-	    int i;
-	    for (i = 0; i < MAXSCREENS; i++)
-	    {
-		vfbScreens[i].lineBias = linebias;
-	    }
-	}
-	else
-	{
-	    vfbScreens[lastScreen].lineBias = linebias;
-	}
+	currentScreen->lineBias = atoi(argv[++i]);
 	return 2;
     }
 
@@ -993,6 +951,11 @@ InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
 
     /* initialize screens */
 
+    if (vfbNumScreens < 1)
+    {
+	vfbScreens[0] = defaultScreenInfo;
+	vfbNumScreens = 1;
+    }
     for (i = 0; i < vfbNumScreens; i++)
     {
 	if (-1 == AddScreen(vfbScreenInit, argc, argv))
commit eeb84547556b943af2acff207e034823205c7dfe
Author: Jamey Sharp <jamey at minilop.net>
Date:   Mon Apr 26 18:04:25 2010 -0700

    Delete redundant scrnum field from Xvfb private screen-info struct.
    
    The screen number can be inferred from the position in the vfbScreens
    array, and it was only used in two places, so it was hardly important.
    
    Signed-off-by: Jamey Sharp <jamey at minilop.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index b2baa19..6d827eb 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -77,7 +77,6 @@ from The Open Group.
 
 typedef struct
 {
-    int scrnum;
     int width;
     int paddedBytesWidth;
     int paddedWidth;
@@ -141,7 +140,6 @@ vfbInitializeDefaultScreens(void)
 
     for (i = 0; i < MAXSCREENS; i++)
     {
-	vfbScreens[i].scrnum = i;
 	vfbScreens[i].width  = VFB_DEFAULT_WIDTH;
 	vfbScreens[i].height = VFB_DEFAULT_HEIGHT;
 	vfbScreens[i].depth  = VFB_DEFAULT_DEPTH;
@@ -598,7 +596,7 @@ vfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
     char dummyBuffer[DUMMY_BUFFER_SIZE];
     int currentFileSize, writeThisTime;
 
-    sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, pvfb->scrnum);
+    sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, (int) (pvfb - vfbScreens));
     if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666)))
     {
 	perror("open");
@@ -671,7 +669,7 @@ vfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
 	return;
     }
 
-    ErrorF("screen %d shmid %d\n", pvfb->scrnum, pvfb->shmid);
+    ErrorF("screen %d shmid %d\n", (int) (pvfb - vfbScreens), pvfb->shmid);
 }
 #endif /* HAS_SHM */
 
commit da0217891904bc48d5f0b7ea5c62c8ea0e9b95f9
Author: Jamey Sharp <jamey at minilop.net>
Date:   Wed Apr 21 22:26:28 2010 -0700

    Track screens' installed colormaps as screen privates.
    
    Several DDXes allow each screen to have at most one (or in some cases,
    exactly one) installed colormap. These all use the same pattern: Declare
    a global-lifetime array of MAXSCREENS ColormapPtrs, and index it by
    screen number. This patch converts most of those to use screen privates
    instead.
    
    Signed-off-by: Jamey Sharp <jamey at minilop.net>
    Acked-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/fb/fbcmap.c b/fb/fbcmap.c
index 2ff3234..b775bc3 100644
--- a/fb/fbcmap.c
+++ b/fb/fbcmap.c
@@ -36,16 +36,18 @@
 #error "You should be compiling fbcmap_mi.c instead of fbcmap.c!"
 #endif
 
+static int cmapScrPrivateKeyIndex;
+static DevPrivateKey cmapScrPrivateKey = &cmapScrPrivateKeyIndex;
 
-
-ColormapPtr FbInstalledMaps[MAXSCREENS];
+#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
+#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
 
 int
 fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 {
     /* By the time we are processing requests, we can guarantee that there
      * is always a colormap installed */
-    *pmaps = FbInstalledMaps[pScreen->myNum]->mid;
+    *pmaps = GetInstalledColormap(pScreen)->mid;
     return (1);
 }
 
@@ -53,8 +55,7 @@ fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 void
 fbInstallColormap(ColormapPtr pmap)
 {
-    int index = pmap->pScreen->myNum;
-    ColormapPtr oldpmap = FbInstalledMaps[index];
+    ColormapPtr oldpmap = GetInstalledColormap(pmap->pScreen);
 
     if(pmap != oldpmap)
     {
@@ -63,7 +64,7 @@ fbInstallColormap(ColormapPtr pmap)
 	if(oldpmap != (ColormapPtr)None)
 	    WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
 	/* Install pmap */
-	FbInstalledMaps[index] = pmap;
+	SetInstalledColormap(pmap->pScreen, pmap);
 	WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
     }
 }
@@ -71,8 +72,7 @@ fbInstallColormap(ColormapPtr pmap)
 void
 fbUninstallColormap(ColormapPtr pmap)
 {
-    int index = pmap->pScreen->myNum;
-    ColormapPtr curpmap = FbInstalledMaps[index];
+    ColormapPtr curpmap = GetInstalledColormap(pmap->pScreen);
 
     if(pmap == curpmap)
     {
diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index 60915fd..b2baa19 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -427,14 +427,18 @@ ddxProcessArgument(int argc, char *argv[], int i)
     return 0;
 }
 
-static ColormapPtr InstalledMaps[MAXSCREENS];
+static int cmapScrPrivateKeyIndex;
+static DevPrivateKey cmapScrPrivateKey = &cmapScrPrivateKeyIndex;
+
+#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
+#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
 
 static int
 vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 {
     /* By the time we are processing requests, we can guarantee that there
      * is always a colormap installed */
-    *pmaps = InstalledMaps[pScreen->myNum]->mid;
+    *pmaps = GetInstalledColormap(pScreen)->mid;
     return (1);
 }
 
@@ -442,8 +446,7 @@ vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 static void
 vfbInstallColormap(ColormapPtr pmap)
 {
-    int index = pmap->pScreen->myNum;
-    ColormapPtr oldpmap = InstalledMaps[index];
+    ColormapPtr oldpmap = GetInstalledColormap(pmap->pScreen);
 
     if (pmap != oldpmap)
     {
@@ -459,7 +462,7 @@ vfbInstallColormap(ColormapPtr pmap)
 	if(oldpmap != (ColormapPtr)None)
 	    WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
 	/* Install pmap */
-	InstalledMaps[index] = pmap;
+	SetInstalledColormap(pmap->pScreen, pmap);
 	WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
 
 	entries = pmap->pVisual->ColormapEntries;
@@ -500,7 +503,7 @@ vfbInstallColormap(ColormapPtr pmap)
 static void
 vfbUninstallColormap(ColormapPtr pmap)
 {
-    ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
+    ColormapPtr curpmap = GetInstalledColormap(pmap->pScreen);
 
     if(pmap == curpmap)
     {
@@ -521,7 +524,7 @@ vfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
     XWDColor *pXWDCmap;
     int i;
 
-    if (pmap != InstalledMaps[pmap->pScreen->myNum])
+    if (pmap != GetInstalledColormap(pmap->pScreen))
     {
 	return;
     }
@@ -830,10 +833,10 @@ vfbCloseScreen(int index, ScreenPtr pScreen)
 
     /*
      * XXX probably lots of stuff to clean.  For now,
-     * clear InstalledMaps[] so that server reset works correctly.
+     * clear installed colormaps so that server reset works correctly.
      */
-    for (i = 0; i < MAXSCREENS; i++)
-	InstalledMaps[i] = NULL;
+    for (i = 0; i < screenInfo.numScreens; i++)
+	SetInstalledColormap(screenInfo.screens[i], NULL);
 
     return pScreen->CloseScreen(index, pScreen);
 }
diff --git a/hw/xnest/Color.c b/hw/xnest/Color.c
index dc74947..2e6de15 100644
--- a/hw/xnest/Color.c
+++ b/hw/xnest/Color.c
@@ -34,7 +34,11 @@ is" without express or implied warranty.
 #include "XNWindow.h"
 #include "Args.h"
 
-static ColormapPtr InstalledMaps[MAXSCREENS];
+static int cmapScrPrivateKeyIndex;
+static DevPrivateKey cmapScrPrivateKey = &cmapScrPrivateKeyIndex;
+
+#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
+#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
 
 Bool
 xnestCreateColormap(ColormapPtr pCmap)
@@ -332,11 +336,7 @@ xnestDirectUninstallColormaps(ScreenPtr pScreen)
 void
 xnestInstallColormap(ColormapPtr pCmap)
 {
-  int index;
-  ColormapPtr pOldCmap;
-  
-  index = pCmap->pScreen->myNum;
-  pOldCmap = InstalledMaps[index];
+  ColormapPtr pOldCmap = GetInstalledColormap(pCmap->pScreen);
   
   if(pCmap != pOldCmap)
     {
@@ -346,7 +346,7 @@ xnestInstallColormap(ColormapPtr pCmap)
       if(pOldCmap != (ColormapPtr)None)
 	WalkTree(pCmap->pScreen, TellLostMap, (pointer)&pOldCmap->mid);
       
-      InstalledMaps[index] = pCmap;
+      SetInstalledColormap(pCmap->pScreen, pCmap);
       WalkTree(pCmap->pScreen, TellGainedMap, (pointer)&pCmap->mid);
       
       xnestSetInstalledColormapWindows(pCmap->pScreen);
@@ -357,11 +357,7 @@ xnestInstallColormap(ColormapPtr pCmap)
 void
 xnestUninstallColormap(ColormapPtr pCmap)
 {
-  int index;
-  ColormapPtr pCurCmap;
-  
-  index = pCmap->pScreen->myNum;
-  pCurCmap = InstalledMaps[index];
+  ColormapPtr pCurCmap = GetInstalledColormap(pCmap->pScreen);
   
   if(pCmap == pCurCmap)
     {
@@ -382,7 +378,7 @@ int
 xnestListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIDs)
 {
   if (xnestInstalledDefaultColormap) {
-    *pCmapIDs = InstalledMaps[pScreen->myNum]->mid;
+    *pCmapIDs = GetInstalledColormap(pScreen)->mid;
     return 1;
   }
   else
commit 22c4300ee25a20e1f815e46225bf0de9cfd6748f
Author: Jamey Sharp <jamey at minilop.net>
Date:   Wed Oct 7 09:00:02 2009 -0700

    Simplify XineramifyXv.
    
    The structure of the adaptor-matching algorithm was obscured by trying
    to use "continue" and "break" as the only control-flow primitives. It's
    a lot more clear if you add "return" to that set.
    
    Signed-off-by: Jamey Sharp <jamey at minilop.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/Xext/xvdisp.c b/Xext/xvdisp.c
index b6fc34f..4345672 100644
--- a/Xext/xvdisp.c
+++ b/Xext/xvdisp.c
@@ -1850,110 +1850,91 @@ XineramaXvPutStill(ClientPtr client)
     return result;
 }
 
+static Bool
+isImageAdaptor(XvAdaptorPtr pAdapt)
+{
+    return (pAdapt->type & XvImageMask) && (pAdapt->nImages > 0);
+}
+
+static Bool
+hasOverlay(XvAdaptorPtr pAdapt)
+{
+    int i;
+    for(i = 0; i < pAdapt->nAttributes; i++)
+	if(!strcmp(pAdapt->pAttributes[i].name, "XV_COLORKEY"))
+	    return TRUE;
+    return FALSE;
+}
+
+static XvAdaptorPtr
+matchAdaptor(ScreenPtr pScreen, XvAdaptorPtr refAdapt, Bool isOverlay)
+{
+    int i;
+    XvScreenPtr xvsp = dixLookupPrivate(&pScreen->devPrivates, XvGetScreenKey());
+    /* Do not try to go on if xv is not supported on this screen */
+    if(xvsp == NULL)
+	return NULL;
+
+    /* if the adaptor has the same name it's a perfect match */
+    for(i = 0; i < xvsp->nAdaptors; i++) {
+	XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
+	if(!strcmp(refAdapt->name, pAdapt->name))
+	    return pAdapt;
+    }
+
+    /* otherwise we only look for XvImage adaptors */
+    if(!isImageAdaptor(refAdapt))
+	return NULL;
+
+    /* prefer overlay/overlay non-overlay/non-overlay pairing */
+    for(i = 0; i < xvsp->nAdaptors; i++) {
+	XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
+	if(isImageAdaptor(pAdapt) && isOverlay == hasOverlay(pAdapt))
+	    return pAdapt;
+    }
+
+    /* but we'll take any XvImage pairing if we can get it */
+    for(i = 0; i < xvsp->nAdaptors; i++) {
+	XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
+	if(isImageAdaptor(pAdapt))
+	    return pAdapt;
+    }
+    return NULL;
+}
+
 void XineramifyXv(void)
 {
-   ScreenPtr pScreen, screen0 = screenInfo.screens[0];
-   XvScreenPtr xvsp0 = (XvScreenPtr)dixLookupPrivate(&screen0->devPrivates,
-						     XvGetScreenKey());
-   XvAdaptorPtr refAdapt, pAdapt;
-   XvAttributePtr pAttr;
-   XvScreenPtr xvsp;
-   Bool isOverlay, hasOverlay;
-   PanoramiXRes *port;
+   XvScreenPtr xvsp0 = dixLookupPrivate(&screenInfo.screens[0]->devPrivates, XvGetScreenKey());
    XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
-   int i, j, k, l;
+   int i, j, k;
 
    XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort");
 
    if (!xvsp0 || !XvXRTPort) return;
 
    for(i = 0; i < xvsp0->nAdaptors; i++) {
-      refAdapt = xvsp0->pAdaptors + i;
+      Bool isOverlay;
+      XvAdaptorPtr refAdapt = xvsp0->pAdaptors + i;
+      if(!(refAdapt->type & XvInputMask)) continue;
 
-      bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
-      
       MatchingAdaptors[0] = refAdapt;
-   
-      if(!(refAdapt->type & XvInputMask)) continue;
-      
-      isOverlay = FALSE;
-      for(j = 0; j < refAdapt->nAttributes; j++) {
-         pAttr = refAdapt->pAttributes + j;
-         if(!strcmp(pAttr->name, "XV_COLORKEY")) {
-	    isOverlay = TRUE;
-	    break;
-	 }
-      }
-   
-      for(j = 1; j < PanoramiXNumScreens; j++) {
-         pScreen = screenInfo.screens[j];
-	 xvsp = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
-					      XvGetScreenKey());
-         /* Do not try to go on if xv is not supported on this screen */
-         if (xvsp==NULL) continue ;
-	 
-         /* if the adaptor has the same name it's a perfect match */
-	 for(k = 0; k < xvsp->nAdaptors; k++) {
-	   pAdapt = xvsp->pAdaptors + k;
-           if(!strcmp(refAdapt->name, pAdapt->name)) {
-	       MatchingAdaptors[j] = pAdapt;
-	       break;
-	   }
-         }
-	 if(MatchingAdaptors[j]) continue; /* found it */
-	 
-	 /* otherwise we only look for XvImage adaptors */
-	 if(!(refAdapt->type & XvImageMask)) continue;
-	 if(refAdapt->nImages <= 0) continue;
-	 
-	 /* prefer overlay/overlay non-overlay/non-overlay pairing */
-	 for(k = 0; k < xvsp->nAdaptors; k++) {
-	    pAdapt = xvsp->pAdaptors + k;
-	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
-	      hasOverlay = FALSE;
-              for(l = 0; l < pAdapt->nAttributes; l++) {
-	         if(!strcmp(pAdapt->pAttributes[l].name, "XV_COLORKEY")) {
-		   hasOverlay = TRUE;
-		   break;
-		 }
-	      }
-	      if(isOverlay && hasOverlay) {
-	      	 MatchingAdaptors[j] = pAdapt;
-		 break;
-	      }
-              else if(!isOverlay && !hasOverlay) {
-	      	 MatchingAdaptors[j] = pAdapt;
-		 break;
-	      }
-	    }
-         }
-	 
-	 if(MatchingAdaptors[j]) continue; /* found it */
-	 
-	 /* but we'll take any XvImage pairing if we can get it */
-	 	 
-	 for(k = 0; k < xvsp->nAdaptors; k++) {
-	    pAdapt = xvsp->pAdaptors + k;
-	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
-	      	 MatchingAdaptors[j] = pAdapt;
-		 break;
-	    }
-         }
-      }
+      isOverlay = hasOverlay(refAdapt);
+      for(j = 1; j < PanoramiXNumScreens; j++)
+	 MatchingAdaptors[j] = matchAdaptor(screenInfo.screens[j], refAdapt, isOverlay);
 
       /* now create a resource for each port */
       for(j = 0; j < refAdapt->nPorts; j++) {
-         if(!(port = xalloc(sizeof(PanoramiXRes))))
+	 PanoramiXRes *port = xalloc(sizeof(PanoramiXRes));
+	 if(!port)
 	    break;
-	 port->info[0].id = MatchingAdaptors[0]->base_id + j;
-	 AddResource(port->info[0].id, XvXRTPort, port);
 
-	 for(k = 1; k < PanoramiXNumScreens; k++) {
+	 for(k = 0; k < PanoramiXNumScreens; k++) {
 	    if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) 
 		port->info[k].id = MatchingAdaptors[k]->base_id + j;
 	    else
 		port->info[k].id = 0;
 	 } 
+	 AddResource(port->info[0].id, XvXRTPort, port);
       }
    }
 
commit af170a4ab76d33254dd4e54a33bb410fa1624739
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 21 15:51:20 2010 +1000

    Xext: only update the sprite on pointer events.
    
    A call to miPointerUpdateSprite for the XTEST keyboard may result in a
    NULL pointer dereference in miDCPutUpCursor() when the save buffer is NULL.
    
    XTS test case: Xlib 11 KeymapNotify
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index a1aacc4..99b6711 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -184,6 +184,7 @@ ProcXTestFakeInput(ClientPtr client)
     int i;
     int base = 0;
     int flags = 0;
+    int need_ptr_update = 1;
 
     nev = (stuff->length << 2) - sizeof(xReq);
     if ((nev % sizeof(xEvent)) || !nev)
@@ -388,6 +389,8 @@ ProcXTestFakeInput(ClientPtr client)
                 client->errorValue = ev->u.u.detail;
                 return BadValue;
             }
+
+            need_ptr_update = 0;
             break;
         case MotionNotify:
             if (!dev->valuator)
@@ -452,7 +455,8 @@ ProcXTestFakeInput(ClientPtr client)
     for (i = 0; i < nevents; i++)
         mieqProcessDeviceEvent(dev, (InternalEvent*)(xtest_evlist+i)->event, NULL);
 
-    miPointerUpdateSprite(dev);
+    if (need_ptr_update)
+        miPointerUpdateSprite(dev);
     return client->noClientException;
 }
 
commit bac1c5f1be4588b2b1eb646ee98a5442e1b767d5
Author: Dirk Wallenstein <halsmit at t-online.de>
Date:   Sat Apr 17 21:36:23 2010 +0200

    xkb: Fix omissions in geometry initialization #27679
    
    _XkbCopyGeom did not copy all of the data from the source geometry. This
    resulted in failures when trying to obtain the keymap from a server
    where the default geometry has not been replaced by a custom
    configuration.
    
    Signed-off-by: Dirk Wallenstein <halsmit at t-online.de>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index e287997..6d0901a 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -1601,6 +1601,7 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
                 else {
                     dcolor->spec = xstrdup(scolor->spec);
                 }
+                dcolor->pixel = scolor->pixel;
             }
 
             dst->geom->num_colors = dst->geom->sz_colors;
@@ -1672,6 +1673,8 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
 
                             memcpy(doutline->points, soutline->points,
                                    soutline->num_points * sizeof(XkbPointRec));
+
+                            doutline->corner_radius = soutline->corner_radius;
                         }
 
                         doutline->num_points = soutline->num_points;
@@ -1681,6 +1684,36 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
 
                 dshape->num_outlines = sshape->num_outlines;
                 dshape->sz_outlines = sshape->num_outlines;
+                dshape->name = sshape->name;
+                dshape->bounds = sshape->bounds;
+
+                dshape->approx = NULL;
+                if (sshape->approx && sshape->num_outlines > 0) {
+
+                    const ptrdiff_t approx_idx =
+                            sshape->approx - sshape->outlines;
+
+                    if (approx_idx < dshape->num_outlines) {
+                            dshape->approx = dshape->outlines + approx_idx;
+                    } else {
+                            LogMessage(X_WARNING, "XKB: approx outline "
+                                            "index is out of range\n");
+                    }
+                }
+
+                dshape->primary = NULL;
+                if (sshape->primary && sshape->num_outlines > 0) {
+
+                    const ptrdiff_t primary_idx =
+                            sshape->primary - sshape->outlines;
+
+                    if (primary_idx < dshape->num_outlines) {
+                            dshape->primary = dshape->outlines + primary_idx;
+                    } else {
+                            LogMessage(X_WARNING, "XKB: primary outline "
+                                            "index is out of range\n");
+                    }
+                }
             }
 
             dst->geom->num_shapes = src->geom->num_shapes;
@@ -1784,6 +1817,10 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
                     }
                     drow->num_keys = srow->num_keys;
                     drow->sz_keys = srow->num_keys;
+                    drow->top = srow->top;
+                    drow->left = srow->left;
+                    drow->vertical = srow->vertical;
+                    drow->bounds = srow->bounds;
                 }
 
                 if (ssection->num_doodads) {
@@ -1802,6 +1839,7 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
                       ddoodad = dsection->doodads;
                      k < ssection->num_doodads;
                      k++, sdoodad++, ddoodad++) {
+                    memcpy(ddoodad , sdoodad, sizeof(XkbDoodadRec));
                     if (sdoodad->any.type == XkbTextDoodad) {
                         if (sdoodad->text.text)
                             ddoodad->text.text =
@@ -1815,7 +1853,6 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
                             ddoodad->logo.logo_name =
                              xstrdup(sdoodad->logo.logo_name);
                     }
-                    ddoodad->any.type = sdoodad->any.type;
                 }
                 dsection->overlays = NULL;
                 dsection->sz_overlays = 0;
@@ -1880,7 +1917,7 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
                   ddoodad = dst->geom->doodads;
                  i < src->geom->num_doodads;
                  i++, sdoodad++, ddoodad++) {
-                ddoodad->any.type = sdoodad->any.type;
+                memcpy(ddoodad , sdoodad, sizeof(XkbDoodadRec));
                 if (sdoodad->any.type == XkbTextDoodad) {
                     if (sdoodad->text.text)
                         ddoodad->text.text = xstrdup(sdoodad->text.text);
commit d073e51beeed2e702fa5c7534b1345360bc302f2
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Mon Apr 26 11:39:19 2010 -0500

    Clarify help strings for disabled features in configure
    
    Features which are disabled by default use the --enable-* syntax to show
    how they need to be passed to override the default.
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Reviewed-by: Mikhail Gusarov <dottedmag at dottedmag.net>
    Reviewed-by: Dan Nicholson <dbn.lists at gmail.com>
    Reviewed-by: Gaetan Nadon <memsize at videotron.ca>

diff --git a/configure.ac b/configure.ac
index ec7ff0f..92ce900 100644
--- a/configure.ac
+++ b/configure.ac
@@ -628,12 +628,12 @@ AC_ARG_ENABLE(dri2,           AS_HELP_STRING([--enable-dri2], [Build DRI2 extens
 AC_ARG_ENABLE(xinerama,	      AS_HELP_STRING([--disable-xinerama], [Build Xinerama extension (default: enabled)]), [XINERAMA=$enableval], [XINERAMA=yes])
 AC_ARG_ENABLE(xf86vidmode,    AS_HELP_STRING([--disable-xf86vidmode], [Build XF86VidMode extension (default: auto)]), [XF86VIDMODE=$enableval], [XF86VIDMODE=auto])
 AC_ARG_ENABLE(xace,           AS_HELP_STRING([--disable-xace], [Build X-ACE extension (default: enabled)]), [XACE=$enableval], [XACE=yes])
-AC_ARG_ENABLE(xselinux,       AS_HELP_STRING([--disable-xselinux], [Build SELinux extension (default: disabled)]), [XSELINUX=$enableval], [XSELINUX=no])
-AC_ARG_ENABLE(xcsecurity,     AS_HELP_STRING([--disable-xcsecurity], [Build Security extension (default: disabled)]), [XCSECURITY=$enableval], [XCSECURITY=no])
+AC_ARG_ENABLE(xselinux,       AS_HELP_STRING([--enable-xselinux], [Build SELinux extension (default: disabled)]), [XSELINUX=$enableval], [XSELINUX=no])
+AC_ARG_ENABLE(xcsecurity,     AS_HELP_STRING([--enable-xcsecurity], [Build Security extension (default: disabled)]), [XCSECURITY=$enableval], [XCSECURITY=no])
 AC_ARG_ENABLE(xcalibrate,     AS_HELP_STRING([--enable-xcalibrate], [Build XCalibrate extension (default: disabled)]), [XCALIBRATE=$enableval], [XCALIBRATE=no])
 AC_ARG_ENABLE(tslib,          AS_HELP_STRING([--enable-tslib], [Build kdrive tslib touchscreen support (default: disabled)]), [TSLIB=$enableval], [TSLIB=no])
 AC_ARG_ENABLE(dbe,            AS_HELP_STRING([--disable-dbe], [Build DBE extension (default: enabled)]), [DBE=$enableval], [DBE=yes])
-AC_ARG_ENABLE(xf86bigfont,    AS_HELP_STRING([--disable-xf86bigfont], [Build XF86 Big Font extension (default: disabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=no])
+AC_ARG_ENABLE(xf86bigfont,    AS_HELP_STRING([--enable-xf86bigfont], [Build XF86 Big Font extension (default: disabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=no])
 AC_ARG_ENABLE(dpms,           AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes])
 AC_ARG_ENABLE(config-udev,    AS_HELP_STRING([--enable-config-udev], [Build udev support (default: auto)]), [CONFIG_UDEV=$enableval], [CONFIG_UDEV=auto])
 AC_ARG_ENABLE(config-dbus,    AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no])
commit 57409af1267f48457f93134922f2450518182e09
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Wed Apr 14 13:18:28 2010 -0500

    Catch when requested SHA1 implementation is missing
    
    The other SHA1 implementation detections already error out if
    specifically requested but were not found.
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/configure.ac b/configure.ac
index 7b74820..ec7ff0f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1386,6 +1386,9 @@ AC_CHECK_LIB([sha1], [sha1_begin], [HAVE_LIBSHA1=yes])
 if test "x$with_sha1" = x && test "x$HAVE_LIBSHA1" = xyes; then
    with_sha1=libsha1
 fi
+if test "x$with_sha1" = xlibsha1 && test "x$HAVE_LIBSHA1" != xyes; then
+	AC_MSG_ERROR([libsha1 requested but not found])
+fi
 if test "x$with_sha1" = xlibsha1; then
 	AC_DEFINE([HAVE_SHA1_IN_LIBSHA1], [1],
 	          [Use libsha1 for SHA1])
@@ -1395,6 +1398,9 @@ AC_CHECK_LIB([gcrypt], [gcry_md_open], [HAVE_LIBGCRYPT=yes])
 if test "x$with_sha1" = x && test "x$HAVE_LIBGCRYPT" = xyes; then
 	with_sha1=libgcrypt
 fi
+if test "x$with_sha1" = xlibgcrypt && test "x$HAVE_LIBGCRYPT" != xyes; then
+	AC_MSG_ERROR([libgcrypt requested but not found])
+fi
 if test "x$with_sha1" = xlibgcrypt; then
 	AC_DEFINE([HAVE_SHA1_IN_LIBGCRYPT], [1],
 	          [Use libgcrypt SHA1 functions])
commit 0d8fe2fe5c37659147cbecac793183c62fc6818a
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Tue Apr 13 13:32:51 2010 -0500

    Prefer libsha1 over libgcrypt
    
    When no SHA1 implementation is specified, we should first prefer
    system-builtin solutions (libc/libmd/CommonCrypto), then smaller
    implementations over the larger ones.  libsha1 is much smaller than
    libgcrypt, so it should be first.
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Reviewed-by: Mikhail Gusarov <dottedmag at dottedmag.net>
    Acked-by: Julien Cristau <jcristau at debian.org>

diff --git a/configure.ac b/configure.ac
index 1dc05f9..7b74820 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1382,15 +1382,6 @@ if test "x$with_sha1" = xlibmd; then
 	          [Use libmd SHA1 functions])
 	SHA1_LIBS=-lmd
 fi
-AC_CHECK_LIB([gcrypt], [gcry_md_open], [HAVE_LIBGCRYPT=yes])
-if test "x$with_sha1" = x && test "x$HAVE_LIBGCRYPT" = xyes; then
-	with_sha1=libgcrypt
-fi
-if test "x$with_sha1" = xlibgcrypt; then
-	AC_DEFINE([HAVE_SHA1_IN_LIBGCRYPT], [1],
-	          [Use libgcrypt SHA1 functions])
-	SHA1_LIBS=-lgcrypt
-fi
 AC_CHECK_LIB([sha1], [sha1_begin], [HAVE_LIBSHA1=yes])
 if test "x$with_sha1" = x && test "x$HAVE_LIBSHA1" = xyes; then
    with_sha1=libsha1
@@ -1400,6 +1391,15 @@ if test "x$with_sha1" = xlibsha1; then
 	          [Use libsha1 for SHA1])
 	SHA1_LIBS=-lsha1
 fi
+AC_CHECK_LIB([gcrypt], [gcry_md_open], [HAVE_LIBGCRYPT=yes])
+if test "x$with_sha1" = x && test "x$HAVE_LIBGCRYPT" = xyes; then
+	with_sha1=libgcrypt
+fi
+if test "x$with_sha1" = xlibgcrypt; then
+	AC_DEFINE([HAVE_SHA1_IN_LIBGCRYPT], [1],
+	          [Use libgcrypt SHA1 functions])
+	SHA1_LIBS=-lgcrypt
+fi
 # We don't need all of the OpenSSL libraries, just libcrypto
 AC_CHECK_LIB([crypto], [SHA1_Init], [HAVE_LIBCRYPTO=yes])
 PKG_CHECK_MODULES([OPENSSL], [openssl], [HAVE_OPENSSL_PKC=yes],
commit 65a2c09549d2372c23b155addff428177708c910
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Thu Apr 8 21:55:45 2010 -0500

    Revert "Disable Record by default."
    
    Record was broken during the pre-1.6 development cycle and was not fixed
    until 1.7.6.  Now that it is fixed, re-enable it by default.
    
    This reverts commit 3eaecdd66e791e0f3d86b23ce10be057ca44c044.
    
    Conflicts:
    
    	configure.ac
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/configure.ac b/configure.ac
index b491d52..1dc05f9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -615,7 +615,7 @@ AC_ARG_ENABLE(registry,       AS_HELP_STRING([--disable-registry], [Build string
 AC_ARG_ENABLE(composite,      AS_HELP_STRING([--disable-composite], [Build Composite extension (default: enabled)]), [COMPOSITE=$enableval], [COMPOSITE=yes])
 AC_ARG_ENABLE(mitshm,         AS_HELP_STRING([--disable-shm], [Build SHM extension (default: enabled)]), [MITSHM=$enableval], [MITSHM=yes])
 AC_ARG_ENABLE(xres,           AS_HELP_STRING([--disable-xres], [Build XRes extension (default: enabled)]), [RES=$enableval], [RES=yes])
-AC_ARG_ENABLE(record,         AS_HELP_STRING([--enable-record], [Build Record extension (default: disabled)]), [RECORD=$enableval], [RECORD=no])
+AC_ARG_ENABLE(record,         AS_HELP_STRING([--disable-record], [Build Record extension (default: enabled)]), [RECORD=$enableval], [RECORD=yes])
 AC_ARG_ENABLE(xv,             AS_HELP_STRING([--disable-xv], [Build Xv extension (default: enabled)]), [XV=$enableval], [XV=yes])
 AC_ARG_ENABLE(xvmc,           AS_HELP_STRING([--disable-xvmc], [Build XvMC extension (default: enabled)]), [XVMC=$enableval], [XVMC=yes])
 AC_ARG_ENABLE(dga,            AS_HELP_STRING([--disable-dga], [Build DGA extension (default: auto)]), [DGA=$enableval], [DGA=auto])
commit 6e0d847c273ab89323883a05f806f449180e3669
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Thu Mar 25 03:37:09 2010 -0500

    xfree86: Fix reference to SGML entities
    
    XORG_CHECK_LINUXDOC sets the SGML search path to the parent of X11/defs.ent.
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Acked-by: Dan Nicholson <dbn.lists at gmail.com>
    Tested-by: Gaetan Nadon <memsize at videotron.ca>

diff --git a/hw/xfree86/doc/sgml/DESIGN.sgml b/hw/xfree86/doc/sgml/DESIGN.sgml
index 5beff65..e95df79 100644
--- a/hw/xfree86/doc/sgml/DESIGN.sgml
+++ b/hw/xfree86/doc/sgml/DESIGN.sgml
@@ -1,5 +1,5 @@
 <!DOCTYPE linuxdoc PUBLIC "-//Xorg//DTD linuxdoc//EN" [
- <!ENTITY % defs SYSTEM "defs.ent"> %defs;
+ <!ENTITY % defs SYSTEM "X11/defs.ent"> %defs;
  <!-- config file keyword markup -->
  <!ENTITY s.key STARTTAG "bf">
  <!ENTITY e.key ENDTAG "bf">
commit 04b7d529c09af2c842cf020d5b26080e1ffd88d6
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Thu Mar 25 03:36:25 2010 -0500

    xfree86: Ignore linuxdoc generated docs
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Acked-by: Gaetan Nadon <memsize at videotron.ca>

diff --git a/hw/xfree86/doc/sgml/.gitignore b/hw/xfree86/doc/sgml/.gitignore
new file mode 100644
index 0000000..a06a215
--- /dev/null
+++ b/hw/xfree86/doc/sgml/.gitignore
@@ -0,0 +1,5 @@
+#		Add & Override for this directory and it's subdirectories
+DESIGN.html
+DESIGN.pdf
+DESIGN.ps
+DESIGN.txt
commit 39e5108c78e0802833a8e9ea7f29d042738625ba
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Thu Mar 25 03:35:36 2010 -0500

    dmx: use silent rules in doc
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Acked-by: Gaetan Nadon <memsize at videotron.ca>

diff --git a/hw/dmx/doc/Makefile.am b/hw/dmx/doc/Makefile.am
index c6fc1c9..ef7c23d 100644
--- a/hw/dmx/doc/Makefile.am
+++ b/hw/dmx/doc/Makefile.am
@@ -33,19 +33,19 @@ SUFFIXES = .sgml .txt .html .ps .pdf
 
 .sgml.txt:
 	@rm -f $@
-	$(MAKE_TEXT) $<
+	$(AM_V_GEN)$(MAKE_TEXT) $<
 
 .sgml.ps:
 	@rm -f $@
-	$(MAKE_PS) $<
+	$(AM_V_GEN)$(MAKE_PS) $<
 
 .ps.pdf:
 	@rm -f $@
-	$(MAKE_PDF) $<
+	$(AM_V_GEN)$(MAKE_PDF) $<
 
 .sgml.html:
 	@rm -f $@
-	$(MAKE_HTML) $<
+	$(AM_V_GEN)$(MAKE_HTML) $<
 
 noinst_DATA = $(TXT_FILES) $(PS_FILES) $(PDF_FILES) $(HTML_FILES)
 CLEANFILES = $(TXT_FILES) $(PS_FILES) $(PDF_FILES) $(HTML_FILES)
commit 3ba2ce5d1054c99354686aeb373247f1b9debf79
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Thu Mar 25 03:33:55 2010 -0500

    dmx: Ignore linuxdoc generated docs
    
    dmx.txt and scaled.txt are generated from SGML, so they probably never
    should have been in version control in the first place.
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Acked-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Dan Nicholson <dbn.lists at gmail.com>

diff --git a/hw/dmx/doc/.gitignore b/hw/dmx/doc/.gitignore
index 5bfaef3..6bdd862 100644
--- a/hw/dmx/doc/.gitignore
+++ b/hw/dmx/doc/.gitignore
@@ -1,2 +1,10 @@
 #		Add & Override for this directory and it's subdirectories
 html/
+dmx.html
+dmx.pdf
+dmx.ps
+dmx.txt
+scaled.html
+scaled.pdf
+scaled.ps
+scaled.txt
diff --git a/hw/dmx/doc/dmx.txt b/hw/dmx/doc/dmx.txt
deleted file mode 100644
index 568c751..0000000
--- a/hw/dmx/doc/dmx.txt
+++ /dev/null
@@ -1,2989 +0,0 @@
-  Distributed Multihead X design
-  Kevin E. Martin, David H. Dawes, and Rickard E. Faith
-
-  29 June 2004 (created 25 July 2001)
-
-  This document covers the motivation, background, design, and implemen-
-  tation of the distributed multihead X (DMX) system.  It is a living
-  document and describes the current design and implementation details
-  of the DMX system.  As the project progresses, this document will be
-  continually updated to reflect the changes in the code and/or design.
-  _C_o_p_y_r_i_g_h_t _2_0_0_1 _b_y _V_A _L_i_n_u_x _S_y_s_t_e_m_s_, _I_n_c_._, _F_r_e_m_o_n_t_, _C_a_l_i_f_o_r_n_i_a_.  _C_o_p_y_-
-  _r_i_g_h_t _2_0_0_1_-_2_0_0_4 _b_y _R_e_d _H_a_t_, _I_n_c_._, _R_a_l_e_i_g_h_, _N_o_r_t_h _C_a_r_o_l_i_n_a
-
-  ______________________________________________________________________
-
-  Table of Contents
-
-
-
-  1. Introduction
-     1.1 The Distributed Multihead X Server
-     1.2 Layout of Paper
-
-  2. Development plan
-     2.1 Bootstrap code
-     2.2 Input device handling
-     2.3 Output device handling
-        2.3.1 Initialization
-        2.3.2 Handling rendering requests
-     2.4 Optimizing DMX
-     2.5 DMX X extension support
-     2.6 Common X extension support
-     2.7 OpenGL support
-
-  3. Current issues
-     3.1 Fonts
-     3.2 Zero width rendering primitives
-     3.3 Output scaling
-     3.4 Per-screen colormaps
-
-  A. Background
-     A.1 Core input device handling
-        A.1.1 InitInput()
-        A.1.2 InitAndStartDevices()
-        A.1.3 devReadInput()
-        A.1.4 ProcessInputEvents()
-        A.1.5 DisableDevice()
-        A.1.6 CloseDevice()
-        A.1.7 LegalModifier()
-     A.2 Output handling
-        A.2.1 InitOutput()
-        A.2.2 AddScreen()
-        A.2.3 ScreenInit()
-        A.2.4 CloseScreen()
-        A.2.5 GC operations
-        A.2.6 Xnest
-        A.2.7 Shadow framebuffer
-     A.3 Xinerama
-        A.3.1 Xinerama-specific changes to the DIX code
-        A.3.2 Xinerama-specific changes to the MI code
-        A.3.3 Intercepted DIX core requests
-
-  B. Development Results
-     B.1 Phase I
-        B.1.1 Scope
-        B.1.2 Results
-        B.1.3 X Test Suite
-           B.1.3.1 Introduction
-           B.1.3.2 Expected Failures for a Single Head
-           B.1.3.3 Expected Failures for Xinerama
-           B.1.3.4 Additional Failures from Xdmx
-           B.1.3.5 Summary and Future Work
-        B.1.4 Fonts
-        B.1.5 Performance
-        B.1.6 Pixmaps
-     B.2 Phase II
-        B.2.1 Moving from XFree86 4.1.99.1 to 4.2.0.0
-        B.2.2 Global changes
-        B.2.3 XSync() Batching
-        B.2.4 Offscreen Optimization
-        B.2.5 Lazy Window Creation Optimization
-        B.2.6 Subdividing Rendering Primitives
-        B.2.7 Summary of x11perf Data
-        B.2.8 Profiling with OProfile
-        B.2.9 X Test Suite
-     B.3 Phase III
-        B.3.1 SHAPE
-        B.3.2 RENDER
-        B.3.3 XKEYBOARD
-        B.3.4 XInput
-        B.3.5 DPMS
-        B.3.6 Other Extensions
-     B.4 Phase IV
-        B.4.1 Moving to XFree86 4.3.0
-        B.4.2 Extensions
-           B.4.2.1 XC-MISC (supported)
-           B.4.2.2 Extended-Visual-Information (supported)
-           B.4.2.3 RES (supported)
-           B.4.2.4 BIG-REQUESTS (supported)
-           B.4.2.5 XSYNC (supported)
-           B.4.2.6 XTEST, RECORD, DEC-XTRAP (supported) and XTestExtension1 (not supported)
-           B.4.2.7 MIT-MISC (not supported)
-           B.4.2.8 SCREENSAVER (not supported)
-           B.4.2.9 GLX (supported)
-           B.4.2.10 RENDER (supported)
-           B.4.2.11 Summary
-        B.4.3 Additional Testing with the X Test Suite
-           B.4.3.1 XFree86 without XTEST
-           B.4.3.2 XFree86 with XTEST
-           B.4.3.3 Xdmx with XTEST, without Xinerama, without GLX
-           B.4.3.4 Xdmx with XTEST, with Xinerama, without GLX
-           B.4.3.5 Xdmx with XTEST, with Xinerama, with GLX
-           B.4.3.6 Conclusion
-        B.4.4 Dynamic Reconfiguration
-           B.4.4.1 Dynamic reconfiguration extension
-           B.4.4.2 Bounding box
-           B.4.4.3 Sample applications
-           B.4.4.4 Additional notes
-        B.4.5 Doxygen documentation
-        B.4.6 Valgrind
-        B.4.7 RATS
-
-
-  ______________________________________________________________________
-
-  11..  IInnttrroodduuccttiioonn
-
-  11..11..  TThhee DDiissttrriibbuutteedd MMuullttiihheeaadd XX SSeerrvveerr
-
-  Current Open Source multihead solutions are limited to a single
-  physical machine.  A single X server controls multiple display
-  devices, which can be arranged as independent heads or unified into a
-  single desktop (with Xinerama).  These solutions are limited to the
-  number of physical devices that can co-exist in a single machine
-  (e.g., due to the number of AGP/PCI slots available for graphics
-  cards).  Thus, large tiled displays are not currently possible.  The
-  work described in this paper will eliminate the requirement that the
-  display devices reside in the same physical machine.  This will be
-  accomplished by developing a front-end proxy X server that will
-  control multiple back-end X servers that make up the large display.
-
-
-  The overall structure of the distributed multihead X (DMX) project is
-  as follows: A single front-end X server will act as a proxy to a set
-  of back-end X servers, which handle all of the visible rendering.  X
-  clients will connect to the front-end server just as they normally
-  would to a regular X server.  The front-end server will present an
-  abstracted view to the client of a single large display.  This will
-  ensure that all standard X clients will continue to operate without
-  modification (limited, as always, by the visuals and extensions
-  provided by the X server).  Clients that are DMX-aware will be able to
-  use an extension to obtain information about the back-end servers
-  (e.g., for placement of pop-up windows, window alignments by the
-  window manager, etc.).
-
-
-  The architecture of the DMX server is divided into two main sections:
-  input (e.g., mouse and keyboard events) and output (e.g., rendering
-  and windowing requests).  Each of these are describe briefly below,
-  and the rest of this design document will describe them in greater
-  detail.
-
-
-  The DMX server can receive input from three general types of input
-  devices: "local" devices that are physically attached to the machine
-  on which DMX is running, "backend" devices that are physically
-  attached to one or more of the back-end X servers (and that generate
-  events via the X protocol stream from the backend), and "console"
-  devices that can be abstracted from any non-back-end X server.
-  Backend and console devices are treated differently because the
-  pointer device on the back-end X server also controls the location of
-  the hardware X cursor.  Full support for XInput extension devices is
-  provided.
-
-
-  Rendering requests will be accepted by the front-end server; however,
-  rendering to visible windows will be broken down as needed and sent to
-  the appropriate back-end server(s) via X11 library calls for actual
-  rendering.  The basic framework will follow a Xnest-style approach.
-  GC state will be managed in the front-end server and sent to the
-  appropriate back-end server(s) as required.  Pixmap rendering will (at
-  least initially) be handled by the front-end X server.  Windowing
-  requests (e.g., ordering, mapping, moving, etc.) will handled in the
-  front-end server.  If the request requires a visible change, the
-  windowing operation will be translated into requests for the
-  appropriate back-end server(s).  Window state will be mirrored in the
-  back-end server(s) as needed.
-
-
-  11..22..  LLaayyoouutt ooff PPaappeerr
-
-  The next section describes the general development plan that was
-  actually used for implementation.  The final section discusses
-  outstanding issues at the conclusion of development.  The first
-  appendix provides low-level technical detail that may be of interest
-  to those intimately familiar with the X server architecture.  The
-  final appendix describes the four phases of development that were
-  performed during the first two years of development.
-
-
-  The final year of work was divided into 9 tasks that are not described
-  in specific sections of this document.  The major tasks during that
-  time were the enhancement of the reconfiguration ability added in
-  Phase IV, addition of support for a dynamic number of back-end
-  displays (instead of a hard-coded limit), and the support for back-end
-  display and input removal and addition.  This work is mentioned in
-  this paper, but is not covered in detail.
-
-
-  22..  DDeevveellooppmmeenntt ppllaann
-
-  This section describes the development plan from approximately June
-  2001 through July 2003.
-
-
-
-  22..11..  BBoooottssttrraapp ccooddee
-
-  To allow for rapid development of the DMX server by multiple
-  developers during the first development stage, the problem will be
-  broken down into three tasks: the overall DMX framework, back-end
-  rendering services and input device handling services.  However,
-  before the work begins on these tasks, a simple framework that each
-  developer could use was implemented to bootstrap the development
-  effort.  This framework renders to a single back-end server and
-  provides dummy input devices (i.e., the keyboard and mouse).  The
-  simple back-end rendering service was implemented using the shadow
-  framebuffer support currently available in the XFree86 environment.
-
-
-  Using this bootstrapping framework, each developer has been able to
-  work on each of the tasks listed above independently as follows: the
-  framework will be extended to handle arbitrary back-end server
-  configurations; the back-end rendering services will be transitioned
-  to the more efficient Xnest-style implementation; and, an input device
-  framework to handle various input devices via the input extension will
-  be developed.
-
-
-  Status: The boot strap code is complete.
-
-
-
-  22..22..  IInnppuutt ddeevviiccee hhaannddlliinngg
-
-  An X server (including the front-end X server) requires two core input
-  devices -- a keyboard and a pointer (mouse).  These core devices are
-  handled and required by the core X11 protocol.  Additional types of
-  input devices may be attached and utilized via the XInput extension.
-  These are usually referred to as ``XInput extension devices'',
-
-
-  There are some options as to how the front-end X server gets its core
-  input devices:
-
-
-  1. Local Input. The physical input devices (e.g., keyboard and mouse)
-     can be attached directly to the front-end X server.  In this case,
-     the keyboard and mouse on the machine running the front-end X
-     server will be used.  The front-end will have drivers to read the
-     raw input from those devices and convert it into the required X
-     input events (e.g., key press/release, pointer button
-     press/release, pointer motion).  The front-end keyboard driver will
-     keep track of keyboard properties such as key and modifier
-     mappings, autorepeat state, keyboard sound and led state.
-     Similarly the front-end pointer driver will keep track if pointer
-     properties such as the button mapping and movement acceleration
-     parameters.  With this option, input is handled fully in the front-
-     end X server, and the back-end X servers are used in a display-only
-     mode.  This option was implemented and works for a limited number
-     of Linux-specific devices.  Adding additional local input devices
-     for other architectures is expected to be relatively simple.
-
-
-     The following options are available for implementing local input
-     devices:
-
-
-     a. The XFree86 X server has modular input drivers that could be
-        adapted for this purpose.  The mouse driver supports a wide
-        range of mouse types and interfaces, as well as a range of
-        Operating System platforms.  The keyboard driver in XFree86 is
-        not currently as modular as the mouse driver, but could be made
-        so.  The XFree86 X server also has a range of other input
-        drivers for extended input devices such as tablets and touch
-        screens.  Unfortunately, the XFree86 drivers are generally
-        complex, often simultaneously providing support for multiple
-        devices across multiple architectures; and rely so heavily on
-        XFree86-specific helper-functions, that this option was not
-        pursued.
-
-
-     b. The kdrive X server in XFree86 has built-in drivers that support
-        PS/2 mice and keyboard under Linux.  The mouse driver can
-        indirectly handle other mouse types if the Linux utility gpm is
-        used as to translate the native mouse protocol into PS/2 mouse
-        format.  These drivers could be adapted and built in to the
-        front-end X server if this range of hardware and OS support is
-        sufficient.  While much simpler than the XFree86 drivers, the
-        kdrive drivers were not used for the DMX implementation.
-
-     c. Reimplementation of keyboard and mouse drivers from scratch for
-        the DMX framework.  Because keyboard and mouse drivers are
-        relatively trivial to implement, this pathway was selected.
-        Other drivers in the X source tree were referenced, and
-        significant contributions from other drivers are noted in the
-        DMX source code.
-
-
-  2. Backend Input.  The front-end can make use of the core input
-     devices attached to one or more of the back-end X servers.  Core
-     input events from multiple back-ends are merged into a single input
-     event stream.  This can work sanely when only a single set of input
-     devices is used at any given time.  The keyboard and pointer state
-     will be handled in the front-end, with changes propagated to the
-     back-end servers as needed.  This option was implemented and works
-     well.  Because the core pointer on a back-end controls the hardware
-     mouse on that back-end, core pointers cannot be treated as XInput
-     extension devices.  However, all back-end XInput extensions devices
-     can be mapped to either DMX core or DMX XInput extension devices.
-
-  3. Console Input.  The front-end server could create a console window
-     that is displayed on an X server independent of the back-end X
-     servers.  This console window could display things like the
-     physical screen layout, and the front-end could get its core input
-     events from events delivered to the console window.  This option
-     was implemented and works well.  To help the human navigate, window
-     outlines are also displayed in the console window.  Further,
-     console windows can be used as either core or XInput extension
-     devices.
-
-  4. Other options were initially explored, but they were all partial
-     subsets of the options listed above and, hence, are irrelevant.
-
-
-  Although extended input devices are not specifically mentioned in the
-  Distributed X requirements, the options above were all implemented so
-  that XInput extension devices were supported.
-
-
-  The bootstrap code (Xdmx) had dummy input devices, and these are still
-  supported in the final version.  These do the necessary initialization
-  to satisfy the X server's requirements for core pointer and keyboard
-  devices, but no input events are ever generated.
-
-
-  Status: The input code is complete.  Because of the complexity of the
-  XFree86 input device drivers (and their heavy reliance on XFree86
-  infrastructure), separate low-level device drivers were implemented
-  for Xdmx.  The following kinds of drivers are supported (in general,
-  the devices can be treated arbitrarily as "core" input devices or as
-  XInput "extension" devices; and multiple instances of different kinds
-  of devices can be simultaneously available):
-
-  1. A "dummy" device drive that never generates events.
-
-  2. "Local" input is from the low-level hardware on which the Xdmx
-     binary is running.  This is the only area where using the XFree86
-     driver infrastructure would have been helpful, and then only
-     partially, since good support for generic USB devices does not yet
-     exist in XFree86 (in any case, XFree86 and kdrive driver code was
-     used where possible).  Currently, the following local devices are
-     supported under Linux (porting to other operating systems should be
-     fairly straightforward):
-
-     +o  Linux keyboard
-
-     +o  Linux serial mouse (MS)
-
-     +o  Linux PS/2 mouse
-
-     +o  USB keyboard
-
-     +o  USB mouse
-
-     +o  USB generic device (e.g., joystick, gamepad, etc.)
-
-
-  3. "Backend" input is taken from one or more of the back-end displays.
-     In this case, events are taken from the back-end X server and are
-     converted to Xdmx events.  Care must be taken so that the sprite
-     moves properly on the display from which input is being taken.
-
-  4. "Console" input is taken from an X window that Xdmx creates on the
-     operator's display (i.e., on the machine running the Xdmx binary).
-     When the operator's mouse is inside the console window, then those
-     events are converted to Xdmx events.  Several special features are
-     available: the console can display outlines of windows that are on
-     the Xdmx display (to facilitate navigation), the cursor can be
-     confined to the console, and a "fine" mode can be activated to
-     allow very precise cursor positioning.
-
-
-
-  22..33..  OOuuttppuutt ddeevviiccee hhaannddlliinngg
-
-  The output of the DMX system displays rendering and windowing requests
-  across multiple screens.  The screens are typically arranged in a grid
-  such that together they represent a single large display.
-
-
-  The output section of the DMX code consists of two parts.  The first
-  is in the front-end proxy X server (Xdmx), which accepts client
-  connections, manages the windows, and potentially renders primitives
-  but does not actually display any of the drawing primitives.  The
-  second part is the back-end X server(s), which accept commands from
-  the front-end server and display the results on their screens.
-
-
-  22..33..11..  IInniittiiaalliizzaattiioonn
-
-  The DMX front-end must first initialize its screens by connecting to
-  each of the back-end X servers and collecting information about each
-  of these screens.  However, the information collected from the back-
-  end X servers might be inconsistent.  Handling these cases can be
-  difficult and/or inefficient.  For example, a two screen system has
-  one back-end X server running at 16bpp while the second is running at
-  32bpp.  Converting rendering requests (e.g., XPutImage() or
-  XGetImage() requests) to the appropriate bit depth can be very time
-  consuming.  Analyzing these cases to determine how or even if it is
-  possible to handle them is required.  The current Xinerama code
-  handles many of these cases (e.g., in PanoramiXConsolidate()) and will
-  be used as a starting point.  In general, the best solution is to use
-  homogeneous X servers and display devices.  Using back-end servers
-  with the same depth is a requirement of the final DMX implementation.
-
-
-  Once this screen consolidation is finished, the relative position of
-  each back-end X server's screen in the unified screen is initialized.
-  A full-screen window is opened on each of the back-end X servers, and
-  the cursor on each screen is turned off.  The final DMX implementation
-  can also make use of a partial-screen window, or multiple windows per
-  back-end screen.
-
-
-  22..33..22..  HHaannddlliinngg rreennddeerriinngg rreeqquueessttss
-
-  After initialization, X applications connect to the front-end server.
-  There are two possible implementations of how rendering and windowing
-  requests are handled in the DMX system:
-
-
-  1. A shadow framebuffer is used in the front-end server as the render
-     target.  In this option, all protocol requests are completely
-     handled in the front-end server.  All state and resources are
-     maintained in the front-end including a shadow copy of the entire
-     framebuffer.  The framebuffers attached to the back-end servers are
-     updated by XPutImage() calls with data taken directly from the
-     shadow framebuffer.
-
-
-     This solution suffers from two main problems.  First, it does not
-     take advantage of any accelerated hardware available in the system.
-     Second, the size of the XPutImage() calls can be quite large and
-     thus will be limited by the bandwidth available.
-
-
-     The initial DMX implementation used a shadow framebuffer by
-     default.
-
-
-  2. Rendering requests are sent to each back-end server for handling
-     (as is done in the Xnest server described above).  In this option,
-     certain protocol requests are handled in the front-end server and
-     certain requests are repackaged and then sent to the back-end
-     servers.  The framebuffer is distributed across the multiple back-
-     end servers.  Rendering to the framebuffer is handled on each back-
-     end and can take advantage of any acceleration available on the
-     back-end servers' graphics display device.  State is maintained
-     both in the front and back-end servers.
-
-
-     This solution suffers from two main drawbacks.  First, protocol
-     requests are sent to all back-end servers -- even those that will
-     completely clip the rendering primitive -- which wastes bandwidth
-     and processing time.  Second, state is maintained both in the
-     front- and back-end servers.  These drawbacks are not as severe as
-     in option 1 (above) and can either be overcome through
-     optimizations or are acceptable.  Therefore, this option will be
-     used in the final implementation.
-
-
-     The final DMX implementation defaults to this mechanism, but also
-     supports the shadow framebuffer mechanism.  Several optimizations
-     were implemented to eliminate the drawbacks of the default
-     mechanism.  These optimizations are described the section below and
-     in Phase II of the Development Results (see appendix).
-
-
-
-  Status: Both the shadow framebuffer and Xnest-style code is complete.
-
-
-
-  22..44..  OOppttiimmiizziinngg DDMMXX
-
-  Initially, the Xnest-style solution's performance will be measured and
-  analyzed to determine where the performance bottlenecks exist.  There
-  are four main areas that will be addressed.
-
-
-  First, to obtain reasonable interactivity with the first development
-  phase, XSync() was called after each protocol request.  The XSync()
-  function flushes any pending protocol requests.  It then waits for the
-  back-end to process the request and send a reply that the request has
-  completed.  This happens with each back-end server and performance
-  greatly suffers.  As a result of the way XSync() is called in the
-  first development phase, the batching that the X11 library performs is
-  effectively defeated.  The XSync() call usage will be analyzed and
-  optimized by batching calls and performing them at regular intervals,
-  except where interactivity will suffer (e.g., on cursor movements).
-
-
-  Second, the initial Xnest-style solution described above sends the
-  repackaged protocol requests to all back-end servers regardless of
-  whether or not they would be completely clipped out.  The requests
-  that are trivially rejected on the back-end server wastes the limited
-  bandwidth available.  By tracking clipping changes in the DMX X
-  server's windowing code (e.g., by opening, closing, moving or resizing
-  windows), we can determine whether or not back-end windows are visible
-  so that trivial tests in the front-end server's GC ops drawing
-  functions can eliminate these unnecessary protocol requests.
-
-
-  Third, each protocol request will be analyzed to determine if it is
-  possible to break the request into smaller pieces at display
-  boundaries.  The initial ones to be analyzed are put and get image
-  requests since they will require the greatest bandwidth to transmit
-  data between the front and back-end servers.  Other protocol requests
-  will be analyzed and those that will benefit from breaking them into
-  smaller requests will be implemented.
-
-
-  Fourth, an extension is being considered that will allow font glyphs
-  to be transferred from the front-end DMX X server to each back-end
-  server.  This extension will permit the front-end to handle all font
-  requests and eliminate the requirement that all back-end X servers
-  share the exact same fonts as the front-end server.  We are
-  investigating the feasibility of this extension during this
-  development phase.
-
-
-  Other potential optimizations will be determined from the performance
-  analysis.
-
-  Please note that in our initial design, we proposed optimizing BLT
-  operations (e.g., XCopyArea() and window moves) by developing an
-  extension that would allow individual back-end servers to directly
-  copy pixel data to other back-end servers.  This potential
-  optimization was in response to the simple image movement
-  implementation that required potentially many calls to GetImage() and
-  PutImage().  However, the current Xinerama implementation handles
-  these BLT operations differently.  Instead of copying data to and from
-  screens, they generate expose events -- just as happens in the case
-  when a window is moved from off a screen to on screen.  This approach
-  saves the limited bandwidth available between front and back-end
-  servers and is being standardized with Xinerama.  It also eliminates
-  the potential setup problems and security issues resulting from having
-  each back-end server open connections to all other back-end servers.
-  Therefore, we suggest accepting Xinerama's expose event solution.
-
-
-  Also note that the approach proposed in the second and third
-  optimizations might cause backing store algorithms in the back-end to
-  be defeated, so a DMX X server configuration flag will be added to
-  disable these optimizations.
-
-
-  Status: The optimizations proposed above are complete.  It was
-  determined that the using the xfs font server was sufficient and
-  creating a new mechanism to pass glyphs was redundant; therefore, the
-  fourth optimization proposed above was not included in DMX.
-
-
-
-  22..55..  DDMMXX XX eexxtteennssiioonn ssuuppppoorrtt
-
-  The DMX X server keeps track of all the windowing information on the
-  back-end X servers, but does not currently export this information to
-  any client applications.  An extension will be developed to pass the
-  screen information and back-end window IDs to DMX-aware clients.
-  These clients can then use this information to directly connect to and
-  render to the back-end windows.  Bypassing the DMX X server allows
-  DMX-aware clients to break up complex rendering requests on their own
-  and send them directly to the windows on the back-end server's
-  screens.  An example of a client that can make effective use of this
-  extension is Chromium.
-
-
-  Status: The extension, as implemented, is fully documented in "Client-
-  to-Server DMX Extension to the X Protocol".  Future changes might be
-  required based on feedback and other proposed enhancements to DMX.
-  Currently, the following facilities are supported:
-
-  1. Screen information (clipping rectangle for each screen relative to
-     the virtual screen)
-
-  2. Window information (window IDs and clipping information for each
-     back-end window that corresponds to each DMX window)
-
-  3. Input device information (mappings from DMX device IDs to back-end
-     device IDs)
-
-  4. Force window creation (so that a client can override the server-
-     side lazy window creation optimization)
-
-  5. Reconfiguration (so that a client can request that a screen
-     position be changed)
-
-  6. Addition and removal of back-end servers and back-end and console
-     inputs.
-  22..66..  CCoommmmoonn XX eexxtteennssiioonn ssuuppppoorrtt
-
-  The XInput, XKeyboard and Shape extensions are commonly used
-  extensions to the base X11 protocol.  XInput allows multiple and non-
-  standard input devices to be accessed simultaneously.  These input
-  devices can be connected to either the front-end or back-end servers.
-  XKeyboard allows much better keyboard mappings control.  Shape adds
-  support for arbitrarily shaped windows and is used by various window
-  managers.  Nearly all potential back-end X servers make these
-  extensions available, and support for each one will be added to the
-  DMX system.
-
-
-  In addition to the extensions listed above, support for the X
-  Rendering extension (Render) is being developed.  Render adds digital
-  image composition to the rendering model used by the X Window System.
-  While this extension is still under development by Keith Packard of
-  HP, support for the current version will be added to the DMX system.
-
-
-  Support for the XTest extension was added during the first development
-  phase.
-
-
-  Status: The following extensions are supported and are discussed in
-  more detail in Phase IV of the Development Results (see appendix):
-  BIG-REQUESTS, DEC-XTRAP, DMX, DPMS, Extended-Visual-Information, GLX,
-  LBX, RECORD, RENDER, SECURITY, SHAPE, SYNC, X-Resource, XC-APPGROUP,
-  XC-MISC, XFree86-Bigfont, XINERAMA, XInputExtension, XKEYBOARD, and
-  XTEST.
-
-
-  22..77..  OOppeennGGLL ssuuppppoorrtt
-
-  OpenGL support using the Mesa code base exists in XFree86 release 4
-  and later.  Currently, the direct rendering infrastructure (DRI)
-  provides accelerated OpenGL support for local clients and
-  unaccelerated OpenGL support (i.e., software rendering) is provided
-  for non-local clients.
-
-
-  The single head OpenGL support in XFree86 4.x will be extended to use
-  the DMX system.  When the front and back-end servers are on the same
-  physical hardware, it is possible to use the DRI to directly render to
-  the back-end servers.  First, the existing DRI will be extended to
-  support multiple display heads, and then to support the DMX system.
-  OpenGL rendering requests will be direct rendering to each back-end X
-  server.  The DRI will request the screen layout (either from the
-  existing Xinerama extension or a DMX-specific extension).  Support for
-  synchronized swap buffers will also be added (on hardware that
-  supports it).  Note that a single front-end server with a single back-
-  end server on the same physical machine can emulate accelerated
-  indirect rendering.
-
-
-  When the front and back-end servers are on different physical hardware
-  or are using non-XFree86 4.x X servers, a mechanism to render
-  primitives across the back-end servers will be provided.  There are
-  several options as to how this can be implemented.
-
-
-  1. The existing OpenGL support in each back-end server can be used by
-     repackaging rendering primitives and sending them to each back-end
-     server.  This option is similar to the unoptimized Xnest-style
-     approach mentioned above.  Optimization of this solution is beyond
-     the scope of this project and is better suited to other distributed
-     rendering systems.
-
-  2. Rendering to a pixmap in the front-end server using the current
-     XFree86 4.x code, and then displaying to the back-ends via calls to
-     XPutImage() is another option.  This option is similar to the
-     shadow frame buffer approach mentioned above.  It is slower and
-     bandwidth intensive, but has the advantage that the back-end
-     servers are not required to have OpenGL support.
-
-
-  These, and other, options will be investigated in this phase of the
-  work.
-
-
-  Work by others have made Chromium DMX-aware.  Chromium will use the
-  DMX X protocol extension to obtain information about the back-end
-  servers and will render directly to those servers, bypassing DMX.
-
-
-  Status: OpenGL support by the glxProxy extension was implemented by
-  SGI and has been integrated into the DMX code base.
-
-
-
-  33..  CCuurrrreenntt iissssuueess
-
-  In this sections the current issues are outlined that require further
-  investigation.
-
-
-  33..11..  FFoonnttss
-
-  The font path and glyphs need to be the same for the front-end and
-  each of the back-end servers.  Font glyphs could be sent to the back-
-  end servers as necessary but this would consume a significant amount
-  of available bandwidth during font rendering for clients that use many
-  different fonts (e.g., Netscape).  Initially, the font server (xfs)
-  will be used to provide the fonts to both the front-end and back-end
-  servers.  Other possibilities will be investigated during development.
-
-
-  33..22..  ZZeerroo wwiiddtthh rreennddeerriinngg pprriimmiittiivveess
-
-  To allow pixmap and on-screen rendering to be pixel perfect, all back-
-  end servers must render zero width primitives exactly the same as the
-  front-end renders the primitives to pixmaps.  For those back-end
-  servers that do not exactly match, zero width primitives will be
-  automatically converted to one width primitives.  This can be handled
-  in the front-end server via the GC state.
-
-
-  33..33..  OOuuttppuutt ssccaalliinngg
-
-  With very large tiled displays, it might be difficult to read the
-  information on the standard X desktop.  In particular, the cursor can
-  be easily lost and fonts could be difficult to read.  Automatic
-  primitive scaling might prove to be very useful.  We will investigate
-  the possibility of scaling the cursor and providing a set of alternate
-  pre-scaled fonts to replace the standard fonts that many applications
-  use (e.g., fixed).  Other options for automatic scaling will also be
-  investigated.
-
-
-
-  33..44..  PPeerr--ssccrreeeenn ccoolloorrmmaappss
-
-  Each screen's default colormap in the set of back-end X servers should
-  be able to be adjusted via a configuration utility.  This support is
-  would allow the back-end screens to be calibrated via custom gamma
-  tables.  On 24-bit systems that support a DirectColor visual, this
-  type of correction can be accommodated.  One possible implementation
-  would be to advertise to X client of the DMX server a TrueColor visual
-  while using DirectColor visuals on the back-end servers to implement
-  this type of color correction.  Other options will be investigated.
-
-
-  AA..  BBaacckkggrroouunndd
-
-  This section describes the existing Open Source architectures that can
-  be used to handle multiple screens and upon which this development
-  project is based.  This section was written before the implementation
-  was finished, and may not reflect actual details of the
-  implementation.  It is left for historical interest only.
-
-
-  AA..11..  CCoorree iinnppuutt ddeevviiccee hhaannddlliinngg
-
-  The following is a description of how core input devices are handled
-  by an X server.
-
-
-  AA..11..11..  IInniittIInnppuutt(())
-
-  InitInput() is a DDX function that is called at the start of each
-  server generation from the X server's main() function.  Its purpose is
-  to determine what input devices are connected to the X server,
-  register them with the DIX and MI layers, and initialize the input
-  event queue.  InitInput() does not have a return value, but the X
-  server will abort if either a core keyboard device or a core pointer
-  device are not registered.  Extended input (XInput) devices can also
-  be registered in InitInput().
-
-
-  InitInput() usually has implementation specific code to determine
-  which input devices are available.  For each input device it will be
-  using, it calls AddInputDevice():
-
-
-     AAddddIInnppuuttDDeevviiccee(())
-        This DIX function allocates the device structure, registers a
-        callback function (which handles device init, close, on and
-        off), and returns the input handle, which can be treated as
-        opaque.  It is called once for each input device.
-
-
-  Once input handles for core keyboard and core pointer devices have
-  been obtained from AddInputDevice(), they are registered as core
-  devices by calling RegisterPointerDevice() and
-  RegisterKeyboardDevice().  Each of these should be called once.  If
-  both core devices are not registered, then the X server will exit with
-  a fatal error when it attempts to start the input devices in
-  InitAndStartDevices(), which is called directly after InitInput() (see
-  below).
-
-
-     RReeggiisstteerr{{PPooiinntteerr,,KKeeyybbooaarrdd}}DDeevviiccee(())
-        These DIX functions take a handle returned from AddInputDevice()
-        and initialize the core input device fields in inputInfo, and
-        initialize the input processing and grab functions for each core
-        input device.
-  The core pointer device is then registered with the miPointer code
-  (which does the high level cursor handling).  While this registration
-  is not necessary for correct miPointer operation in the current
-  XFree86 code, it is still done mostly for compatibility reasons.
-
-
-     mmiiRReeggiisstteerrPPooiinntteerrDDeevviiccee(())
-        This MI function registers the core pointer's input handle with
-        with the miPointer code.
-
-
-  The final part of InitInput() is the initialization of the input event
-  queue handling.  In most cases, the event queue handling provided in
-  the MI layer is used.  The primary XFree86 X server uses its own event
-  queue handling to support some special cases related to the XInput
-  extension and the XFree86-specific DGA extension.  For our purposes,
-  the MI event queue handling should be suitable.  It is initialized by
-  calling mieqInit():
-
-
-     mmiieeqqIInniitt(())
-        This MI function initializes the MI event queue for the core
-        devices, and is passed the public component of the input handles
-        for the two core devices.
-
-
-  If a wakeup handler is required to deliver synchronous input events,
-  it can be registered here by calling the DIX function
-  RegisterBlockAndWakeupHandlers().  (See the devReadInput() description
-  below.)
-
-
-  AA..11..22..  IInniittAAnnddSSttaarrttDDeevviicceess(())
-
-  InitAndStartDevices() is a DIX function that is called immediately
-  after InitInput() from the X server's main() function.  Its purpose is
-  to initialize each input device that was registered with
-  AddInputDevice(), enable each input device that was successfully
-  initialized, and create the list of enabled input devices.  Once each
-  registered device is processed in this way, the list of enabled input
-  devices is checked to make sure that both a core keyboard device and
-  core pointer device were registered and successfully enabled.  If not,
-  InitAndStartDevices() returns failure, and results in the the X server
-  exiting with a fatal error.
-
-
-  Each registered device is initialized by calling its callback
-  (dev->deviceProc) with the DEVICE_INIT argument:
-
-
-     ((**ddeevv-->>ddeevviicceePPrroocc))((ddeevv,, DDEEVVIICCEE__IINNIITT))
-        This function initializes the device structs with core
-        information relevant to the device.
-
-
-        For pointer devices, this means specifying the number of
-        buttons, default button mapping, the function used to get motion
-        events (usually miPointerGetMotionEvents()), the function used
-        to change/control the core pointer motion parameters
-        (acceleration and threshold), and the motion buffer size.
-
-
-        For keyboard devices, this means specifying the keycode range,
-        default keycode to keysym mapping, default modifier mapping, and
-        the functions used to sound the keyboard bell and modify/control
-        the keyboard parameters (LEDs, bell pitch and duration, key
-        click, which keys are auto-repeating, etc).
-
-
-  Each initialized device is enabled by calling EnableDevice():
-
-
-     EEnnaabblleeDDeevviiccee(())
-        EnableDevice() calls the device callback with DEVICE_ON:
-
-        ((**ddeevv-->>ddeevviicceePPrroocc))((ddeevv,, DDEEVVIICCEE__OONN))
-           This typically opens and initializes the relevant physical
-           device, and when appropriate, registers the device's file
-           descriptor (or equivalent) as a valid input source.
-
-
-        EnableDevice() then adds the device handle to the X server's
-        global list of enabled devices.
-
-
-  InitAndStartDevices() then verifies that a valid core keyboard and
-  pointer has been initialized and enabled.  It returns failure if
-  either are missing.
-
-
-  AA..11..33..  ddeevvRReeaaddIInnppuutt(())
-
-  Each device will have some function that gets called to read its
-  physical input.  These may be called in a number of different ways.
-  In the case of synchronous I/O, they will be called from a DDX wakeup-
-  handler that gets called after the server detects that new input is
-  available.  In the case of asynchronous I/O, they will be called from
-  a (SIGIO) signal handler triggered when new input is available.  This
-  function should do at least two things: make sure that input events
-  get enqueued, and make sure that the cursor gets moved for motion
-  events (except if these are handled later by the driver's own event
-  queue processing function, which cannot be done when using the MI
-  event queue handling).
-
-
-  Events are queued by calling mieqEnqueue():
-
-
-     mmiieeqqEEnnqquueeuuee(())
-        This MI function is used to add input events to the event queue.
-        It is simply passed the event to be queued.
-
-
-  The cursor position should be updated when motion events are enqueued,
-  by calling either miPointerAbsoluteCursor() or miPointerDeltaCursor():
-
-
-     mmiiPPooiinntteerrAAbbssoolluutteeCCuurrssoorr(())
-        This MI function is used to move the cursor to the absolute
-        coordinates provided.
-
-     mmiiPPooiinntteerrDDeellttaaCCuurrssoorr(())
-        This MI function is used to move the cursor relative to its
-        current position.
-
-
-  AA..11..44..  PPrroocceessssIInnppuuttEEvveennttss(())
-
-  ProcessInputEvents() is a DDX function that is called from the X
-  server's main dispatch loop when new events are available in the input
-  event queue.  It typically processes the enqueued events, and updates
-  the cursor/pointer position.  It may also do other DDX-specific event
-  processing.
-
-
-  Enqueued events are processed by mieqProcessInputEvents() and passed
-  to the DIX layer for transmission to clients:
-
-
-     mmiieeqqPPrroocceessssIInnppuuttEEvveennttss(())
-        This function processes each event in the event queue, and
-        passes it to the device's input processing function.  The DIX
-        layer provides default functions to do this processing, and they
-        handle the task of getting the events passed back to the
-        relevant clients.
-
-     mmiiPPooiinntteerrUUppddaattee(())
-        This function resynchronized the cursor position with the new
-        pointer position.  It also takes care of moving the cursor
-        between screens when needed in multi-head configurations.
-
-
-
-  AA..11..55..  DDiissaabblleeDDeevviiccee(())
-
-  DisableDevice is a DIX function that removes an input device from the
-  list of enabled devices.  The result of this is that the device no
-  longer generates input events.  The device's data structures are kept
-  in place, and disabling a device like this can be reversed by calling
-  EnableDevice().  DisableDevice() may be called from the DDX when it is
-  desirable to do so (e.g., the XFree86 server does this when VT
-  switching).  Except for special cases, this is not normally called for
-  core input devices.
-
-
-  DisableDevice() calls the device's callback function with DEVICE_OFF:
-
-
-     ((**ddeevv-->>ddeevviicceePPrroocc))((ddeevv,, DDEEVVIICCEE__OOFFFF))
-        This typically closes the relevant physical device, and when
-        appropriate, unregisters the device's file descriptor (or
-        equivalent) as a valid input source.
-
-
-  DisableDevice() then removes the device handle from the X server's
-  global list of enabled devices.
-
-
-
-  AA..11..66..  CClloosseeDDeevviiccee(())
-
-  CloseDevice is a DIX function that removes an input device from the
-  list of available devices.  It disables input from the device and
-  frees all data structures associated with the device.  This function
-  is usually called from CloseDownDevices(), which is called from main()
-  at the end of each server generation to close all input devices.
-
-
-  CloseDevice() calls the device's callback function with DEVICE_CLOSE:
-
-
-     ((**ddeevv-->>ddeevviicceePPrroocc))((ddeevv,, DDEEVVIICCEE__CCLLOOSSEE))
-        This typically closes the relevant physical device, and when
-        appropriate, unregisters the device's file descriptor (or
-        equivalent) as a valid input source.  If any device specific
-        data structures were allocated when the device was initialized,
-        they are freed here.
-
-  CloseDevice() then frees the data structures that were allocated for
-  the device when it was registered/initialized.
-
-
-
-  AA..11..77..  LLeeggaallMMooddiiffiieerr(())
-
-  LegalModifier() is a required DDX function that can be used to
-  restrict which keys may be modifier keys.  This seems to be present
-  for historical reasons, so this function should simply return TRUE
-  unconditionally.
-
-
-
-  AA..22..  OOuuttppuutt hhaannddlliinngg
-
-  The following sections describe the main functions required to
-  initialize, use and close the output device(s) for each screen in the
-  X server.
-
-
-  AA..22..11..  IInniittOOuuttppuutt(())
-
-  This DDX function is called near the start of each server generation
-  from the X server's main() function.  InitOutput()'s main purpose is
-  to initialize each screen and fill in the global screenInfo structure
-  for each screen.  It is passed three arguments: a pointer to the
-  screenInfo struct, which it is to initialize, and argc and argv from
-  main(), which can be used to determine additional configuration
-  information.
-
-
-  The primary tasks for this function are outlined below:
-
-
-  1. PPaarrssee ccoonnffiigguurraattiioonn iinnffoo:: The first task of InitOutput() is to
-     parses any configuration information from the configuration file.
-     In addition to the XF86Config file, other configuration information
-     can be taken from the command line.  The command line options can
-     be gathered either in InitOutput() or earlier in the
-     ddxProcessArgument() function, which is called by
-     ProcessCommandLine().  The configuration information determines the
-     characteristics of the screen(s).  For example, in the XFree86 X
-     server, the XF86Config file specifies the monitor information, the
-     screen resolution, the graphics devices and slots in which they are
-     located, and, for Xinerama, the screens' layout.
-
-  2. IInniittiiaalliizzee ssccrreeeenn iinnffoo:: The next task is to initialize the screen-
-     dependent internal data structures.  For example, part of what the
-     XFree86 X server does is to allocate its screen and pixmap private
-     indices, probe for graphics devices, compare the probed devices to
-     the ones listed in the XF86Config file, and add the ones that match
-     to the internal xf86Screens[] structure.
-
-  3. SSeett ppiixxmmaapp ffoorrmmaattss:: The next task is to initialize the screenInfo's
-     image byte order, bitmap bit order and bitmap scanline unit/pad.
-     The screenInfo's pixmap format's depth, bits per pixel and scanline
-     padding is also initialized at this stage.
-
-  4. UUnniiffyy ssccrreeeenn iinnffoo:: An optional task that might be done at this
-     stage is to compare all of the information from the various screens
-     and determines if they are compatible (i.e., if the set of screens
-     can be unified into a single desktop).  This task has potential to
-     be useful to the DMX front-end server, if Xinerama's
-     PanoramiXConsolidate() function is not sufficient.
-
-  Once these tasks are complete, the valid screens are known and each of
-  these screens can be initialized by calling AddScreen().
-
-
-  AA..22..22..  AAddddSSccrreeeenn(())
-
-  This DIX function is called from InitOutput(), in the DDX layer, to
-  add each new screen to the screenInfo structure.  The DDX screen
-  initialization function and command line arguments (i.e., argc and
-  argv) are passed to it as arguments.
-
-
-  This function first allocates a new Screen structure and any privates
-  that are required.  It then initializes some of the fields in the
-  Screen struct and sets up the pixmap padding information.  Finally, it
-  calls the DDX screen initialization function ScreenInit(), which is
-  described below.  It returns the number of the screen that were just
-  added, or -1 if there is insufficient memory to add the screen or if
-  the DDX screen initialization fails.
-
-
-  AA..22..33..  SSccrreeeennIInniitt(())
-
-  This DDX function initializes the rest of the Screen structure with
-  either generic or screen-specific functions (as necessary).  It also
-  fills in various screen attributes (e.g., width and height in
-  millimeters, black and white pixel values).
-
-
-  The screen init function usually calls several functions to perform
-  certain screen initialization functions.  They are described below:
-
-
-     {{mmii,,**ffbb}}SSccrreeeennIInniitt(())
-        The DDX layer's ScreenInit() function usually calls another
-        layer's ScreenInit() function (e.g., miScreenInit() or
-        fbScreenInit()) to initialize the fallbacks that the DDX driver
-        does not specifically handle.
-
-
-        After calling another layer's ScreenInit() function, any screen-
-        specific functions either wrap or replace the other layer's
-        function pointers.  If a function is to be wrapped, each of the
-        old function pointers from the other layer are stored in a
-        screen private area.  Common functions to wrap are CloseScreen()
-        and SaveScreen().
-
-
-     mmiiIInniittiiaalliizzeeBBaacckkiinnggSSttoorree(())
-        This MI function initializes the screen's backing storage
-        functions, which are used to save areas of windows that are
-        currently covered by other windows.
-
-
-     mmiiDDCCIInniittiiaalliizzee(())
-        This MI function initializes the MI cursor display structures
-        and function pointers.  If a hardware cursor is used, the DDX
-        layer's ScreenInit() function will wrap additional screen and
-        the MI cursor display function pointers.
-
-
-  Another common task for ScreenInit() function is to initialize the
-  output device state.  For example, in the XFree86 X server, the
-  ScreenInit() function saves the original state of the video card and
-  then initializes the video mode of the graphics device.
-
-  AA..22..44..  CClloosseeSSccrreeeenn(())
-
-  This function restores any wrapped screen functions (and in particular
-  the wrapped CloseScreen() function) and restores the state of the
-  output device to its original state.  It should also free any private
-  data it created during the screen initialization.
-
-
-  AA..22..55..  GGCC ooppeerraattiioonnss
-
-  When the X server is requested to render drawing primitives, it does
-  so by calling drawing functions through the graphics context's
-  operation function pointer table (i.e., the GCOps functions).  These
-  functions render the basic graphics operations such as drawing
-  rectangles, lines, text or copying pixmaps.  Default routines are
-  provided either by the MI layer, which draws indirectly through a
-  simple span interface, or by the framebuffer layers (e.g., CFB, MFB,
-  FB), which draw directly to a linearly mapped frame buffer.
-
-
-  To take advantage of special hardware on the graphics device, specific
-  GCOps functions can be replaced by device specific code.  However,
-  many times the graphics devices can handle only a subset of the
-  possible states of the GC, so during graphics context validation,
-  appropriate routines are selected based on the state and capabilities
-  of the hardware.  For example, some graphics hardware can accelerate
-  single pixel width lines with certain dash patterns.  Thus, for dash
-  patterns that are not supported by hardware or for width 2 or greater
-  lines, the default routine is chosen during GC validation.
-
-
-  Note that some pointers to functions that draw to the screen are
-  stored in the Screen structure.  They include GetImage(), GetSpans(),
-  PaintWindowBackground(), PaintWindowBorder(), CopyWindow() and
-  RestoreAreas().
-
-
-  AA..22..66..  XXnneesstt
-
-  The Xnest X server is a special proxy X server that relays the X
-  protocol requests that it receives to a ``real'' X server that then
-  processes the requests and displays the results, if applicable.  To
-  the X applications, Xnest appears as if it is a regular X server.
-  However, Xnest is both server to the X application and client of the
-  real X server, which will actually handle the requests.
-
-
-  The Xnest server implements all of the standard input and output
-  initialization steps outlined above.
-
-
-     IInniittOOuuttppuutt(())
-        Xnest takes its configuration information from command line
-        arguments via ddxProcessArguments().  This information includes
-        the real X server display to connect to, its default visual
-        class, the screen depth, the Xnest window's geometry, etc.
-        Xnest then connects to the real X server and gathers visual,
-        colormap, depth and pixmap information about that server's
-        display, creates a window on that server, which will be used as
-        the root window for Xnest.
-
-
-        Next, Xnest initializes its internal data structures and uses
-        the data from the real X server's pixmaps to initialize its own
-        pixmap formats.  Finally, it calls AddScreen(xnestOpenScreen,
-        argc, argv) to initialize each of its screens.
-     SSccrreeeennIInniitt(())
-        Xnest's ScreenInit() function is called xnestOpenScreen().  This
-        function initializes its screen's depth and visual information,
-        and then calls miScreenInit() to set up the default screen
-        functions.  It then calls miInitializeBackingStore() and
-        miDCInitialize() to initialize backing store and the software
-        cursor.  Finally, it replaces many of the screen functions with
-        its own functions that repackage and send the requests to the
-        real X server to which Xnest is attached.
-
-
-     CClloosseeSSccrreeeenn(())
-        This function frees its internal data structure allocations.
-        Since it replaces instead of wrapping screen functions, there
-        are no function pointers to unwrap.  This can potentially lead
-        to problems during server regeneration.
-
-
-     GGCC ooppeerraattiioonnss
-        The GC operations in Xnest are very simple since they leave all
-        of the drawing to the real X server to which Xnest is attached.
-        Each of the GCOps takes the request and sends it to the real X
-        server using standard Xlib calls.  For example, the X
-        application issues a XDrawLines() call.  This function turns
-        into a protocol request to Xnest, which calls the
-        xnestPolylines() function through Xnest's GCOps function pointer
-        table.  The xnestPolylines() function is only a single line,
-        which calls XDrawLines() using the same arguments that were
-        passed into it.  Other GCOps functions are very similar.  Two
-        exceptions to the simple GCOps functions described above are the
-        image functions and the BLT operations.
-
-
-        The image functions, GetImage() and PutImage(), must use a
-        temporary image to hold the image to be put of the image that
-        was just grabbed from the screen while it is in transit to the
-        real X server or the client.  When the image has been
-        transmitted, the temporary image is destroyed.
-
-
-        The BLT operations, CopyArea() and CopyPlane(), handle not only
-        the copy function, which is the same as the simple cases
-        described above, but also the graphics exposures that result
-        when the GC's graphics exposure bit is set to True.  Graphics
-        exposures are handled in a helper function,
-        xnestBitBlitHelper().  This function collects the exposure
-        events from the real X server and, if any resulting in regions
-        being exposed, then those regions are passed back to the MI
-        layer so that it can generate exposure events for the X
-        application.
-
-
-  The Xnest server takes its input from the X server to which it is
-  connected.  When the mouse is in the Xnest server's window, keyboard
-  and mouse events are received by the Xnest server, repackaged and sent
-  back to any client that requests those events.
-
-
-  AA..22..77..  SShhaaddooww ffrraammeebbuuffffeerr
-
-  The most common type of framebuffer is a linear array memory that maps
-  to the video memory on the graphics device.  However, accessing that
-  video memory over an I/O bus (e.g., ISA or PCI) can be slow.  The
-  shadow framebuffer layer allows the developer to keep the entire
-  framebuffer in main memory and copy it back to video memory at regular
-  intervals.  It also has been extended to handle planar video memory
-  and rotated framebuffers.
-
-
-  There are two main entry points to the shadow framebuffer code:
-
-
-     sshhaaddoowwAAlllloocc((wwiiddtthh,, hheeiigghhtt,, bbpppp))
-        This function allocates the in memory copy of the framebuffer of
-        size width*height*bpp.  It returns a pointer to that memory,
-        which will be used by the framebuffer ScreenInit() code during
-        the screen's initialization.
-
-
-     sshhaaddoowwIInniitt((ppSSccrreeeenn,, uuppddaatteePPrroocc,, wwiinnddoowwPPrroocc))
-        This function initializes the shadow framebuffer layer.  It
-        wraps several screen drawing functions, and registers a block
-        handler that will update the screen.  The updateProc is a
-        function that will copy the damaged regions to the screen, and
-        the windowProc is a function that is used when the entire linear
-        video memory range cannot be accessed simultaneously so that
-        only a window into that memory is available (e.g., when using
-        the VGA aperture).
-
-
-  The shadow framebuffer code keeps track of the damaged area of each
-  screen by calculating the bounding box of all drawing operations that
-  have occurred since the last screen update.  Then, when the block
-  handler is next called, only the damaged portion of the screen is
-  updated.
-
-
-  Note that since the shadow framebuffer is kept in main memory, all
-  drawing operations are performed by the CPU and, thus, no accelerated
-  hardware drawing operations are possible.
-
-
-
-  AA..33..  XXiinneerraammaa
-
-  Xinerama is an X extension that allows multiple physical screens
-  controlled by a single X server to appear as a single screen.
-  Although the extension allows clients to find the physical screen
-  layout via extension requests, it is completely transparent to clients
-  at the core X11 protocol level.  The original public implementation of
-  Xinerama came from Digital/Compaq.  XFree86 rewrote it, filling in
-  some missing pieces and improving both X11 core protocol compliance
-  and performance.  The Xinerama extension will be passing through
-  X.Org's standardization process in the near future, and the sample
-  implementation will be based on this rewritten version.
-
-
-  The current implementation of Xinerama is based primarily in the DIX
-  (device independent) and MI (machine independent) layers of the X
-  server.  With few exceptions the DDX layers do not need any changes to
-  support Xinerama.  X server extensions often do need modifications to
-  provide full Xinerama functionality.
-
-
-  The following is a code-level description of how Xinerama functions.
-
-
-  Note: Because the Xinerama extension was originally called the
-  PanoramiX extension, many of the Xinerama functions still have the
-  PanoramiX prefix.
-
-
-     PPaannoorraammiiXXEExxtteennssiioonnIInniitt(())
-        PanoramiXExtensionInit() is a device-independent extension
-        function that is called at the start of each server generation
-        from InitExtensions(), which is called from the X server's
-        main() function after all output devices have been initialized,
-        but before any input devices have been initialized.
-
-
-        PanoramiXNumScreens is set to the number of physical screens.
-        If only one physical screen is present, the extension is
-        disabled, and PanoramiXExtensionInit() returns without doing
-        anything else.
-
-
-        The Xinerama extension is registered by calling AddExtension().
-
-
-        A local per-screen array of data structures (panoramiXdataPtr[])
-        is allocated for each physical screen, and GC and Screen private
-        indexes are allocated, and both GC and Screen private areas are
-        allocated for each physical screen.  These hold Xinerama-
-        specific per-GC and per-Screen data.  Each screen's CreateGC and
-        CloseScreen functions are wrapped by XineramaCreateGC() and
-        XineramaCloseScreen() respectively.  Some new resource classes
-        are created for Xinerama drawables and GCs, and resource types
-        for Xinerama windows, pixmaps and colormaps.
-
-
-        A region (XineramaScreenRegions[i]) is initialized for each
-        physical screen, and single region (PanoramiXScreenRegion) is
-        initialized to be the union of the screen regions.  The
-        panoramiXdataPtr[] array is also initialized with the size and
-        origin of each screen.  The relative positioning information for
-        the physical screens is taken from the array dixScreenOrigins[],
-        which the DDX layer must initialize in InitOutput().  The bounds
-        of the combined screen is also calculated (PanoramiXPixWidth and
-        PanoramiXPixHeight).
-
-
-        The DIX layer has a list of function pointers (ProcVector[])
-        that holds the entry points for the functions that process core
-        protocol requests.  The requests that Xinerama must intercept
-        and break up into physical screen-specific requests are wrapped.
-        The original set is copied to SavedProcVector[].  The types of
-        requests intercepted are Window requests, GC requests, colormap
-        requests, drawing requests, and some geometry-related requests.
-        This wrapping allows the bulk of the protocol request processing
-        to be handled transparently to the DIX layer.  Some operations
-        cannot be dealt with in this way and are handled with Xinerama-
-        specific code within the DIX layer.
-
-
-     PPaannoorraammiiXXCCoonnssoolliiddaattee(())
-        PanoramiXConsolidate() is a device-independent extension
-        function that is called directly from the X server's main()
-        function after extensions and input/output devices have been
-        initialized, and before the root windows are defined and
-        initialized.
-
-
-        This function finds the set of depths (PanoramiXDepths[]) and
-        visuals (PanoramiXVisuals[]) common to all of the physical
-        screens.  PanoramiXNumDepths is set to the number of common
-        depths, and PanoramiXNumVisuals is set to the number of common
-        visuals.  Resources are created for the single root window and
-        the default colormap.  Each of these resources has per-physical
-        screen entries.
-
-
-     PPaannoorraammiiXXCCrreeaatteeCCoonnnneeccttiioonnBBlloocckk(())
-        PanoramiXConsolidate() is a device-independent extension
-        function that is called directly from the X server's main()
-        function after the per-physical screen root windows are created.
-        It is called instead of the standard DIX CreateConnectionBlock()
-        function.  If this function returns FALSE, the X server exits
-        with a fatal error.  This function will return FALSE if no
-        common depths were found in PanoramiXConsolidate().  With no
-        common depths, Xinerama mode is not possible.
-
-
-        The connection block holds the information that clients get when
-        they open a connection to the X server.  It includes information
-        such as the supported pixmap formats, number of screens and the
-        sizes, depths, visuals, default colormap information, etc, for
-        each of the screens (much of information that xdpyinfo shows).
-        The connection block is initialized with the combined single
-        screen values that were calculated in the above two functions.
-
-
-        The Xinerama extension allows the registration of connection
-        block callback functions.  The purpose of these is to allow
-        other extensions to do processing at this point.  These
-        callbacks can be registered by calling
-        XineramaRegisterConnectionBlockCallback() from the other
-        extension's ExtensionInit() function.  Each registered
-        connection block callback is called at the end of
-        PanoramiXCreateConnectionBlock().
-
-
-  AA..33..11..  XXiinneerraammaa--ssppeecciiffiicc cchhaannggeess ttoo tthhee DDIIXX ccooddee
-
-  There are a few types of Xinerama-specific changes within the DIX
-  code.  The main ones are described here.
-
-
-  Functions that deal with colormap or GC -related operations outside of
-  the intercepted protocol requests have a test added to only do the
-  processing for screen numbers > 0.  This is because they are handled
-  for the single Xinerama screen and the processing is done once for
-  screen 0.
-
-
-  The handling of motion events does some coordinate translation between
-  the physical screen's origin and screen zero's origin.  Also, motion
-  events must be reported relative to the composite screen origin rather
-  than the physical screen origins.
-
-
-  There is some special handling for cursor, window and event processing
-  that cannot (either not at all or not conveniently) be done via the
-  intercepted protocol requests.  A particular case is the handling of
-  pointers moving between physical screens.
-
-
-  AA..33..22..  XXiinneerraammaa--ssppeecciiffiicc cchhaannggeess ttoo tthhee MMII ccooddee
-
-  The only Xinerama-specific change to the MI code is in
-  miSendExposures() to handle the coordinate (and window ID) translation
-  for expose events.
-
-
-
-  AA..33..33..  IInntteerrcceepptteedd DDIIXX ccoorree rreeqquueessttss
-
-  Xinerama breaks up drawing requests for dispatch to each physical
-  screen.  It also breaks up windows into pieces for each physical
-  screen.  GCs are translated into per-screen GCs.  Colormaps are
-  replicated on each physical screen.  The functions handling the
-  intercepted requests take care of breaking the requests and
-  repackaging them so that they can be passed to the standard request
-  handling functions for each screen in turn.  In addition, and to aid
-  the repackaging, the information from many of the intercepted requests
-  is used to keep up to date the necessary state information for the
-  single composite screen.  Requests (usually those with replies) that
-  can be satisfied completely from this stored state information do not
-  call the standard request handling functions.
-
-
-
-  BB..  DDeevveellooppmmeenntt RReessuullttss
-
-  In this section the results of each phase of development are
-  discussed.  This development took place between approximately June
-  2001 and July 2003.
-
-
-  BB..11..  PPhhaassee II
-
-  The initial development phase dealt with the basic implementation
-  including the bootstrap code, which used the shadow framebuffer, and
-  the unoptimized implementation, based on an Xnest-style
-  implementation.
-
-
-  BB..11..11..  SSccooppee
-
-  The goal of Phase I is to provide fundamental functionality that can
-  act as a foundation for ongoing work:
-
-  1. Develop the proxy X server
-
-     +o  The proxy X server will operate on the X11 protocol and relay
-        requests as necessary to correctly perform the request.
-
-     +o  Work will be based on the existing work for Xinerama and Xnest.
-
-     +o  Input events and windowing operations are handled in the proxy
-        server and rendering requests are repackaged and sent to each of
-        the back-end servers for display.
-
-     +o  The multiple screen layout (including support for overlapping
-        screens) will be user configurable via a configuration file or
-        through the configuration tool.
-
-  2. Develop graphical configuration tool
-
-     +o  There will be potentially a large number of X servers to
-        configure into a single display.  The tool will allow the user
-        to specify which servers are involved in the configuration and
-        how they should be laid out.
-
-  3. Pass the X Test Suite
-
-     +o  The X Test Suite covers the basic X11 operations.  All tests
-        known to succeed must correctly operate in the distributed X
-        environment.
-
-
-  For this phase, the back-end X servers are assumed to be unmodified X
-  servers that do not support any DMX-related protocol extensions;
-  future optimization pathways are considered, but are not implemented;
-  and the configuration tool is assumed to rely only on libraries in the
-  X source tree (e.g., Xt).
-
-
-  BB..11..22..  RReessuullttss
-
-  The proxy X server, Xdmx, was developed to distribute X11 protocol
-  requests to the set of back-end X servers.  It opens a window on each
-  back-end server, which represents the part of the front-end's root
-  window that is visible on that screen.  It mirrors window, pixmap and
-  other state in each back-end server.  Drawing requests are sent to
-  either windows or pixmaps on each back-end server.  This code is based
-  on Xnest and uses the existing Xinerama extension.
-
-
-  Input events can be taken from (1) devices attached to the back-end
-  server, (2) core devices attached directly to the Xdmx server, or (3)
-  from a ``console'' window on another X server.  Events for these
-  devices are gathered, processed and delivered to clients attached to
-  the Xdmx server.
-
-
-  An intuitive configuration format was developed to help the user
-  easily configure the multiple back-end X servers.  It was defined (see
-  grammar in Xdmx man page) and a parser was implemented that is used by
-  the Xdmx server and by a standalone xdmxconfig utility.  The parsing
-  support was implemented such that it can be easily factored out of the
-  X source tree for use with other tools (e.g., vdl).  Support for
-  converting legacy vdl-format configuration files to the DMX format is
-  provided by the vdltodmx utility.
-
-
-  Originally, the configuration file was going to be a subsection of
-  XFree86's XF86Config file, but that was not possible since Xdmx is a
-  completely separate X server.  Thus, a separate config file format was
-  developed.  In addition, a graphical configuration tool, xdmxconfig,
-  was developed to allow the user to create and arrange the screens in
-  the configuration file.  The --ccoonnffiiggffiillee and --ccoonnffiigg command-line
-  options can be used to start Xdmx using a configuration file.
-
-
-  An extension that enables remote input testing is required for the X
-  Test Suite to function.  During this phase, this extension (XTEST) was
-  implemented in the Xdmx server.  The results from running the X Test
-  Suite are described in detail below.
-
-
-  BB..11..33..  XX TTeesstt SSuuiittee
-
-  BB..11..33..11..  IInnttrroodduuccttiioonn
-
-  The X Test Suite contains tests that verify Xlib functions operate
-  correctly.  The test suite is designed to run on a single X server;
-  however, since X applications will not be able to tell the difference
-  between the DMX server and a standard X server, the X Test Suite
-  should also run on the DMX server.
-
-  The Xdmx server was tested with the X Test Suite, and the existing
-  failures are noted in this section.  To put these results in
-  perspective, we first discuss expected X Test failures and how errors
-  in underlying systems can impact Xdmx test results.
-
-
-  BB..11..33..22..  EExxppeecctteedd FFaaiilluurreess ffoorr aa SSiinnggllee HHeeaadd
-
-  A correctly implemented X server with a single screen is expected to
-  fail certain X Test tests.  The following well-known errors occur
-  because of rounding error in the X server code:
-
-  XDrawArc: Tests 42, 63, 66, 73
-  XDrawArcs: Tests 45, 66, 69, 76
-
-
-
-  The following failures occur because of the high-level X server
-  implementation:
-
-  XLoadQueryFont: Test 1
-  XListFontsWithInfo: Tests 3, 4
-  XQueryFont: Tests 1, 2
-
-
-
-  The following test fails when running the X server as root under Linux
-  because of the way directory modes are interpreted:
-
-  XWriteBitmapFile: Test 3
-
-
-
-  Depending on the video card used for the back-end, other failures may
-  also occur because of bugs in the low-level driver implementation.
-  Over time, failures of this kind are usually fixed by XFree86, but
-  will show up in Xdmx testing until then.
-
-
-  BB..11..33..33..  EExxppeecctteedd FFaaiilluurreess ffoorr XXiinneerraammaa
-
-  Xinerama fails several X Test Suite tests because of design decisions
-  made for the current implementation of Xinerama.  Over time, many of
-  these errors will be corrected by XFree86 and the group working on a
-  new Xinerama implementation.  Therefore, Xdmx will also share X Suite
-  Test failures with Xinerama.
-
-  We may be able to fix or work-around some of these failures at the
-  Xdmx level, but this will require additional exploration that was not
-  part of Phase I.
-
-  Xinerama is constantly improving, and the list of Xinerama-related
-  failures depends on XFree86 version and the underlying graphics
-  hardware.  We tested with a variety of hardware, including nVidia, S3,
-  ATI Radeon, and Matrox G400 (in dual-head mode).  The list below
-  includes only those failures that appear to be from the Xinerama
-  layer, and does not include failures listed in the previous section,
-  or failures that appear to be from the low-level graphics driver
-  itself:
-
-  These failures were noted with multiple Xinerama configurations:
-
-  XCopyPlane: Tests 13, 22, 31 (well-known Xinerama implementation issue)
-  XSetFontPath: Test 4
-  XGetDefault: Test 5
-  XMatchVisualInfo: Test 1
-
-
-
-  These failures were noted only when using one dual-head video card
-  with a 4.2.99.x XFree86 server:
-
-  XListPixmapFormats: Test 1
-  XDrawRectangles: Test 45
-
-
-
-  These failures were noted only when using two video cards from
-  different vendors with a 4.1.99.x XFree86 server:
-
-  XChangeWindowAttributes: Test 32
-  XCreateWindow: Test 30
-  XDrawLine: Test 22
-  XFillArc: Test 22
-  XChangeKeyboardControl: Tests 9, 10
-  XRebindKeysym: Test 1
-
-
-
-  BB..11..33..44..  AAddddiittiioonnaall FFaaiilluurreess ffrroomm XXddmmxx
-
-  When running Xdmx, no unexpected failures were noted.  Since the Xdmx
-  server is based on Xinerama, we expect to have most of the Xinerama
-  failures present in the Xdmx server.  Similarly, since the Xdmx server
-  must rely on the low-level device drivers on each back-end server, we
-  also expect that Xdmx will exhibit most of the back-end failures.
-  Here is a summary:
-
-  XListPixmapFormats: Test 1 (configuration dependent)
-  XChangeWindowAttributes: Test 32
-  XCreateWindow: Test 30
-  XCopyPlane: Test 13, 22, 31
-  XSetFontPath: Test 4
-  XGetDefault: Test 5 (configuration dependent)
-  XMatchVisualInfo: Test 1
-  XRebindKeysym: Test 1 (configuration dependent)
-
-
-
-  Note that this list is shorter than the combined list for Xinerama
-  because Xdmx uses different code paths to perform some Xinerama
-  operations.  Further, some Xinerama failures have been fixed in the
-  XFree86 4.2.99.x CVS repository.
-
-
-  BB..11..33..55..  SSuummmmaarryy aanndd FFuuttuurree WWoorrkk
-
-  Running the X Test Suite on Xdmx does not produce any failures that
-  cannot be accounted for by the underlying Xinerama subsystem used by
-  the front-end or by the low-level device-driver code running on the
-  back-end X servers.  The Xdmx server therefore is as ``correct'' as
-  possible with respect to the standard set of X Test Suite tests.
-
-  During the following phases, we will continue to verify Xdmx
-  correctness using the X Test Suite.  We may also use other tests
-  suites or write additional tests that run under the X Test Suite that
-  specifically verify the expected behavior of DMX.
-
-
-
-  BB..11..44..  FFoonnttss
-
-  In Phase I, fonts are handled directly by both the front-end and the
-  back-end servers, which is required since we must treat each back-end
-  server during this phase as a ``black box''.  What this requires is
-  that tthhee ffrroonntt-- aanndd bbaacckk--eenndd sseerrvveerrss mmuusstt sshhaarree tthhee eexxaacctt ssaammee ffoonntt
-  ppaatthh.  There are two ways to help make sure that all servers share the
-  same font path:
-
-
-  1. First, each server can be configured to use the same font server.
-     The font server, xfs, can be configured to serve fonts to multiple
-     X servers via TCP.
-
-  2. Second, each server can be configured to use the same font path and
-     either those font paths can be copied to each back-end machine or
-     they can be mounted (e.g., via NFS) on each back-end machine.
-
-
-  One additional concern is that a client program can set its own font
-  path, and if it does so, then that font path must be available on each
-  back-end machine.
-
-
-  The -fontpath command line option was added to allow users to
-  initialize the font path of the front end server.  This font path is
-  propagated to each back-end server when the default font is loaded.
-  If there are any problems, an error message is printed, which will
-  describe the problem and list the current font path.  For more
-  information about setting the font path, see the -fontpath option
-  description in the man page.
-
-
-  BB..11..55..  PPeerrffoorrmmaannccee
-
-  Phase I of development was not intended to optimize performance.  Its
-  focus was on completely and correctly handling the base X11 protocol
-  in the Xdmx server.  However, several insights were gained during
-  Phase I, which are listed here for reference during the next phase of
-  development.
-
-
-  1. Calls to XSync() can slow down rendering since it requires a
-     complete round trip to and from a back-end server.  This is
-     especially problematic when communicating over long haul networks.
-
-  2. Sending drawing requests to only the screens that they overlap
-     should improve performance.
-
-
-  BB..11..66..  PPiixxmmaappss
-
-  Pixmaps were originally expected to be handled entirely in the front-
-  end X server; however, it was found that this overly complicated the
-  rendering code and would have required sending potentially large
-  images to each back server that required them when copying from pixmap
-  to screen.  Thus, pixmap state is mirrored in the back-end server just
-  as it is with regular window state.  With this implementation, the
-  same rendering code that draws to windows can be used to draw to
-  pixmaps on the back-end server, and no large image transfers are
-  required to copy from pixmap to window.
-
-
-
-  BB..22..  PPhhaassee IIII
-
-  The second phase of development concentrates on performance
-  optimizations.  These optimizations are documented here, with x11perf
-  data to show how the optimizations improve performance.
-
-
-  All benchmarks were performed by running Xdmx on a dual processor
-  1.4GHz AMD Athlon machine with 1GB of RAM connecting over 100baseT to
-  two single-processor 1GHz Pentium III machines with 256MB of RAM and
-  ATI Rage 128 (RF) video cards.  The front end was running Linux
-  2.4.20-pre1-ac1 and the back ends were running Linux 2.4.7-10 and
-  version 4.2.99.1 of XFree86 pulled from the XFree86 CVS repository on
-  August 7, 2002.  All systems were running Red Hat Linux 7.2.
-
-
-  BB..22..11..  MMoovviinngg ffrroomm XXFFrreeee8866 44..11..9999..11 ttoo 44..22..00..00
-
-  For phase II, the working source tree was moved to the branch tagged
-  with dmx-1-0-branch and was updated from version 4.1.99.1 (20 August
-  2001) of the XFree86 sources to version 4.2.0.0 (18 January 2002).
-  After this update, the following tests were noted to be more than 10%
-  faster:
-
-  1.13   Fill 300x300 opaque stippled trapezoid (161x145 stipple)
-  1.16   Fill 1x1 tiled trapezoid (161x145 tile)
-  1.13   Fill 10x10 tiled trapezoid (161x145 tile)
-  1.17   Fill 100x100 tiled trapezoid (161x145 tile)
-  1.16   Fill 1x1 tiled trapezoid (216x208 tile)
-  1.20   Fill 10x10 tiled trapezoid (216x208 tile)
-  1.15   Fill 100x100 tiled trapezoid (216x208 tile)
-  1.37   Circulate Unmapped window (200 kids)
-
-
-
-  And the following tests were noted to be more than 10% slower:
-
-  0.88   Unmap window via parent (25 kids)
-  0.75   Circulate Unmapped window (4 kids)
-  0.79   Circulate Unmapped window (16 kids)
-  0.80   Circulate Unmapped window (25 kids)
-  0.82   Circulate Unmapped window (50 kids)
-  0.85   Circulate Unmapped window (75 kids)
-
-
-
-  These changes were not caused by any changes in the DMX system, and
-  may point to changes in the XFree86 tree or to tests that have more
-  "jitter" than most other x11perf tests.
-
-
-  BB..22..22..  GGlloobbaall cchhaannggeess
-
-  During the development of the Phase II DMX server, several global
-  changes were made.  These changes were also compared with the Phase I
-  server.  The following tests were noted to be more than 10% faster:
-
-
-
-  1.13   Fill 300x300 opaque stippled trapezoid (161x145 stipple)
-  1.15   Fill 1x1 tiled trapezoid (161x145 tile)
-  1.13   Fill 10x10 tiled trapezoid (161x145 tile)
-  1.17   Fill 100x100 tiled trapezoid (161x145 tile)
-  1.16   Fill 1x1 tiled trapezoid (216x208 tile)
-  1.19   Fill 10x10 tiled trapezoid (216x208 tile)
-  1.15   Fill 100x100 tiled trapezoid (216x208 tile)
-  1.15   Circulate Unmapped window (4 kids)
-
-
-
-  The following tests were noted to be more than 10% slower:
-
-  0.69   Scroll 10x10 pixels
-  0.68   Scroll 100x100 pixels
-  0.68   Copy 10x10 from window to window
-  0.68   Copy 100x100 from window to window
-  0.76   Circulate Unmapped window (75 kids)
-  0.83   Circulate Unmapped window (100 kids)
-
-
-
-  For the remainder of this analysis, the baseline of comparison will be
-  the Phase II deliverable with all optimizations disabled (unless
-  otherwise noted).  This will highlight how the optimizations in
-  isolation impact performance.
-
-
-  BB..22..33..  XXSSyynncc(()) BBaattcchhiinngg
-
-  During the Phase I implementation, XSync() was called after every
-  protocol request made by the DMX server.  This provided the DMX server
-  with an interactive feel, but defeated X11's protocol buffering system
-  and introduced round-trip wire latency into every operation.  During
-  Phase II, DMX was changed so that protocol requests are no longer
-  followed by calls to XSync().  Instead, the need for an XSync() is
-  noted, and XSync() calls are only made every 100mS or when the DMX
-  server specifically needs to make a call to guarantee interactivity.
-  With this new system, X11 buffers protocol as much as possible during
-  a 100mS interval, and many unnecessary XSync() calls are avoided.
-
-
-  Out of more than 300 x11perf tests, 8 tests became more than 100 times
-  faster, with 68 more than 50X faster, 114 more than 10X faster, and
-  181 more than 2X faster.  See table below for summary.
-
-
-  The following tests were noted to be more than 10% slower with XSync()
-  batching on:
-
-  0.88   500x500 tiled rectangle (161x145 tile)
-  0.89   Copy 500x500 from window to window
-
-
-
-  BB..22..44..  OOffffssccrreeeenn OOppttiimmiizzaattiioonn
-
-  Windows span one or more of the back-end servers' screens; however,
-  during Phase I development, windows were created on every back-end
-  server and every rendering request was sent to every window regardless
-  of whether or not that window was visible.  With the offscreen
-  optimization, the DMX server tracks when a window is completely off of
-  a back-end server's screen and, in that case, it does not send
-  rendering requests to those back-end windows.  This optimization saves
-  bandwidth between the front and back-end servers, and it reduces the
-  number of XSync() calls.  The performance tests were run on a DMX
-  system with only two back-end servers.  Greater performance gains will
-  be had as the number of back-end servers increases.
-
-
-  Out of more than 300 x11perf tests, 3 tests were at least twice as
-  fast, and 146 tests were at least 10% faster.  Two tests were more
-  than 10% slower with the offscreen optimization:
-
-  0.88   Hide/expose window via popup (4 kids)
-  0.89   Resize unmapped window (75 kids)
-
-
-
-  BB..22..55..  LLaazzyy WWiinnddooww CCrreeaattiioonn OOppttiimmiizzaattiioonn
-
-  As mentioned above, during Phase I, windows were created on every
-  back-end server even if they were not visible on that back-end.  With
-  the lazy window creation optimization, the DMX server does not create
-  windows on a back-end server until they are either visible or they
-  become the parents of a visible window.  This optimization builds on
-  the offscreen optimization (described above) and requires it to be
-  enabled.
-
-
-  The lazy window creation optimization works by creating the window
-  data structures in the front-end server when a client creates a
-  window, but delays creation of the window on the back-end server(s).
-  A private window structure in the DMX server saves the relevant window
-  data and tracks changes to the window's attributes and stacking order
-  for later use.  The only times a window is created on a back-end
-  server are (1) when it is mapped and is at least partially overlapping
-  the back-end server's screen (tracked by the offscreen optimization),
-  or (2) when the window becomes the parent of a previously visible
-  window.  The first case occurs when a window is mapped or when a
-  visible window is copied, moved or resized and now overlaps the back-
-  end server's screen.  The second case occurs when starting a window
-  manager after having created windows to which the window manager needs
-  to add decorations.
-
-
-  When either case occurs, a window on the back-end server is created
-  using the data saved in the DMX server's window private data
-  structure.  The stacking order is then adjusted to correctly place the
-  window on the back-end and lastly the window is mapped.  From this
-  time forward, the window is handled exactly as if the window had been
-  created at the time of the client's request.
-
-
-  Note that when a window is no longer visible on a back-end server's
-  screen (e.g., it is moved offscreen), the window is not destroyed;
-  rather, it is kept and reused later if the window once again becomes
-  visible on the back-end server's screen.  Originally with this
-  optimization, destroying windows was implemented but was later
-  rejected because it increased bandwidth when windows were opaquely
-  moved or resized, which is common in many window managers.
-
-
-
-  The performance tests were run on a DMX system with only two back-end
-  servers.  Greater performance gains will be had as the number of back-
-  end servers increases.
-
-
-  This optimization improved the following x11perf tests by more than
-  10%:
-
-  1.10   500x500 rectangle outline
-  1.12   Fill 100x100 stippled trapezoid (161x145 stipple)
-  1.20   Circulate Unmapped window (50 kids)
-  1.19   Circulate Unmapped window (75 kids)
-
-
-
-  BB..22..66..  SSuubbddiivviiddiinngg RReennddeerriinngg PPrriimmiittiivveess
-
-  X11 imaging requests transfer significant data between the client and
-  the X server.  During Phase I, the DMX server would then transfer the
-  image data to each back-end server.  Even with the offscreen
-  optimization (above), these requests still required transferring
-  significant data to each back-end server that contained a visible
-  portion of the window.  For example, if the client uses XPutImage() to
-  copy an image to a window that overlaps the entire DMX screen, then
-  the entire image is copied by the DMX server to every back-end server.
-
-
-  To reduce the amount of data transferred between the DMX server and
-  the back-end servers when XPutImage() is called, the image data is
-  subdivided and only the data that will be visible on a back-end
-  server's screen is sent to that back-end server.  Xinerama already
-  implements a subdivision algorithm for XGetImage() and no further
-  optimization was needed.
-
-
-  Other rendering primitives were analyzed, but the time required to
-  subdivide these primitives was a significant proportion of the time
-  required to send the entire rendering request to the back-end server,
-  so this optimization was rejected for the other rendering primitives.
-
-
-  Again, the performance tests were run on a DMX system with only two
-  back-end servers.  Greater performance gains will be had as the number
-  of back-end servers increases.
-
-
-  This optimization improved the following x11perf tests by more than
-  10%:
-
-  1.12   Fill 100x100 stippled trapezoid (161x145 stipple)
-  1.26   PutImage 10x10 square
-  1.83   PutImage 100x100 square
-  1.91   PutImage 500x500 square
-  1.40   PutImage XY 10x10 square
-  1.48   PutImage XY 100x100 square
-  1.50   PutImage XY 500x500 square
-  1.45   Circulate Unmapped window (75 kids)
-  1.74   Circulate Unmapped window (100 kids)
-
-
-
-  The following test was noted to be more than 10% slower with this
-  optimization:
-
-  0.88   10-pixel fill chord partial circle
-
-
-
-  BB..22..77..  SSuummmmaarryy ooff xx1111ppeerrff DDaattaa
-
-  With all of the optimizations on, 53 x11perf tests are more than 100X
-  faster than the unoptimized Phase II deliverable, with 69 more than
-  50X faster, 73 more than 10X faster, and 199 more than twice as fast.
-  No tests were more than 10% slower than the unoptimized Phase II
-  deliverable.  (Compared with the Phase I deliverable, only Circulate
-  Unmapped window (100 kids) was more than 10% slower than the Phase II
-  deliverable.  As noted above, this test seems to have wider
-  variability than other x11perf tests.)
-
-
-  The following table summarizes relative x11perf test changes for all
-  optimizations individually and collectively.  Note that some of the
-  optimizations have a synergistic effect when used together.
-
-
-
-  1: XSync() batching only
-  2: Off screen optimizations only
-  3: Window optimizations only
-  4: Subdivprims only
-  5: All optimizations
-
-      1     2    3    4      5 Operation
-  ------ ---- ---- ---- ------ ---------
-    2.14 1.85 1.00 1.00   4.13 Dot
-    1.67 1.80 1.00 1.00   3.31 1x1 rectangle
-    2.38 1.43 1.00 1.00   2.44 10x10 rectangle
-    1.00 1.00 0.92 0.98   1.00 100x100 rectangle
-    1.00 1.00 1.00 1.00   1.00 500x500 rectangle
-    1.83 1.85 1.05 1.06   3.54 1x1 stippled rectangle (8x8 stipple)
-    2.43 1.43 1.00 1.00   2.41 10x10 stippled rectangle (8x8 stipple)
-    0.98 1.00 1.00 1.00   1.00 100x100 stippled rectangle (8x8 stipple)
-    1.00 1.00 1.00 1.00   0.98 500x500 stippled rectangle (8x8 stipple)
-    1.75 1.75 1.00 1.00   3.40 1x1 opaque stippled rectangle (8x8 stipple)
-    2.38 1.42 1.00 1.00   2.34 10x10 opaque stippled rectangle (8x8 stipple)
-    1.00 1.00 0.97 0.97   1.00 100x100 opaque stippled rectangle (8x8 stipple)
-    1.00 1.00 1.00 1.00   0.99 500x500 opaque stippled rectangle (8x8 stipple)
-    1.82 1.82 1.04 1.04   3.56 1x1 tiled rectangle (4x4 tile)
-    2.33 1.42 1.00 1.00   2.37 10x10 tiled rectangle (4x4 tile)
-    1.00 0.92 1.00 1.00   1.00 100x100 tiled rectangle (4x4 tile)
-    1.00 1.00 1.00 1.00   1.00 500x500 tiled rectangle (4x4 tile)
-    1.94 1.62 1.00 1.00   3.66 1x1 stippled rectangle (17x15 stipple)
-    1.74 1.28 1.00 1.00   1.73 10x10 stippled rectangle (17x15 stipple)
-    1.00 1.00 1.00 0.89   0.98 100x100 stippled rectangle (17x15 stipple)
-    1.00 1.00 1.00 1.00   0.98 500x500 stippled rectangle (17x15 stipple)
-    1.94 1.62 1.00 1.00   3.67 1x1 opaque stippled rectangle (17x15 stipple)
-    1.69 1.26 1.00 1.00   1.66 10x10 opaque stippled rectangle (17x15 stipple)
-    1.00 0.95 1.00 1.00   1.00 100x100 opaque stippled rectangle (17x15 stipple)
-    1.00 1.00 1.00 1.00   0.97 500x500 opaque stippled rectangle (17x15 stipple)
-    1.93 1.61 0.99 0.99   3.69 1x1 tiled rectangle (17x15 tile)
-    1.73 1.27 1.00 1.00   1.72 10x10 tiled rectangle (17x15 tile)
-    1.00 1.00 1.00 1.00   0.98 100x100 tiled rectangle (17x15 tile)
-    1.00 1.00 0.97 0.97   1.00 500x500 tiled rectangle (17x15 tile)
-    1.95 1.63 1.00 1.00   3.83 1x1 stippled rectangle (161x145 stipple)
-    1.80 1.30 1.00 1.00   1.83 10x10 stippled rectangle (161x145 stipple)
-    0.97 1.00 1.00 1.00   1.01 100x100 stippled rectangle (161x145 stipple)
-    1.00 1.00 1.00 1.00   0.98 500x500 stippled rectangle (161x145 stipple)
-    1.95 1.63 1.00 1.00   3.56 1x1 opaque stippled rectangle (161x145 stipple)
-    1.65 1.25 1.00 1.00   1.68 10x10 opaque stippled rectangle (161x145 stipple)
-    1.00 1.00 1.00 1.00   1.01 100x100 opaque stippled rectangle (161x145...
-    1.00 1.00 1.00 1.00   0.97 500x500 opaque stippled rectangle (161x145...
-    1.95 1.63 0.98 0.99   3.80 1x1 tiled rectangle (161x145 tile)
-    1.67 1.26 1.00 1.00   1.67 10x10 tiled rectangle (161x145 tile)
-    1.13 1.14 1.14 1.14   1.14 100x100 tiled rectangle (161x145 tile)
-    0.88 1.00 1.00 1.00   0.99 500x500 tiled rectangle (161x145 tile)
-    1.93 1.63 1.00 1.00   3.53 1x1 tiled rectangle (216x208 tile)
-    1.69 1.26 1.00 1.00   1.66 10x10 tiled rectangle (216x208 tile)
-    1.00 1.00 1.00 1.00   1.00 100x100 tiled rectangle (216x208 tile)
-    1.00 1.00 1.00 1.00   1.00 500x500 tiled rectangle (216x208 tile)
-    1.82 1.70 1.00 1.00   3.38 1-pixel line segment
-    2.07 1.56 0.90 1.00   3.31 10-pixel line segment
-    1.29 1.10 1.00 1.00   1.27 100-pixel line segment
-    1.05 1.06 1.03 1.03   1.09 500-pixel line segment
-    1.30 1.13 1.00 1.00   1.29 100-pixel line segment (1 kid)
-    1.32 1.15 1.00 1.00   1.32 100-pixel line segment (2 kids)
-    1.33 1.16 1.00 1.00   1.33 100-pixel line segment (3 kids)
-    1.92 1.64 1.00 1.00   3.73 10-pixel dashed segment
-    1.34 1.16 1.00 1.00   1.34 100-pixel dashed segment
-    1.24 1.11 0.99 0.97   1.23 100-pixel double-dashed segment
-    1.72 1.77 1.00 1.00   3.25 10-pixel horizontal line segment
-    1.83 1.66 1.01 1.00   3.54 100-pixel horizontal line segment
-    1.86 1.30 1.00 1.00   1.84 500-pixel horizontal line segment
-    2.11 1.52 1.00 0.99   3.02 10-pixel vertical line segment
-    1.21 1.10 1.00 1.00   1.20 100-pixel vertical line segment
-    1.03 1.03 1.00 1.00   1.02 500-pixel vertical line segment
-    4.42 1.68 1.00 1.01   4.64 10x1 wide horizontal line segment
-    1.83 1.31 1.00 1.00   1.83 100x10 wide horizontal line segment
-    1.07 1.00 0.96 1.00   1.07 500x50 wide horizontal line segment
-    4.10 1.67 1.00 1.00   4.62 10x1 wide vertical line segment
-    1.50 1.24 1.06 1.06   1.48 100x10 wide vertical line segment
-    1.06 1.03 1.00 1.00   1.05 500x50 wide vertical line segment
-    2.54 1.61 1.00 1.00   3.61 1-pixel line
-    2.71 1.48 1.00 1.00   2.67 10-pixel line
-    1.19 1.09 1.00 1.00   1.19 100-pixel line
-    1.04 1.02 1.00 1.00   1.03 500-pixel line
-    2.68 1.51 0.98 1.00   3.17 10-pixel dashed line
-    1.23 1.11 0.99 0.99   1.23 100-pixel dashed line
-    1.15 1.08 1.00 1.00   1.15 100-pixel double-dashed line
-    2.27 1.39 1.00 1.00   2.23 10x1 wide line
-    1.20 1.09 1.00 1.00   1.20 100x10 wide line
-    1.04 1.02 1.00 1.00   1.04 500x50 wide line
-    1.52 1.45 1.00 1.00   1.52 100x10 wide dashed line
-    1.54 1.47 1.00 1.00   1.54 100x10 wide double-dashed line
-    1.97 1.30 0.96 0.95   1.95 10x10 rectangle outline
-    1.44 1.27 1.00 1.00   1.43 100x100 rectangle outline
-    3.22 2.16 1.10 1.09   3.61 500x500 rectangle outline
-    1.95 1.34 1.00 1.00   1.90 10x10 wide rectangle outline
-    1.14 1.14 1.00 1.00   1.13 100x100 wide rectangle outline
-    1.00 1.00 1.00 1.00   1.00 500x500 wide rectangle outline
-    1.57 1.72 1.00 1.00   3.03 1-pixel circle
-    1.96 1.35 1.00 1.00   1.92 10-pixel circle
-    1.21 1.07 0.86 0.97   1.20 100-pixel circle
-    1.08 1.04 1.00 1.00   1.08 500-pixel circle
-    1.39 1.19 1.03 1.03   1.38 100-pixel dashed circle
-    1.21 1.11 1.00 1.00   1.23 100-pixel double-dashed circle
-    1.59 1.28 1.00 1.00   1.58 10-pixel wide circle
-    1.22 1.12 0.99 1.00   1.22 100-pixel wide circle
-    1.06 1.04 1.00 1.00   1.05 500-pixel wide circle
-    1.87 1.84 1.00 1.00   1.85 100-pixel wide dashed circle
-    1.90 1.93 1.01 1.01   1.90 100-pixel wide double-dashed circle
-    2.13 1.43 1.00 1.00   2.32 10-pixel partial circle
-    1.42 1.18 1.00 1.00   1.42 100-pixel partial circle
-    1.92 1.85 1.01 1.01   1.89 10-pixel wide partial circle
-    1.73 1.67 1.00 1.00   1.73 100-pixel wide partial circle
-    1.36 1.95 1.00 1.00   2.64 1-pixel solid circle
-    2.02 1.37 1.00 1.00   2.03 10-pixel solid circle
-    1.19 1.09 1.00 1.00   1.19 100-pixel solid circle
-    1.02 0.99 1.00 1.00   1.01 500-pixel solid circle
-    1.74 1.28 1.00 0.88   1.73 10-pixel fill chord partial circle
-    1.31 1.13 1.00 1.00   1.31 100-pixel fill chord partial circle
-    1.67 1.31 1.03 1.03   1.72 10-pixel fill slice partial circle
-    1.30 1.13 1.00 1.00   1.28 100-pixel fill slice partial circle
-    2.45 1.49 1.01 1.00   2.71 10-pixel ellipse
-    1.22 1.10 1.00 1.00   1.22 100-pixel ellipse
-    1.09 1.04 1.00 1.00   1.09 500-pixel ellipse
-    1.90 1.28 1.00 1.00   1.89 100-pixel dashed ellipse
-    1.62 1.24 0.96 0.97   1.61 100-pixel double-dashed ellipse
-    2.43 1.50 1.00 1.00   2.42 10-pixel wide ellipse
-    1.61 1.28 1.03 1.03   1.60 100-pixel wide ellipse
-    1.08 1.05 1.00 1.00   1.08 500-pixel wide ellipse
-    1.93 1.88 1.00 1.00   1.88 100-pixel wide dashed ellipse
-    1.94 1.89 1.01 1.00   1.94 100-pixel wide double-dashed ellipse
-    2.31 1.48 1.00 1.00   2.67 10-pixel partial ellipse
-    1.38 1.17 1.00 1.00   1.38 100-pixel partial ellipse
-    2.00 1.85 0.98 0.97   1.98 10-pixel wide partial ellipse
-    1.89 1.86 1.00 1.00   1.89 100-pixel wide partial ellipse
-    3.49 1.60 1.00 1.00   3.65 10-pixel filled ellipse
-    1.67 1.26 1.00 1.00   1.67 100-pixel filled ellipse
-    1.06 1.04 1.00 1.00   1.06 500-pixel filled ellipse
-    2.38 1.43 1.01 1.00   2.32 10-pixel fill chord partial ellipse
-    2.06 1.30 1.00 1.00   2.05 100-pixel fill chord partial ellipse
-    2.27 1.41 1.00 1.00   2.27 10-pixel fill slice partial ellipse
-    1.98 1.33 1.00 0.97   1.97 100-pixel fill slice partial ellipse
-   57.46 1.99 1.01 1.00 114.92 Fill 1x1 equivalent triangle
-   56.94 1.98 1.01 1.00  73.89 Fill 10x10 equivalent triangle
-    6.07 1.75 1.00 1.00   6.07 Fill 100x100 equivalent triangle
-   51.12 1.98 1.00 1.00 102.81 Fill 1x1 trapezoid
-   51.42 1.82 1.01 1.00  94.89 Fill 10x10 trapezoid
-    6.47 1.80 1.00 1.00   6.44 Fill 100x100 trapezoid
-    1.56 1.28 1.00 0.99   1.56 Fill 300x300 trapezoid
-   51.27 1.97 0.96 0.97 102.54 Fill 1x1 stippled trapezoid (8x8 stipple)
-   51.73 2.00 1.02 1.02  67.92 Fill 10x10 stippled trapezoid (8x8 stipple)
-    5.36 1.72 1.00 1.00   5.36 Fill 100x100 stippled trapezoid (8x8 stipple)
-    1.54 1.26 1.00 1.00   1.59 Fill 300x300 stippled trapezoid (8x8 stipple)
-   51.41 1.94 1.01 1.00 102.82 Fill 1x1 opaque stippled trapezoid (8x8 stipple)
-   50.71 1.95 0.99 1.00  65.44 Fill 10x10 opaque stippled trapezoid (8x8...
-    5.33 1.73 1.00 1.00   5.36 Fill 100x100 opaque stippled trapezoid (8x8...
-    1.58 1.25 1.00 1.00   1.58 Fill 300x300 opaque stippled trapezoid (8x8...
-   51.56 1.96 0.99 0.90 103.68 Fill 1x1 tiled trapezoid (4x4 tile)
-   51.59 1.99 1.01 1.01  62.25 Fill 10x10 tiled trapezoid (4x4 tile)
-    5.38 1.72 1.00 1.00   5.38 Fill 100x100 tiled trapezoid (4x4 tile)
-    1.54 1.25 1.00 0.99   1.58 Fill 300x300 tiled trapezoid (4x4 tile)
-   51.70 1.98 1.01 1.01 103.98 Fill 1x1 stippled trapezoid (17x15 stipple)
-   44.86 1.97 1.00 1.00  44.86 Fill 10x10 stippled trapezoid (17x15 stipple)
-    2.74 1.56 1.00 1.00   2.73 Fill 100x100 stippled trapezoid (17x15 stipple)
-    1.29 1.14 1.00 1.00   1.27 Fill 300x300 stippled trapezoid (17x15 stipple)
-   51.41 1.96 0.96 0.95 103.39 Fill 1x1 opaque stippled trapezoid (17x15...
-   45.14 1.96 1.01 1.00  45.14 Fill 10x10 opaque stippled trapezoid (17x15...
-    2.68 1.56 1.00 1.00   2.68 Fill 100x100 opaque stippled trapezoid (17x15...
-    1.26 1.10 1.00 1.00   1.28 Fill 300x300 opaque stippled trapezoid (17x15...
-   51.13 1.97 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (17x15 tile)
-   47.58 1.96 1.00 1.00  47.86 Fill 10x10 tiled trapezoid (17x15 tile)
-    2.74 1.56 1.00 1.00   2.74 Fill 100x100 tiled trapezoid (17x15 tile)
-    1.29 1.14 1.00 1.00   1.28 Fill 300x300 tiled trapezoid (17x15 tile)
-   51.13 1.97 0.99 0.97 103.39 Fill 1x1 stippled trapezoid (161x145 stipple)
-   45.14 1.97 1.00 1.00  44.29 Fill 10x10 stippled trapezoid (161x145 stipple)
-    3.02 1.77 1.12 1.12   3.38 Fill 100x100 stippled trapezoid (161x145 stipple)
-    1.31 1.13 1.00 1.00   1.30 Fill 300x300 stippled trapezoid (161x145 stipple)
-   51.27 1.97 1.00 1.00 103.10 Fill 1x1 opaque stippled trapezoid (161x145...
-   45.01 1.97 1.00 1.00  45.01 Fill 10x10 opaque stippled trapezoid (161x145...
-    2.67 1.56 1.00 1.00   2.69 Fill 100x100 opaque stippled trapezoid (161x145..
-    1.29 1.13 1.00 1.01   1.27 Fill 300x300 opaque stippled trapezoid (161x145..
-   51.41 1.96 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (161x145 tile)
-   45.01 1.96 0.98 1.00  45.01 Fill 10x10 tiled trapezoid (161x145 tile)
-    2.62 1.36 1.00 1.00   2.69 Fill 100x100 tiled trapezoid (161x145 tile)
-    1.27 1.13 1.00 1.00   1.22 Fill 300x300 tiled trapezoid (161x145 tile)
-   51.13 1.98 1.00 1.00 103.39 Fill 1x1 tiled trapezoid (216x208 tile)
-   45.14 1.97 1.01 0.99  45.14 Fill 10x10 tiled trapezoid (216x208 tile)
-    2.62 1.55 1.00 1.00   2.71 Fill 100x100 tiled trapezoid (216x208 tile)
-    1.28 1.13 1.00 1.00   1.20 Fill 300x300 tiled trapezoid (216x208 tile)
-   50.71 1.95 1.00 1.00  54.70 Fill 10x10 equivalent complex polygon
-    5.51 1.71 0.96 0.98   5.47 Fill 100x100 equivalent complex polygons
-    8.39 1.97 1.00 1.00  16.75 Fill 10x10 64-gon (Convex)
-    8.38 1.83 1.00 1.00   8.43 Fill 100x100 64-gon (Convex)
-    8.50 1.96 1.00 1.00  16.64 Fill 10x10 64-gon (Complex)
-    8.26 1.83 1.00 1.00   8.35 Fill 100x100 64-gon (Complex)
-   14.09 1.87 1.00 1.00  14.05 Char in 80-char line (6x13)
-   11.91 1.87 1.00 1.00  11.95 Char in 70-char line (8x13)
-   11.16 1.85 1.01 1.00  11.10 Char in 60-char line (9x15)
-   10.09 1.78 1.00 1.00  10.09 Char16 in 40-char line (k14)
-    6.15 1.75 1.00 1.00   6.31 Char16 in 23-char line (k24)
-   11.92 1.90 1.03 1.03  11.88 Char in 80-char line (TR 10)
-    8.18 1.78 1.00 0.99   8.17 Char in 30-char line (TR 24)
-   42.83 1.44 1.01 1.00  42.11 Char in 20/40/20 line (6x13, TR 10)
-   27.45 1.43 1.01 1.01  27.45 Char16 in 7/14/7 line (k14, k24)
-   12.13 1.85 1.00 1.00  12.05 Char in 80-char image line (6x13)
-   10.00 1.84 1.00 1.00  10.00 Char in 70-char image line (8x13)
-    9.18 1.83 1.00 1.00   9.12 Char in 60-char image line (9x15)
-    9.66 1.82 0.98 0.95   9.66 Char16 in 40-char image line (k14)
-    5.82 1.72 1.00 1.00   5.99 Char16 in 23-char image line (k24)
-    8.70 1.80 1.00 1.00   8.65 Char in 80-char image line (TR 10)
-    4.67 1.66 1.00 1.00   4.67 Char in 30-char image line (TR 24)
-   84.43 1.47 1.00 1.00 124.18 Scroll 10x10 pixels
-    3.73 1.50 1.00 0.98   3.73 Scroll 100x100 pixels
-    1.00 1.00 1.00 1.00   1.00 Scroll 500x500 pixels
-   84.43 1.51 1.00 1.00 134.02 Copy 10x10 from window to window
-    3.62 1.51 0.98 0.98   3.62 Copy 100x100 from window to window
-    0.89 1.00 1.00 1.00   1.00 Copy 500x500 from window to window
-   57.06 1.99 1.00 1.00  88.64 Copy 10x10 from pixmap to window
-    2.49 2.00 1.00 1.00   2.48 Copy 100x100 from pixmap to window
-    1.00 0.91 1.00 1.00   0.98 Copy 500x500 from pixmap to window
-    2.04 1.01 1.00 1.00   2.03 Copy 10x10 from window to pixmap
-    1.05 1.00 1.00 1.00   1.05 Copy 100x100 from window to pixmap
-    1.00 1.00 0.93 1.00   1.04 Copy 500x500 from window to pixmap
-   58.52 1.03 1.03 1.02  57.95 Copy 10x10 from pixmap to pixmap
-    2.40 1.00 1.00 1.00   2.45 Copy 100x100 from pixmap to pixmap
-    1.00 1.00 1.00 1.00   1.00 Copy 500x500 from pixmap to pixmap
-   51.57 1.92 1.00 1.00  85.75 Copy 10x10 1-bit deep plane
-    6.37 1.75 1.01 1.01   6.37 Copy 100x100 1-bit deep plane
-    1.26 1.11 1.00 1.00   1.24 Copy 500x500 1-bit deep plane
-    4.23 1.63 0.98 0.97   4.38 Copy 10x10 n-bit deep plane
-    1.04 1.02 1.00 1.00   1.04 Copy 100x100 n-bit deep plane
-    1.00 1.00 1.00 1.00   1.00 Copy 500x500 n-bit deep plane
-    6.45 1.98 1.00 1.26  12.80 PutImage 10x10 square
-    1.10 1.87 1.00 1.83   2.11 PutImage 100x100 square
-    1.02 1.93 1.00 1.91   1.91 PutImage 500x500 square
-    4.17 1.78 1.00 1.40   7.18 PutImage XY 10x10 square
-    1.27 1.49 0.97 1.48   2.10 PutImage XY 100x100 square
-    1.00 1.50 1.00 1.50   1.52 PutImage XY 500x500 square
-    1.07 1.01 1.00 1.00   1.06 GetImage 10x10 square
-    1.01 1.00 1.00 1.00   1.01 GetImage 100x100 square
-    1.00 1.00 1.00 1.00   1.00 GetImage 500x500 square
-    1.56 1.00 0.99 0.97   1.56 GetImage XY 10x10 square
-    1.02 1.00 1.00 1.00   1.02 GetImage XY 100x100 square
-    1.00 1.00 1.00 1.00   1.00 GetImage XY 500x500 square
-    1.00 1.00 1.01 0.98   0.95 X protocol NoOperation
-    1.02 1.03 1.04 1.03   1.00 QueryPointer
-    1.03 1.02 1.04 1.03   1.00 GetProperty
-  100.41 1.51 1.00 1.00 198.76 Change graphics context
-   45.81 1.00 0.99 0.97  57.10 Create and map subwindows (4 kids)
-   78.45 1.01 1.02 1.02  63.07 Create and map subwindows (16 kids)
-   73.91 1.01 1.00 1.00  56.37 Create and map subwindows (25 kids)
-   73.22 1.00 1.00 1.00  49.07 Create and map subwindows (50 kids)
-   72.36 1.01 0.99 1.00  32.14 Create and map subwindows (75 kids)
-   70.34 1.00 1.00 1.00  30.12 Create and map subwindows (100 kids)
-   55.00 1.00 1.00 0.99  23.75 Create and map subwindows (200 kids)
-   55.30 1.01 1.00 1.00 141.03 Create unmapped window (4 kids)
-   55.38 1.01 1.01 1.00 163.25 Create unmapped window (16 kids)
-   54.75 0.96 1.00 0.99 166.95 Create unmapped window (25 kids)
-   54.83 1.00 1.00 0.99 178.81 Create unmapped window (50 kids)
-   55.38 1.01 1.01 1.00 181.20 Create unmapped window (75 kids)
-   55.38 1.01 1.01 1.00 181.20 Create unmapped window (100 kids)
-   54.87 1.01 1.01 1.00 182.05 Create unmapped window (200 kids)
-   28.13 1.00 1.00 1.00  30.75 Map window via parent (4 kids)
-   36.14 1.01 1.01 1.01  32.58 Map window via parent (16 kids)
-   26.13 1.00 0.98 0.95  29.85 Map window via parent (25 kids)
-   40.07 1.00 1.01 1.00  27.57 Map window via parent (50 kids)
-   23.26 0.99 1.00 1.00  18.23 Map window via parent (75 kids)
-   22.91 0.99 1.00 0.99  16.52 Map window via parent (100 kids)
-   27.79 1.00 1.00 0.99  12.50 Map window via parent (200 kids)
-   22.35 1.00 1.00 1.00  56.19 Unmap window via parent (4 kids)
-    9.57 1.00 0.99 1.00  89.78 Unmap window via parent (16 kids)
-   80.77 1.01 1.00 1.00 103.85 Unmap window via parent (25 kids)
-   96.34 1.00 1.00 1.00 116.06 Unmap window via parent (50 kids)
-   99.72 1.00 1.00 1.00 124.93 Unmap window via parent (75 kids)
-  112.36 1.00 1.00 1.00 125.27 Unmap window via parent (100 kids)
-  105.41 1.00 1.00 0.99 120.00 Unmap window via parent (200 kids)
-   51.29 1.03 1.02 1.02  74.19 Destroy window via parent (4 kids)
-   86.75 0.99 0.99 0.99 116.87 Destroy window via parent (16 kids)
-  106.43 1.01 1.01 1.01 127.49 Destroy window via parent (25 kids)
-  120.34 1.01 1.01 1.00 140.11 Destroy window via parent (50 kids)
-  126.67 1.00 0.99 0.99 145.00 Destroy window via parent (75 kids)
-  126.11 1.01 1.01 1.00 140.56 Destroy window via parent (100 kids)
-  128.57 1.01 1.00 1.00 137.91 Destroy window via parent (200 kids)
-   16.04 0.88 1.00 1.00  20.36 Hide/expose window via popup (4 kids)
-   19.04 1.01 1.00 1.00  23.48 Hide/expose window via popup (16 kids)
-   19.22 1.00 1.00 1.00  20.44 Hide/expose window via popup (25 kids)
-   17.41 1.00 0.91 0.97  17.68 Hide/expose window via popup (50 kids)
-   17.29 1.01 1.00 1.01  17.07 Hide/expose window via popup (75 kids)
-   16.74 1.00 1.00 1.00  16.17 Hide/expose window via popup (100 kids)
-   10.30 1.00 1.00 1.00  10.51 Hide/expose window via popup (200 kids)
-   16.48 1.01 1.00 1.00  26.05 Move window (4 kids)
-   17.01 0.95 1.00 1.00  23.97 Move window (16 kids)
-   16.95 1.00 1.00 1.00  22.90 Move window (25 kids)
-   16.05 1.01 1.00 1.00  21.32 Move window (50 kids)
-   15.58 1.00 0.98 0.98  19.44 Move window (75 kids)
-   14.98 1.02 1.03 1.03  18.17 Move window (100 kids)
-   10.90 1.01 1.01 1.00  12.68 Move window (200 kids)
-   49.42 1.00 1.00 1.00 198.27 Moved unmapped window (4 kids)
-   50.72 0.97 1.00 1.00 193.66 Moved unmapped window (16 kids)
-   50.87 1.00 0.99 1.00 195.09 Moved unmapped window (25 kids)
-   50.72 1.00 1.00 1.00 189.34 Moved unmapped window (50 kids)
-   50.87 1.00 1.00 1.00 191.33 Moved unmapped window (75 kids)
-   50.87 1.00 1.00 0.90 186.71 Moved unmapped window (100 kids)
-   50.87 1.00 1.00 1.00 179.19 Moved unmapped window (200 kids)
-   41.04 1.00 1.00 1.00  56.61 Move window via parent (4 kids)
-   69.81 1.00 1.00 1.00 130.82 Move window via parent (16 kids)
-   95.81 1.00 1.00 1.00 141.92 Move window via parent (25 kids)
-   95.98 1.00 1.00 1.00 149.43 Move window via parent (50 kids)
-   96.59 1.01 1.01 1.00 153.98 Move window via parent (75 kids)
-   97.19 1.00 1.00 1.00 157.30 Move window via parent (100 kids)
-   96.67 1.00 0.99 0.96 159.44 Move window via parent (200 kids)
-   17.75 1.01 1.00 1.00  27.61 Resize window (4 kids)
-   17.94 1.00 1.00 0.99  25.42 Resize window (16 kids)
-   17.92 1.01 1.00 1.00  24.47 Resize window (25 kids)
-   17.24 0.97 1.00 1.00  24.14 Resize window (50 kids)
-   16.81 1.00 1.00 0.99  22.75 Resize window (75 kids)
-   16.08 1.00 1.00 1.00  21.20 Resize window (100 kids)
-   12.92 1.00 0.99 1.00  16.26 Resize window (200 kids)
-   52.94 1.01 1.00 1.00 327.12 Resize unmapped window (4 kids)
-   53.60 1.01 1.01 1.01 333.71 Resize unmapped window (16 kids)
-   52.99 1.00 1.00 1.00 337.29 Resize unmapped window (25 kids)
-   51.98 1.00 1.00 1.00 329.38 Resize unmapped window (50 kids)
-   53.05 0.89 1.00 1.00 322.60 Resize unmapped window (75 kids)
-   53.05 1.00 1.00 1.00 318.08 Resize unmapped window (100 kids)
-   53.11 1.00 1.00 0.99 306.21 Resize unmapped window (200 kids)
-   16.76 1.00 0.96 1.00  19.46 Circulate window (4 kids)
-   17.24 1.00 1.00 0.97  16.24 Circulate window (16 kids)
-   16.30 1.03 1.03 1.03  15.85 Circulate window (25 kids)
-   13.45 1.00 1.00 1.00  14.90 Circulate window (50 kids)
-   12.91 1.00 1.00 1.00  13.06 Circulate window (75 kids)
-   11.30 0.98 1.00 1.00  11.03 Circulate window (100 kids)
-    7.58 1.01 1.01 0.99   7.47 Circulate window (200 kids)
-    1.01 1.01 0.98 1.00   0.95 Circulate Unmapped window (4 kids)
-    1.07 1.07 1.01 1.07   1.02 Circulate Unmapped window (16 kids)
-    1.04 1.09 1.06 1.05   0.97 Circulate Unmapped window (25 kids)
-    1.04 1.23 1.20 1.18   1.05 Circulate Unmapped window (50 kids)
-    1.18 1.53 1.19 1.45   1.24 Circulate Unmapped window (75 kids)
-    1.08 1.02 1.01 1.74   1.01 Circulate Unmapped window (100 kids)
-    1.01 1.12 0.98 0.91   0.97 Circulate Unmapped window (200 kids)
-
-
-
-  BB..22..88..  PPrrooffiilliinngg wwiitthh OOPPrrooffiillee
-
-  OProfile (available from http://oprofile.sourceforge.net/) is a
-  system-wide profiler for Linux systems that uses processor-level
-  counters to collect sampling data.  OProfile can provide information
-  that is similar to that provided by gprof, but without the necessity
-  of recompiling the program with special instrumentation (i.e.,
-  OProfile can collect statistical profiling information about optimized
-  programs).  A test harness was developed to collect OProfile data for
-  each x11perf test individually.
-
-
-  Test runs were performed using the RETIRED_INSNS counter on the AMD
-  Athlon and the CPU_CLK_HALTED counter on the Intel Pentium III (with a
-  test configuration different from the one described above).  We have
-  examined OProfile output and have compared it with gprof output.  This
-  investigation has not produced results that yield performance
-  increases in x11perf numbers.
-
-
-
-  BB..22..99..  XX TTeesstt SSuuiittee
-
-  The X Test Suite was run on the fully optimized DMX server using the
-  configuration described above.  The following failures were noted:
-
-  XListPixmapFormats: Test 1              [1]
-  XChangeWindowAttributes: Test 32        [1]
-  XCreateWindow: Test 30                  [1]
-  XFreeColors: Test 4                     [3]
-  XCopyArea: Test 13, 17, 21, 25, 30      [2]
-  XCopyPlane: Test 11, 15, 27, 31         [2]
-  XSetFontPath: Test 4                    [1]
-  XChangeKeyboardControl: Test 9, 10      [1]
-
-  [1] Previously documented errors expected from the Xinerama
-      implementation (see Phase I discussion).
-  [2] Newly noted errors that have been verified as expected
-      behavior of the Xinerama implementation.
-  [3] Newly noted error that has been verified as a Xinerama
-      implementation bug.
-
-
-
-  BB..33..  PPhhaassee IIIIII
-
-  During the third phase of development, support was provided for the
-  following extensions: SHAPE, RENDER, XKEYBOARD, XInput.
-
-
-  BB..33..11..  SSHHAAPPEE
-
-  The SHAPE extension is supported.  Test applications (e.g., xeyes and
-  oclock) and window managers that make use of the SHAPE extension will
-  work as expected.
-
-
-  BB..33..22..  RREENNDDEERR
-
-  The RENDER extension is supported.  The version included in the DMX
-  CVS tree is version 0.2, and this version is fully supported by Xdmx.
-  Applications using only version 0.2 functions will work correctly;
-  however, some apps that make use of functions from later versions do
-  not properly check the extension's major/minor version numbers.  These
-  apps will fail with a Bad Implementation error when using post-version
-  0.2 functions.  This is expected behavior.  When the DMX CVS tree is
-  updated to include newer versions of RENDER, support for these newer
-  functions will be added to the DMX X server.
-
-
-  BB..33..33..  XXKKEEYYBBOOAARRDD
-
-  The XKEYBOARD extension is supported.  If present on the back-end X
-  servers, the XKEYBOARD extension will be used to obtain information
-  about the type of the keyboard for initialization.  Otherwise, the
-  keyboard will be initialized using defaults.  Note that this departs
-  from older behavior: when Xdmx is compiled without XKEYBOARD support,
-  the map from the back-end X server will be preserved.  With XKEYBOARD
-  support, the map is not preserved because better information and
-  control of the keyboard is available.
-
-
-  BB..33..44..  XXIInnppuutt
-
-  The XInput extension is supported.  Any device can be used as a core
-  device and be used as an XInput extension device, with the exception
-  of core devices on the back-end servers.  This limitation is present
-  because cursor handling on the back-end requires that the back-end
-  cursor sometimes track the Xdmx core cursor -- behavior that is
-  incompatible with using the back-end pointer as a non-core device.
-
-
-  Currently, back-end extension devices are not available as Xdmx
-  extension devices, but this limitation should be removed in the
-  future.
-
-
-  To demonstrate the XInput extension, and to provide more examples for
-  low-level input device driver writers, USB device drivers have been
-  written for mice (usb-mou), keyboards (usb-kbd), and non-mouse/non-
-  keyboard USB devices (usb-oth).  Please see the man page for
-  information on Linux kernel drivers that are required for using these
-  Xdmx drivers.
-
-
-  BB..33..55..  DDPPMMSS
-
-  The DPMS extension is exported but does not do anything at this time.
-
-
-  BB..33..66..  OOtthheerr EExxtteennssiioonnss
-
-  The LBX, SECURITY, XC-APPGROUP, and XFree86-Bigfont extensions do not
-  require any special Xdmx support and have been exported.
-
-
-  The BIG-REQUESTS, DEC-XTRAP, DOUBLE-BUFFER, Extended-Visual-
-  Information, FontCache, GLX, MIT-SCREEN-SAVER, MIT-SHM, MIT-SUNDRY-
-  NONSTANDARD, RECORD, SECURITY, SGI-GLX, SYNC, TOG-CUP, X-Resource, XC-
-  MISC, XFree86-DGA, XFree86-DRI, XFree86-Misc,
-  XFree86-VidModeExtension, and XVideo extensions are _n_o_t supported at
-  this time, but will be evaluated for inclusion in future DMX releases.
-  SSeeee bbeellooww ffoorr aaddddiittiioonnaall wwoorrkk oonn eexxtteennssiioonnss aafftteerr PPhhaassee IIIIII..
-
-
-  BB..44..  PPhhaassee IIVV
-
-  BB..44..11..  MMoovviinngg ttoo XXFFrreeee8866 44..33..00
-
-  For Phase IV, the recent release of XFree86 4.3.0 (27 February 2003)
-  was merged onto the dmx.sourceforge.net CVS trunk and all work is
-  proceeding using this tree.
-
-
-  BB..44..22..  EExxtteennssiioonnss
-
-  BB..44..22..11..  XXCC--MMIISSCC ((ssuuppppoorrtteedd))
-
-  XC-MISC is used internally by the X library to recycle XIDs from the X
-  server.  This is important for long-running X server sessions.  Xdmx
-  supports this extension.  The X Test Suite passed and failed the exact
-  same tests before and after this extension was enabled.
-
-
-  BB..44..22..22..  EExxtteennddeedd--VViissuuaall--IInnffoorrmmaattiioonn ((ssuuppppoorrtteedd))
-
-  The Extended-Visual-Information extension provides a method for an X
-  client to obtain detailed visual information.  Xdmx supports this
-  extension.  It was tested using the hw/dmx/examples/evi example
-  program.  NNoottee tthhaatt tthhiiss eexxtteennssiioonn iiss nnoott XXiinneerraammaa--aawwaarree -- it will
-  return visual information for each screen even though Xinerama is
-  causing the X server to export a single logical screen.
-
-
-  BB..44..22..33..  RREESS ((ssuuppppoorrtteedd))
-
-  The X-Resource extension provides a mechanism for a client to obtain
-  detailed information about the resources used by other clients.  This
-  extension was tested with the hw/dmx/examples/res program.  The X Test
-  Suite passed and failed the exact same tests before and after this
-  extension was enabled.
-
-
-  BB..44..22..44..  BBIIGG--RREEQQUUEESSTTSS ((ssuuppppoorrtteedd))
-
-  This extension enables the X11 protocol to handle requests longer than
-  262140 bytes.  The X Test Suite passed and failed the exact same tests
-  before and after this extension was enabled.
-
-
-  BB..44..22..55..  XXSSYYNNCC ((ssuuppppoorrtteedd))
-
-  This extension provides facilities for two different X clients to
-  synchronize their requests.  This extension was minimally tested with
-  xdpyinfo and the X Test Suite passed and failed the exact same tests
-  before and after this extension was enabled.
-
-
-  BB..44..22..66..  XXTTEESSTT,, RREECCOORRDD,, DDEECC--XXTTRRAAPP ((ssuuppppoorrtteedd)) aanndd XXTTeessttEExxtteennssiioonn11
-  ((nnoott ssuuppppoorrtteedd))
-
-  The XTEST and RECORD extension were developed by the X Consortium for
-  use in the X Test Suite and are supported as a standard in the X11R6
-  tree.  They are also supported in Xdmx.  When X Test Suite tests that
-  make use of the XTEST extension are run, Xdmx passes and fails exactly
-  the same tests as does a standard XFree86 X server.  When the rcrdtest
-  test (a part of the X Test Suite that verifies the RECORD extension)
-  is run, Xdmx passes and fails exactly the same tests as does a
-  standard XFree86 X server.
-
-
-  There are two older XTEST-like extensions: DEC-XTRAP and
-  XTestExtension1.  The XTestExtension1 extension was developed for use
-  by the X Testing Consortium for use with a test suite that eventually
-  became (part of?) the X Test Suite.  Unlike XTEST, which only allows
-  events to be sent to the server, the XTestExtension1 extension also
-  allowed events to be recorded (similar to the RECORD extension).  The
-  second is the DEC-XTRAP extension that was developed by the Digital
-  Equipment Corporation.
-
-
-  The DEC-XTRAP extension is available from Xdmx and has been tested
-  with the xtrap* tools which are distributed as standard X11R6 clients.
-
-
-  The XTestExtension1 is _n_o_t supported because it does not appear to be
-  used by any modern X clients (the few that support it also support
-  XTEST) and because there are no good methods available for testing
-  that it functions correctly (unlike XTEST and DEC-XTRAP, the code for
-  XTestExtension1 is not part of the standard X server source tree, so
-  additional testing is important).
-
-
-  Most of these extensions are documented in the X11R6 source tree.
-  Further, several original papers exist that this author was unable to
-  locate -- for completeness and historical interest, citations are
-  provide:
-
-     XXRREECCOORRDD
-        Martha Zimet. Extending X For Recording.  8th Annual X Technical
-        Conference Boston, MA January 24-26, 1994.
-
-     DDEECC--XXTTRRAAPP
-        Dick Annicchiarico, Robert Chesler, Alan Jamison. XTrap
-        Architecture. Digital Equipment Corporation, July 1991.
-
-     XXTTeessttEExxtteennssiioonn11
-        Larry Woestman. X11 Input Synthesis Extension Proposal. Hewlett
-        Packard, November 1991.
-
-
-  BB..44..22..77..  MMIITT--MMIISSCC ((nnoott ssuuppppoorrtteedd))
-
-  The MIT-MISC extension is used to control a bug-compatibility flag
-  that provides compatibility with xterm programs from X11R1 and X11R2.
-  There does not appear to be a single client available that makes use
-  of this extension and there is not way to verify that it works
-  correctly.  The Xdmx server does _n_o_t support MIT-MISC.
-
-
-  BB..44..22..88..  SSCCRREEEENNSSAAVVEERR ((nnoott ssuuppppoorrtteedd))
-
-  This extension provides special support for the X screen saver.  It
-  was tested with beforelight, which appears to be the only client that
-  works with it.  When Xinerama was not active, beforelight behaved as
-  expected.  However, when Xinerama was active, beforelight did not
-  behave as expected.  Further, when this extension is not active,
-  xscreensaver (a widely-used X screen saver program) did not behave as
-  expected.  Since this extension is not Xinerama-aware and is not
-  commonly used with expected results by clients, we have left this
-  extension disabled at this time.
-
-  BB..44..22..99..  GGLLXX ((ssuuppppoorrtteedd))
-
-  The GLX extension provides OpenGL and GLX windowing support.  In Xdmx,
-  the extension is called glxProxy, and it is Xinerama aware.  It works
-  by either feeding requests forward through Xdmx to each of the back-
-  end servers or handling them locally.  All rendering requests are
-  handled on the back-end X servers.  This code was donated to the DMX
-  project by SGI.  For the X Test Suite results comparison, see below.
-
-
-  BB..44..22..1100..  RREENNDDEERR ((ssuuppppoorrtteedd))
-
-  The X Rendering Extension (RENDER) provides support for digital image
-  composition.  Geometric and text rendering are supported.  RENDER is
-  partially Xinerama-aware, with text and the most basic compositing
-  operator; however, its higher level primitives (triangles, triangle
-  strips, and triangle fans) are not yet Xinerama-aware.  The RENDER
-  extension is still under development, and is currently at version 0.8.
-  Additional support will be required in DMX as more primitives and/or
-  requests are added to the extension.
-
-
-  There is currently no test suite for the X Rendering Extension;
-  however, there has been discussion of developing a test suite as the
-  extension matures.  When that test suite becomes available, additional
-  testing can be performed with Xdmx.  The X Test Suite passed and
-  failed the exact same tests before and after this extension was
-  enabled.
-
-
-  BB..44..22..1111..  SSuummmmaarryy
-
-  To summarize, the following extensions are currently supported: BIG-
-  REQUESTS, DEC-XTRAP, DMX, DPMS, Extended-Visual-Information, GLX, LBX,
-  RECORD, RENDER, SECURITY, SHAPE, SYNC, X-Resource, XC-APPGROUP, XC-
-  MISC, XFree86-Bigfont, XINERAMA, XInputExtension, XKEYBOARD, and
-  XTEST.
-
-
-  The following extensions are _n_o_t supported at this time: DOUBLE-
-  BUFFER, FontCache, MIT-SCREEN-SAVER, MIT-SHM, MIT-SUNDRY-NONSTANDARD,
-  TOG-CUP, XFree86-DGA, XFree86-Misc, XFree86-VidModeExtension,
-  XTestExtensionExt1, and XVideo.
-
-
-  BB..44..33..  AAddddiittiioonnaall TTeessttiinngg wwiitthh tthhee XX TTeesstt SSuuiittee
-
-  BB..44..33..11..  XXFFrreeee8866 wwiitthhoouutt XXTTEESSTT
-
-  After the release of XFree86 4.3.0, we retested the XFree86 X server
-  with and without using the XTEST extension.  When the XTEST extension
-  was _n_o_t used for testing, the XFree86 4.3.0 server running on our
-  usual test system with a Radeon VE card reported unexpected failures
-  in the following tests:
-
-  XListPixmapFormats: Test 1
-  XChangeKeyboardControl: Tests 9, 10
-  XGetDefault: Test 5
-  XRebindKeysym: Test 1
-
-
-
-  BB..44..33..22..  XXFFrreeee8866 wwiitthh XXTTEESSTT
-
-  When using the XTEST extension, the XFree86 4.3.0 server reported the
-  following errors:
-
-  XListPixmapFormats: Test 1
-  XChangeKeyboardControl: Tests 9, 10
-  XGetDefault: Test 5
-  XRebindKeysym: Test 1
-
-  XAllowEvents: Tests 20, 21, 24
-  XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
-  XGrabKey: Test 8
-  XSetPointerMapping: Test 3
-  XUngrabButton: Test 4
-
-
-
-  While these errors may be important, they will probably be fixed
-  eventually in the XFree86 source tree.  We are particularly interested
-  in demonstrating that the Xdmx server does not introduce additional
-  failures that are not known Xinerama failures.
-
-
-  BB..44..33..33..  XXddmmxx wwiitthh XXTTEESSTT,, wwiitthhoouutt XXiinneerraammaa,, wwiitthhoouutt GGLLXX
-
-  Without Xinerama, but using the XTEST extension, the following errors
-  were reported from Xdmx (note that these are the same as for the
-  XFree86 4.3.0, except that XGetDefault no longer fails):
-
-  XListPixmapFormats: Test 1
-  XChangeKeyboardControl: Tests 9, 10
-  XRebindKeysym: Test 1
-
-  XAllowEvents: Tests  20, 21, 24
-  XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
-  XGrabKey: Test 8
-  XSetPointerMapping: Test 3
-  XUngrabButton: Test 4
-
-
-
-  BB..44..33..44..  XXddmmxx wwiitthh XXTTEESSTT,, wwiitthh XXiinneerraammaa,, wwiitthhoouutt GGLLXX
-
-  With Xinerama, using the XTEST extension, the following errors were
-  reported from Xdmx:
-
-  XListPixmapFormats: Test 1
-  XChangeKeyboardControl: Tests 9, 10
-  XRebindKeysym: Test 1
-
-  XAllowEvents: Tests 20, 21, 24
-  XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
-  XGrabKey: Test 8
-  XSetPointerMapping: Test 3
-  XUngrabButton: Test 4
-
-  XCopyPlane: Tests 13, 22, 31 (well-known XTEST/Xinerama interaction issue)
-  XDrawLine: Test 67
-  XDrawLines: Test 91
-  XDrawSegments: Test 68
-
-
-
-  Note that the first two sets of errors are the same as for the XFree86
-  4.3.0 server, and that the XCopyPlane error is a well-known error
-  resulting from an XTEST/Xinerama interaction when the request crosses
-  a screen boundary.  The XDraw* errors are resolved when the tests are
-  run individually and they do not cross a screen boundary.  We will
-  investigate these errors further to determine their cause.
-
-
-  BB..44..33..55..  XXddmmxx wwiitthh XXTTEESSTT,, wwiitthh XXiinneerraammaa,, wwiitthh GGLLXX
-
-  With GLX enabled, using the XTEST extension, the following errors were
-  reported from Xdmx (these results are from early during the Phase IV
-  development, but were confirmed with a late Phase IV snapshot):
-
-  XListPixmapFormats: Test 1
-  XChangeKeyboardControl: Tests 9, 10
-  XRebindKeysym: Test 1
-
-  XAllowEvents: Tests 20, 21, 24
-  XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
-  XGrabKey: Test 8
-  XSetPointerMapping: Test 3
-  XUngrabButton: Test 4
-
-  XClearArea: Test 8
-  XCopyArea: Tests 4, 5, 11, 14, 17, 23, 25, 27, 30
-  XCopyPlane: Tests 6, 7, 10, 19, 22, 31
-  XDrawArcs: Tests 89, 100, 102
-  XDrawLine: Test 67
-  XDrawSegments: Test 68
-
-
-  Note that the first two sets of errors are the same as for the XFree86
-  4.3.0 server, and that the third set has different failures than when
-  Xdmx does not include GLX support.  Since the GLX extension adds new
-  visuals to support GLX's visual configs and the X Test Suite runs
-  tests over the entire set of visuals, additional rendering tests were
-  run and presumably more of them crossed a screen boundary.  This con-
-  clusion is supported by the fact that nearly all of the rendering
-  errors reported are resolved when the tests are run individually and
-  they do no cross a screen boundary.
-
-
-  Further, when hardware rendering is disabled on the back-end displays,
-  many of the errors in the third set are eliminated, leaving only:
-
-  XClearArea: Test 8
-  XCopyArea: Test 4, 5, 11, 14, 17, 23, 25, 27, 30
-  XCopyPlane: Test 6, 7, 10, 19, 22, 31
-
-
-
-  BB..44..33..66..  CCoonncclluussiioonn
-
-  We conclude that all of the X Test Suite errors reported for Xdmx are
-  the result of errors in the back-end X server or the Xinerama
-  implementation.  Further, all of these errors that can be reasonably
-  fixed at the Xdmx layer have been.  (Where appropriate, we have
-  submitted patches to the XFree86 and Xinerama upstream maintainers.)
-
-
-  BB..44..44..  DDyynnaammiicc RReeccoonnffiigguurraattiioonn
-
-  During this development phase, dynamic reconfiguration support was
-  added to DMX.  This support allows an application to change the
-  position and offset of a back-end server's screen.  For example, if
-  the application would like to shift a screen slightly to the left, it
-  could query Xdmx for the screen's <x,y> position and then dynamically
-  reconfigure that screen to be at position <x+10,y>.  When a screen is
-  dynamically reconfigured, input handling and a screen's root window
-  dimensions are adjusted as needed.  These adjustments are transparent
-  to the user.
-
-
-  BB..44..44..11..  DDyynnaammiicc rreeccoonnffiigguurraattiioonn eexxtteennssiioonn
-
-  The application interface to DMX's dynamic reconfiguration is through
-  a function in the DMX extension library:
-
-  Bool DMXReconfigureScreen(Display *dpy, int screen, int x, int y)
-
-
-  where _d_p_y is DMX server's display, _s_c_r_e_e_n is the number of the screen
-  to be reconfigured, and _x and _y are the new upper, left-hand coordi-
-  nates of the screen to be reconfigured.
-
-
-  The coordinates are not limited other than as required by the X
-  protocol, which limits all coordinates to a signed 16 bit number.  In
-  addition, all coordinates within a screen must also be legal values.
-  Therefore, setting a screen's upper, left-hand coordinates such that
-  the right or bottom edges of the screen is greater than 32,767 is
-  illegal.
-
-
-  BB..44..44..22..  BBoouunnddiinngg bbooxx
-
-  When the Xdmx server is started, a bounding box is calculated from the
-  screens' layout given either on the command line or in the
-  configuration file.  This bounding box is currently fixed for the
-  lifetime of the Xdmx server.
-
-
-  While it is possible to move a screen outside of the bounding box, it
-  is currently not possible to change the dimensions of the bounding
-  box.  For example, it is possible to specify coordinates of
-  <-100,-100> for the upper, left-hand corner of the bounding box, which
-  was previously at coordinates <0,0>.  As expected, the screen is moved
-  down and to the right; however, since the bounding box is fixed, the
-  left side and upper portions of the screen exposed by the
-  reconfiguration are no longer accessible on that screen.  Those
-  inaccessible regions are filled with black.
-
-
-  This fixed bounding box limitation will be addressed in a future
-  development phase.
-
-
-  BB..44..44..33..  SSaammppllee aapppplliiccaattiioonnss
-
-  An example of where this extension is useful is in setting up a video
-  wall.  It is not always possible to get everything perfectly aligned,
-  and sometimes the positions are changed (e.g., someone might bump into
-  a projector).  Instead of physically moving projectors or monitors, it
-  is now possible to adjust the positions of the back-end server's
-  screens using the dynamic reconfiguration support in DMX.
-
-
-  Other applications, such as automatic setup and calibration tools, can
-  make use of dynamic reconfiguration to correct for projector alignment
-  problems, as long as the projectors are still arranged rectilinearly.
-  Horizontal and vertical keystone correction could be applied to
-  projectors to correct for non-rectilinear alignment problems; however,
-  this must be done external to Xdmx.
-
-
-  A sample test program is included in the DMX server's examples
-  directory to demonstrate the interface and how an application might
-  use dynamic reconfiguration.  See dmxreconfig.c for details.
-
-
-  BB..44..44..44..  AAddddiittiioonnaall nnootteess
-
-  In the original development plan, Phase IV was primarily devoted to
-  adding OpenGL support to DMX; however, SGI became interested in the
-  DMX project and developed code to support OpenGL/GLX.  This code was
-  later donated to the DMX project and integrated into the DMX code
-  base, which freed the DMX developers to concentrate on dynamic
-  reconfiguration (as described above).
-
-
-  BB..44..55..  DDooxxyyggeenn ddooccuummeennttaattiioonn
-
-  Doxygen is an open-source (GPL) documentation system for generating
-  browseable documentation from stylized comments in the source code.
-  We have placed all of the Xdmx server and DMX protocol source code
-  files under Doxygen so that comprehensive documentation for the Xdmx
-  source code is available in an easily browseable format.
-
-
-  BB..44..66..  VVaallggrriinndd
-
-  Valgrind, an open-source (GPL) memory debugger for Linux, was used to
-  search for memory management errors.  Several memory leaks were
-  detected and repaired.  The following errors were not addressed:
-
-  1. When the X11 transport layer sends a reply to the client, only
-     those fields that are required by the protocol are filled in --
-     unused fields are left as uninitialized memory and are therefore
-     noted by valgrind.  These instances are not errors and were not
-     repaired.
-
-  2. At each server generation, glxInitVisuals allocates memory that is
-     never freed.  The amount of memory lost each generation
-     approximately equal to 128 bytes for each back-end visual.  Because
-     the code involved is automatically generated, this bug has not been
-     fixed and will be referred to SGI.
-
-  3. At each server generation, dmxRealizeFont calls XLoadQueryFont,
-     which allocates a font structure that is not freed.
-     dmxUnrealizeFont can free the font structure for the first screen,
-     but cannot free it for the other screens since they are already
-     closed by the time dmxUnrealizeFont could free them.  The amount of
-     memory lost each generation is approximately equal to 80 bytes per
-     font per back-end.  When this bug is fixed in the the X server's
-     device-independent (dix) code, DMX will be able to properly free
-     the memory allocated by XLoadQueryFont.
-
-
-  BB..44..77..  RRAATTSS
-
-  RATS (Rough Auditing Tool for Security) is an open-source (GPL)
-  security analysis tool that scans source code for common security-
-  related programming errors (e.g., buffer overflows and TOCTOU races).
-  RATS was used to audit all of the code in the hw/dmx directory and all
-  "High" notations were checked manually.  The code was either re-
-  written to eliminate the warning, or a comment containing "RATS" was
-  inserted on the line to indicate that a human had checked the code.
-  Unrepaired warnings are as follows:
-
-  1. Fixed-size buffers are used in many areas, but code has been added
-     to protect against buffer overflows (e.g., XmuSnprint).  The only
-     instances that have not yet been fixed are in config/xdmxconfig.c
-     (which is not part of the Xdmx server) and input/usb-common.c.
-
-  2. vprintf and vfprintf are used in the logging routines.  In general,
-     all uses of these functions (e.g., dmxLog) provide a constant
-     format string from a trusted source, so the use is relatively
-     benign.
-
-  3. glxProxy/glxscreens.c uses getenv and strcat.  The use of these
-     functions is safe and will remain safe as long as ExtensionsString
-     is longer then GLXServerExtensions (ensuring this may not be ovious
-     to the casual programmer, but this is in automatically generated
-     code, so we hope that the generator enforces this constraint).
-
-
-
diff --git a/hw/dmx/doc/scaled.txt b/hw/dmx/doc/scaled.txt
deleted file mode 100644
index d30105d..0000000
--- a/hw/dmx/doc/scaled.txt
+++ /dev/null
@@ -1,579 +0,0 @@
-  Scaled Window Support in DMX
-  Rickard E. Faith and Kevin E. Martin
-  15 October 2003 (created 19 September 2003)
-
-  This document investigates the possibility of adding scaled window
-  support to the DMX X server, thereby allowing a window or some
-  selected part of the logical DMX area to be displayed using a scaling
-  factor.  For example, this might allow the contents of a window to be
-  magnified for easier viewing.  In particular, scaling for the VNC
-  client is explored.  _C_o_p_y_r_i_g_h_t _2_0_0_3 _b_y _R_e_d _H_a_t_, _I_n_c_._, _R_a_l_e_i_g_h_, _N_o_r_t_h
-  _C_a_r_o_l_i_n_a
-
-  ______________________________________________________________________
-
-  Table of Contents
-
-
-  1. Introduction
-     1.1 DMX
-     1.2 Problem Statement
-     1.3 Task
-
-  2. Previous Work
-     2.1 VNC
-        2.1.1 Scaling under VNC
-     2.2 The X Video Extension
-
-  3. Possible Solutions
-     3.1 VNC-like Scaling
-        3.1.1 Software Scaling
-        3.1.2 Scaling with the X Video Extension
-           3.1.2.1 Implementing the X Video Extension for DMX
-           3.1.2.2 Supporting RGB formats for the X Video Extension
-        3.1.3 Scaling with an XPutImageScaled Extension
-        3.1.4 Scaling with an XCopyAreaScaled Extension
-        3.1.5 Scaling with OpenGL
-     3.2 Application-transparent Scaling for DMX
-        3.2.1 Back-end Scaling Without Disconnect/Reconnect
-        3.2.2 Back-end Scaling With Disconnect/Reconnect
-        3.2.3 Server-side Scaling
-     3.3 XCreateScaledWindow API
-        3.3.1 XCreateWindow
-        3.3.2 XSetWindowAttributes
-        3.3.3 XGetWindowAttributes, XGetGeometry
-        3.3.4 Popup and Child window positions
-        3.3.5 Events
-        3.3.6 Implementation
-
-  4. Conclusion and Recommendations
-
-
-  ______________________________________________________________________
-
-  11..  IInnttrroodduuccttiioonn
-
-  11..11..  DDMMXX
-
-  The DMX X server (Xdmx) is a proxy server that is designed to allow X
-  servers on multiple machines to be combined into a single multi-headed
-  X server.  Combined with Xinerama, these heads can appear as a single
-  very high-resolution screen.  Typical applications include the
-  creation of a video wall with 16 1280x1024 displays arranged in a
-  rectangle, for a total resolution of of 5120x4096.
-
-
-
-  11..22..  PPrroobblleemm SSttaatteemmeenntt
-
-  Applications displayed on a physically large video wall that provides
-  high pixel-resolution may be difficult to see, especially if the
-  application is designed for use on a typical desktop computer with a
-  relatively small display located close to the human operator.  The
-  goal of this paper is to describe and discuss solutions to this
-  problem.
-
-  The original driving problem for this work is to provide scaling for
-  the vncviewer application when displayed using DMX (VNC scaling is
-  currently available only with the Windows client, and there is no plan
-  to extend that capability to other clients).  While this specific
-  problem will be addressed in this paper, the general solution space
-  will also be explored, since this may lead to a good solution not only
-  for vncviewer but also for other applications.
-
-  11..33..  TTaasskk
-
-  For reference, here is the original description of the task this paper
-  addresses:
-
-  +o  Scaled window support (for VNC)
-
-     +o  Investigate possibility of implementing a "scaled window"
-        extension:
-
-        +o  Add XCreateScaledWindow call that could be used in place of
-           XCreateWindow
-
-        +o  All primitives drawn to scaled window would be scaled by
-           appropriate (integral?) scaling factor
-
-     +o  Alternate approach: special case VNC support
-
-  22..  PPrreevviioouuss WWoorrkk
-
-  This section reviews relevant previous work.
-
-  22..11..  VVNNCC
-
-  22..11..11..  SSccaalliinngg uunnddeerr VVNNCC
-
-  When using the vncviewer program for Windows, it is possible to
-  specify a scaling factor (as numerator and denominator).  When scaling
-  is in effect, the viewer software uses StretchBlt (instead of BitBlt)
-  to display the pixels for the user.  When this call is made, the
-  viewer already has received all of the pixel information (at full
-  unscaled resolution).
-
-  The scaling in VNC is primitive.  It does not conserve bandwidth, it
-  does not treat textual information differently (i.e., by using a
-  suitably scaled font), and it does not provide any anti-aliasing other
-  than that provided by the underlying (Windows-only) system library.
-
-  22..22..  TThhee XX VViiddeeoo EExxtteennssiioonn
-
-  The X Video Extension is a widely-available extension to the X11
-  protocol that provides support for streaming video.  Integral to this
-  support is the ability to arbitrarily scale the output.  In version
-  2.2 of the X Video specification, support for scaled still images was
-  provided, using both shared memory and traditional transport.  The API
-  for this support uses calls that are quite similar to XCreateWindow,
-  XPutImage, and XShmPutImage.  Currently, most of the drivers
-  implemented in XFree86 only support data in various YUV formats.
-  However, several modern video adaptors support RGB as well.
-  Note, though, that the target output for this scaling is an overlay
-  plane -- so X Video provides functionality that is fundamentally
-  different from that provided by the Windows StrechBlt call.
-
-  33..  PPoossssiibbllee SSoolluuttiioonnss
-
-  This section briefly discusses possible solutions, including major
-  advantages and disadvantages from both the implementation and the end-
-  user programmer standpoint.
-
-  33..11..  VVNNCC--lliikkee SSccaalliinngg
-
-  33..11..11..  SSooffttwwaarree SSccaalliinngg
-
-  The vncviewer application could be modified to provide software
-  scaling.  This is not a general solution, but it does solve one of the
-  goals of this work.
-
-  A prototype of this solution was implemented and a patch against
-  vnc-3.3.7-unixsrc is available in the dmx/external directory.  Because
-  of limited time available for this work, all of the edge cases were
-  not considered and the solution works well mainly for integer scaling.
-
-  Currently, vncviewer writes to the X display with XPutImage,
-  XCopyArea, and XFillRectangle.  All instances of these calls have to
-  be aware of scaling and must round correctly.  In the prototype
-  solution, rounding is incorrect and can cause artifacts.
-
-  A better solution would be to cache all updates to the desktop image
-  in vncviewer and only send the damaged area to the X display with
-  XPutImage.  This would allow the damaged area to be computed so that
-  rounding errors do not create artifacts.  This method is probably
-  similar to what is used in the Window client.  (The whole VNC suite is
-  being re-written in C++ and the forthcoming version 4 has not been
-  evaluated.)
-
-  33..11..22..  SSccaalliinngg wwiitthh tthhee XX VViiddeeoo EExxtteennssiioonn
-
-  The scaling in the Windows vncviewer application makes use of a scaled
-  blit that is supplied by the underlying system library.  Several video
-  cards currently provide support for a scaled blit, and some X servers
-  (including XFree86) expose this capability to applications via the
-  XvPutImage interface of the X Video Extension.  The capability exposed
-  by XvPutImage results in the scaled image being drawn to an overlay
-  plane.  Most video cards also provide support for a scaled blit into
-  the normal output planes, but this is not exposed via XvPutImage.
-
-  The vncviewer program could be modified to use the X Video Extension
-  to provide scaling under X11 that is similar to the scaling currently
-  provided under Windows.  Unfortunately, Xdmx does not currently export
-  the X Video Extension, so this would not provide an immediate solution
-  usable with DMX.
-
-  A very early-stage proof-of-concept prototype was implemented and a
-  preliminary patch against vnc-3.3.7-unixsrc is available in the
-  dmx/external directory.  This prototype was implemented to better
-  understand the problems that must be solved to make this solution
-  viable:
-
-  +o  As noted under the software scaling section above, vncviewer writes
-     to the X display with several different calls.  These calls write
-     to the normal output planes and are compatible with XvPutImage,
-     which writes to an overlay plane.  To eliminate artifacts caused by
-     this problem, vncviewer should be modified so that a cached copy of
-     the desktop is available, either as a client-side image or a
-     server-side off-screen pixmap, so that XvPutImage would be the only
-     method for writing to the X display.
-
-  +o
-
-     Although several modern graphics adaptors support hardware scaling
-     using an RGB format (e.g., ATI Radeon, nVidia, etc.), XFree86
-     drivers typically only implement YUV formats.  YUV generally
-     compress the pixel information in some way.  For example, two
-     commonly implemented formats, YUY2 and UYVY provide intensity
-     information for every RGB pixel, but only provide chroma and
-     luminance information for pairs of horizontal pixels.  Since VNC
-     uses pixel-resolution for communicating updates on the wire,
-     additional artifacts are introduced (because there may not be
-     enough information from the wire to update a pair of pixels).
-
-     Further, the well-known problem with YUV encoding is even more
-     evident when the image is a desktop instead of a movie.  For
-     example, consider a 1-pixel-wide vertical window border.  If the
-     border changes in color but not intensity (e.g., because a window
-     manager uses color to indicate focus), there may or may not be a
-     change in the YUY2 image, depending on the algorithm used for RGB
-     to YUV conversion and on how the border pixel is ordered in the
-     pair of pixels used by the algorithm.
-
-     Many of these artifacts could be eliminated if vncviewer cached a
-     complete RGB image of the desktop, and only did the conversion to
-     YUV for properly aligned areas of damage.  The remaining artifacts
-     could be eliminated if an RGB format was used with X Video (which
-     may require the extension of existing XFree86 drivers to support
-     RGB).
-
-  +o  Most modern video cards support exactly one overlay plane that is
-     suitable for use with X Video.  Therefore, only one application can
-     use X Video at any given time.  This is a severe limitation in a
-     desktop environment.
-
-  33..11..22..11..  IImmpplleemmeennttiinngg tthhee XX VViiddeeoo EExxtteennssiioonn ffoorr DDMMXX
-
-  The user-level API for X Video is fairly simple, but the underlying
-  support required for the full specification is large.  However, since
-  the API provides a method to query supported capabilities, a usable
-  subset of X Video can be implemented that would support XvPutImage and
-  little else.  This would require support for the following:
-
-  +o  X Video Extension API calls, including the following:
-
-     +o  XvQueryExtension
-
-     +o  XvQueryAdaptors
-
-     +o  XvQueryPortAttributes
-
-     +o  XvFreeAdaptorInfo
-
-     +o  XvListImageFormats
-
-     +o  XvGrabPort
-
-     +o  XvCreateImage
-
-     +o  XvPutImage
-
-     +o  XvShmCreateImage
-
-     +o  XvShmPutImage
-
-  +o  Support for querying back-end X Video Extension capabilities.
-
-  +o  Support for sending the image to the back-ends.  Because X Video
-     requires sending full images, there may be a trade-off between
-     bandwidth limitations and additional complexity to divide the image
-     up such that is scales properly.
-
-  +o  Possible support for a software fall-back.  For example, if all of
-     the back-ends do not support the X Video Extension, software
-     scaling can be implemented such that the image is sent to the back-
-     end with XPutImage.  This pathway would have poor performance.
-
-  33..11..22..22..  SSuuppppoorrttiinngg RRGGBB ffoorrmmaattss ffoorr tthhee XX VViiddeeoo EExxtteennssiioonn
-
-  Assuming an XFree86 driver already supports the X Video Extension, and
-  assuming the target hardware supports an RGB format, then adding
-  support for that format is relatively simple and straightforward.
-
-  33..11..33..  SSccaalliinngg wwiitthh aann XXPPuuttIImmaaggeeSSccaalleedd EExxtteennssiioonn
-
-  Instead of (or in addition to) implementing the X Video Extension in
-  DMX, one obvious solution would be to implement a new extension that
-  provides access to hardware-assisted scaled blits, similar to the
-  StretchBlt call available under Windows.  This call would scale RGB
-  images and would not use the overlay plane (unlike the X Video
-  Extension).
-
-  This approach has many of the same advantages and disadvantages as the
-  XCopyAreaScaled Extension, discussed in the next section.  Discussion
-  of XPutImageScaled is deferred in favor of XCopyAreaScaled for the
-  following reasons:
-
-  +o  XPutImageScaled can be emulated with XCopyAreaScaled by first using
-     XPutImage to copy the image to an off-screen pixmap, and then
-     calling XCopyAreaScaled between that off-screen pixmap and the
-     target drawable.
-
-  +o  Since XCopyAreaScaled would copy between two areas of on-screen or
-     off-screen memory, it has additional uses and can be viewed as
-     efficiently providing a superset of XPutImageScaled functionality.
-
-  33..11..44..  SSccaalliinngg wwiitthh aann XXCCooppyyAArreeaaSSccaalleedd EExxtteennssiioonn
-
-  As noted in the previous section, because XCopyAreaScaled provides a
-  superset of the functionality provided by XPutImageScaled, we will
-  consider this extension instead.
-
-  First, XCopyAreaScaled would provide for RGB scaling between pixmaps
-  (i.e., on-screen or off-screen areas of memory that reside on the
-  video card).  Unlike the X Video Extension, which writes into an
-  overlay plane, XCopyAreaScaled would write into the non-overlay areas
-  of the screen.  Key points to consider are as follows:
-
-  +o  Because different planes are involved, the two scaling operations
-     are usually implemented in hardware differently, so an
-     XCopyAreaScaled extension could be added in a manner that would
-     neither conflict with nor interact with the X Video extension in
-     any way.
-
-  +o  The XCopyAreaScaled extension provides new functionality that the X
-     Video Extension does not provide.  Based on anecdotal feedback, we
-     believe that many people outside the DMX and VNC communities would
-     be excited about this extension.
-
-  +o  The main drawback to this extension is that it is new and needs to
-     be implemented at the driver level in XFree86 for each video card
-     to be supported.  At the present time, it is more likely that the X
-     Video Extension will be implemented for a particular piece hardware
-     because the X Video extension has multimedia uses.  However, over
-     time, we would expect the XCopyAreaScaled extension to be
-     implemented along with the X Video extension, especially if it
-     becomes popular.
-
-  +o  Another drawback is that not all modern cards provide support for a
-     simple scaled blit operation.  However, these cards usually do
-     provide a 3D pipeline which could be used to provide this
-     functionality in a manner that is transparent to the client
-     application that is using the XCopyAreaScaled extension.  However,
-     this implementation pathway would make this extension somewhat more
-     difficult to implement on certain cards.
-
-  33..11..55..  SSccaalliinngg wwiitthh OOppeennGGLL
-
-  Another general solution to the scaling problem is to use the texture
-  scaling found in all 3D hardware.  This ability is already exposed
-  through OpenGL and can be exploited by clients without X server
-  modification (i.e., other than the ability to support OpenGL).  An
-  application using OpenGL would transmit the non-scaled image to the X
-  server as a texture, and would then display a single non-transformed
-  rect using that texture.  This also works around the single overlay
-  problem with the X Video Extension as well as the need to implement
-  additional scaled primitive extensions.
-
-  The downside is that most OpenGL implementations require power of 2
-  texture sizes and this can be very wasteful of memory if, for example,
-  the application needs to scale a 1025x1025 image, which would require
-  a 2048x2048 texture area (even a 640x480 image would require a
-  1024x512 texture).  Another downside is that some OpenGL
-  implementations have a limited about of texture memory and cannot
-  handle textures that are very large.  For example, they might limit
-  the texture size to 1024x1024.
-
-  33..22..  AApppplliiccaattiioonn--ttrraannssppaarreenntt SSccaalliinngg ffoorr DDMMXX
-
-  33..22..11..  BBaacckk--eenndd SSccaalliinngg WWiitthhoouutt DDiissccoonnnneecctt//RReeccoonnnneecctt
-
-  VNC does scaling on the client side (in the vncviewer application).
-  Implementing a similar solution for DMX would require support in the
-  back-end X servers and, therefore, is not a general solution.
-
-  XFree86 already implements some support for "scaling" that could be
-  used with DMX: if, in the XF86Config file, multiple Modes are listed
-  in the Display Subsection of the Screen Section, then pressing Ctrl-
-  Alt-Plus and Ctrl-Alt-Minus can be used to iterate through the listed
-  modes.  The display dimensions will change to the dimensions in the
-  Modes line, but the logical dimensions of the X server (i.e., the
-  dimensions that Xdmx knows about) will not change.
-
-  Further, the dimensions of the XFree86 display are under software
-  control (via the XFree86-VidModeExtension), so the Xdmx server could
-  change the screen dimensions on a per-display basis, thereby scaling
-  the information on part of that display.
-
-  However, this scaling appears to have limited use.  For example,
-  assume a 4 by 4 display wall consisting of 16 1280x1024 displays.  If
-  all of the back-end servers were simultaneously configured to display
-  640x480, the left hand corner of each display would be magnified, but
-  the composite result would be unreadable.  Magnifying one display at a
-  time could be usable, but could have limited utility, since the result
-  would still be no larger than a single display.
-
-
-  33..22..22..  BBaacckk--eenndd SSccaalliinngg WWiitthh DDiissccoonnnneecctt//RReeccoonnnneecctt
-
-  Disconnect and reconnect features are not currently supported in DMX,
-  but are scheduled to be implemented in the future.  These features,
-  combined with the XFree86-VidModeExtension Extension, would allow an
-  application to do the following:
-
-  +o  Disconnect a specific back-end server (via the DMX Extension),
-
-  +o  reconfigure the XFree86 back-end server resolution, and
-
-  +o  reconnect the back-end server to DMX -- at a new origin with the
-     new screen resolution.
-
-  For example, consider a display wall consisting of 16 1280x1024
-  displays with a total resolution of 5120x4096.  All of the screens
-  could be disconnected, repositioned, and reconnected each at a
-  resolution of 640x480.  The total resolution of the display wall would
-  be 2560x1920, allowing a view of a selected area approximately one-
-  fourth of the size of the DMX display.  This change would be
-  completely application independent (except, perhaps, for a DMX-aware
-  window manager).  When work at the increased resolution was completed,
-  the back-end servers could be disconnected, reconfigured, and
-  reconnected for the original 5120x4096 view.
-
-  Support for this type of scaling can be implemented in a DMX-aware X11
-  client assuming the DMX server support arbitrary disconnect and
-  reconnect semantics.  Because this application cannot be written
-  before disconnect/reconnect is implemented, this solution will not be
-  discussed further in this paper.
-
-  33..22..33..  SSeerrvveerr--ssiiddee SSccaalliinngg
-
-  In earlier versions of DMX, a frame buffer was maintained on the
-  server side, and XPutImage was used to move the information from the
-  server to the client (similar to some early VNC implementations).  The
-  use of a server-side frame buffer would allow the server to do
-  scaling, but is not a recommended solution because of overall
-  performance issues and server-side memory issues (i.e., the frame
-  buffer would be very large for large display walls).
-
-  Exploration of this path is not recommended.
-
-  33..33..  XXCCrreeaatteeSSccaalleeddWWiinnddooww AAPPII
-
-  The implementation of X Video Extension in DMX, and the use of
-  XvPutImage by applications requiring scaling requires significant
-  changes in DMX Further, XvPutImage is, essentially a scaled blit, and
-  it is only useful for applications which are already using (or can be
-  modified to use) XPutImage.  Therefore, a more general API will be
-  discussed as another possibility.
-
-  X applications typically create windows with the XCreateWindow call.
-  A new extension could provide an XCreateScaledWindow call that could
-  be used in place of the XCreateWindow call and be otherwise
-  transparent to the application.  This would allow applications, even
-  those that do not depend on XPutImage, to take advantage of window
-  scaling.  In this section we describe how the call would work, what
-  transparency it provides, and how to solve the potential problems that
-  transparency creates.
-
-  33..33..11..  XXCCrreeaatteeWWiinnddooww
-
-  The XCreateWindow call takes width and height as parameters.  An
-  XCreateScaledWindow call could take all the same parameters, with the
-  addition of a scaling factor.
-  33..33..22..  XXSSeettWWiinnddoowwAAttttrriibbuutteess
-
-  An X11 window has several attributes that would have to be scaled:
-
-  +o  Background and border pixmaps
-
-  +o  Border width
-
-  +o  Cursor
-
-  33..33..33..  XXGGeettWWiinnddoowwAAttttrriibbuutteess,, XXGGeettGGeeoommeettrryy
-
-  For transparency, calls that query the window attributes should return
-  unscaled information.  This suggests that all unscaled pixmaps and
-  window attributes should be cached.
-
-  Unfortunately, a window manager requires the scaled geometry to
-  properly decorate the window.  The X server can probably determine
-  which client is acting as the window manager (e.g., because that
-  client will select events that are used exclusively by the window
-  manager).  However, other Scaled Window Extension aware clients may
-  also need to determine the scaled geometry.  Therefore, at least two
-  additional extension calls should be implemented:
-  XGetScaledWindowAttributes and XGetScaledGeometry.
-
-  33..33..44..  PPooppuupp aanndd CChhiilldd wwiinnddooww ppoossiittiioonnss
-
-  Some applications may position popup and child windows based on an
-  unscaled notion of the main window geometry.  In this case, additional
-  modifications to the client would be required.
-
-  33..33..55..  EEvveennttss
-
-  Most events (e.g., for mouse motion) return information about the
-  coordinates at which the even occurred.  These coordinates would have
-  to be modified so that unscaled values were presented to the client.
-
-  33..33..66..  IImmpplleemmeennttaattiioonn
-
-  There are many implementation issues, some of which are similar to the
-  issues involved in implementing the X Video Extension for DMX.  The
-  window contents must be scaled, either by performing all operations to
-  a frame buffer and then writing the image to the display (perhaps
-  using hardware scaling support), or by modifying all of the various
-  drawing operations to perform scaling.  Because of the complexity
-  involved, the frame buffer option is recommended.
-
-  44..  CCoonncclluussiioonn aanndd RReeccoommmmeennddaattiioonnss
-
-  We recommend a three phase implementation strategy, based on how an
-  application could be written to take advantage of scaling:
-
-  1.
-
-     The XCopyAreaScaled extension should be implemented, since this is
-     the ideal solution for applications like VNC, and since making use
-     of this extension will require minimal changes to applications that
-     already use XPutImage or XCopyArea.
-
-     The initial implementation work would include the design of the X
-     protocol extension, writing this up in the usual format for
-     extension documentation, implementation of the protocol transport
-     pieces in XFree86, implementation of a software fall-back in
-     XFree86 and DMX, one example hardware implementation for XFree86,
-     and implementation of support for this extension in DMX.
-
-     We suggest implementing the extension first on the ATI Radeon
-     cards.  However, since these cards do not provide a 2D scaled blit
-     primitive, the implementation would have to make use of the 3D
-     texture engine to emulate a scaled blit.  This is recommended,
-     since other modern graphics cards also do not provide a simple 2D
-     scaled blit operation and an example of the more difficult
-     implementation pathway would be helpful to others.
-
-  2.
-
-     Until XCopyAreaScaled is widely supported, applications that
-     require scaling will have to fall back to another scaling method.
-     We suggest OpenGL as the first fall-back method because it is
-     widely available and supported by DMX.
-
-     A project centered around OpenGL-based scaling would implement this
-     scaling in VNC as an example.  This work would include re-writing
-     the vncviewer rendering engine to cache a master copy of the
-     desktop image for all operations.
-
-  3.
-
-     Since OpenGL is not implemented everywhere, and may not provide
-     hardware-assisted performance in every implementation, an
-     application that requires scaling should also fall back to using
-     the X Video Extension.
-
-     This project would add support for the X Video Extension to DMX and
-     would add support to VNC to take advantage of this extension
-     without introducing artifacts.  This would require modifying the
-     vncviewer rendering engine to cache a master copy of the desktop
-     image for all operations.  This project should also add support for
-     the RGB format to at least one XFree86 driver (e.g., ATI Radeon).
-
-     The X Video Extension is one of the few popular extensions that DMX
-     does not support.  We recommend implementing the X Video Extension
-     even if scaling is the specific goal of that work.
-
-  We do nnoott recommend implementation of the XCreateScaledWindow
-  extension because of the complexity involved.  We do nnoott recommend
-  implementation of the XPutImageScaled extension because it requires
-  the same amount of work as the XCopyAreaScaled extension, but provides
-  less functionality.  Further, server-side scaling with a large frame
-  buffer is nnoott recommended because of the performance implications.
-
-  The back-end scaling, especially with disconnect/reconnect support
-  should be explored in the future after disconnect/reconnect is
-  implemented, but not at the present time.
-
-
-
commit 40972576b606237d5d42abc13d846163e264a4ac
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Tue Mar 23 04:47:27 2010 -0500

    Use AC_PROG_SED and respect its result
    
    AC_PROG_SED sets SED as the path to a fully-functional 'sed' (which may
    also be called 'gsed' if GNU sed is installed alongside a proprietary
    version).
    
    This is a follow up to commit 9be4157391edf0c5fc4ee36adfb1eb1c3bdb8e3b.
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>

diff --git a/configure.ac b/configure.ac
index b48d3a9..b491d52 100644
--- a/configure.ac
+++ b/configure.ac
@@ -77,7 +77,7 @@ AC_PROG_LEX
 AC_PROG_YACC
 AC_SYS_LARGEFILE
 XORG_PROG_RAWCPP
-AC_PATH_PROG(SED,sed)
+AC_PROG_SED
 
 # Quoted so that make will expand $(CWARNFLAGS) in makefiles to allow
 # easier overrides at build time.
@@ -1167,8 +1167,8 @@ fi
 dnl XKM_OUTPUT_DIR (used in code) must end in / or file names get hosed
 dnl XKB_COMPILED_DIR (used in Makefiles) must not or install-sh gets confused
 
-XKBOUTPUT=`echo $XKBOUTPUT/ | sed 's|/*$|/|'`
-XKB_COMPILED_DIR=`echo $XKBOUTPUT | sed 's|/*$||'`
+XKBOUTPUT=`echo $XKBOUTPUT/ | $SED 's|/*$|/|'`
+XKB_COMPILED_DIR=`echo $XKBOUTPUT | $SED 's|/*$||'`
 AC_DEFINE_DIR(XKM_OUTPUT_DIR, XKBOUTPUT, [Path to XKB output dir])
 AC_SUBST(XKB_COMPILED_DIR)
 
@@ -1646,11 +1646,11 @@ if test "x$XORG" = xyes; then
 		AC_CHECK_HEADERS([sys/vt.h], [solaris_vt=yes], [solaris_vt=no])
 		# Check for minimum supported release
 		AC_MSG_CHECKING([Solaris version])
-	        OS_MINOR=`echo ${host_os}|sed -e 's/^.*solaris2\.//' -e s'/\..*$//'`
+	        OS_MINOR=`echo ${host_os}|$SED -e 's/^.*solaris2\.//' -e s'/\..*$//'`
 		if test "${OS_MINOR}" -ge 7 ; then
 	        	AC_MSG_RESULT(Solaris ${OS_MINOR})
 		else
-			AC_MSG_RESULT(Solaris `echo ${host_os}|sed -e 's/^.*solaris//`)
+			AC_MSG_RESULT(Solaris `echo ${host_os}|$SED -e 's/^.*solaris//`)
 		fi
 		if test "${OS_MINOR}" -lt 8 ; then
 			AC_MSG_ERROR([This release no longer supports Solaris versions older than Solaris 8.])
commit edbc56c088462844f6445f5e6d7cbcfc58a207dc
Author: Tiago Vignatti <tiago.vignatti at nokia.com>
Date:   Mon Apr 26 14:49:25 2010 +0300

    include: remove couple of unused structures fields and bump ABI
    
    Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index bbf5786..d61758f 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -82,9 +82,9 @@ typedef enum {
  * mask is 0xFFFF0000.
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
-#define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(7, 0)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(9, 0)
-#define ABI_EXTENSION_VERSION	SET_ABI_VERSION(3, 0)
+#define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(8, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(10, 0)
+#define ABI_EXTENSION_VERSION	SET_ABI_VERSION(4, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
 #define MODINFOSTRING1	0xef23fdc5
diff --git a/include/dixstruct.h b/include/dixstruct.h
index 696b793..5b1a698 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -85,7 +85,6 @@ typedef struct _Window *SaveSetElt;
 #define SaveSetAssignMap(ss,m)
 #endif
 
-/* The unused_ members are ABI spacing.  Please reuse them. */
 typedef struct _Client {
     int         index;
     Mask        clientAsMask;
@@ -101,7 +100,6 @@ typedef struct _Client {
 					 * killed */
     SaveSetElt	*saveSet;
     int         numSaved;
-    void	*unused_screenPrivate[16];
     int         (**requestVector) (
 		ClientPtr /* pClient */);
     CARD32	req_len;		/* length of current request */
@@ -116,8 +114,6 @@ typedef struct _Client {
     KeyCode		minKC,maxKC;
 
     unsigned long replyBytesRemaining;
-    void *unused_appgroup;
-    void *unused_fontResFunc;
     int	    smart_priority;
     long    smart_start_tick;
     long    smart_stop_tick;
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 5a7c57d..5538936 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -615,10 +615,8 @@ typedef struct _ScreenInfo {
     int		numPixmapFormats;
     PixmapFormatRec
 		formats[MAXFORMATS];
-    int		unused2;
     int		numScreens;
     ScreenPtr	screens[MAXSCREENS];
-    int		unused;
 } ScreenInfo;
 
 extern _X_EXPORT ScreenInfo screenInfo;
commit 4f8dc1109dcdfa973466a038c16c07da5f6c16b4
Author: Tiago Vignatti <tiago.vignatti at nokia.com>
Date:   Thu Apr 22 15:43:11 2010 +0300

    dix and others: remove unused arraySize field from ScreenInfo
    
    Bizarre. This seems to never be used before. I left the field in ScreenInfo,
    with another name. So, stop looking at it.
    
    Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>

diff --git a/dix/main.c b/dix/main.c
index f023536..e5667a6 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -190,7 +190,6 @@ int main(int argc, char *argv[], char *envp[])
 	    FatalError("couldn't init server resources");
 
 	SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
-	screenInfo.arraySize = MAXSCREENS;
 	screenInfo.numScreens = 0;
 
 	InitAtoms();
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index c42119d..5a7c57d 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -615,7 +615,7 @@ typedef struct _ScreenInfo {
     int		numPixmapFormats;
     PixmapFormatRec
 		formats[MAXFORMATS];
-    int		arraySize;
+    int		unused2;
     int		numScreens;
     ScreenPtr	screens[MAXSCREENS];
     int		unused;
diff --git a/test/xi2/protocol-common.c b/test/xi2/protocol-common.c
index 2dff1ad..0afa55a 100644
--- a/test/xi2/protocol-common.c
+++ b/test/xi2/protocol-common.c
@@ -141,7 +141,6 @@ static Bool device_cursor_init(DeviceIntPtr dev, ScreenPtr screen) { return TRUE
 static Bool set_cursor_pos(DeviceIntPtr dev, ScreenPtr screen, int x, int y, Bool event) { return TRUE; }
 void init_simple(void)
 {
-    screenInfo.arraySize = MAXSCREENS;
     screenInfo.numScreens = 1;
     screenInfo.screens[0] = &screen;
 
diff --git a/test/xtest.c b/test/xtest.c
index 572f5d2..cc1188d 100644
--- a/test/xtest.c
+++ b/test/xtest.c
@@ -49,7 +49,6 @@ static void xtest_init_devices(void)
 
     /* random stuff that needs initialization */
     memset(&screen, 0, sizeof(screen));
-    screenInfo.arraySize = MAXSCREENS;
     screenInfo.numScreens = 1;
     screenInfo.screens[0] = &screen;
     screen.myNum = 0;
commit 64fd39f2f0ffbbdc2d5929047d260263d0962141
Author: Tiago Vignatti <tiago.vignatti at nokia.com>
Date:   Thu Apr 22 15:48:48 2010 +0300

    xfree86: no need to assign numScreens again
    
    numScreens is always being assigned to 0 in dix for any server generation.
    
    Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 03a29ea..55d7a62 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -552,9 +552,6 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
   xf86Initialising = TRUE;
 
   if (serverGeneration == 1) {
-
-    pScreenInfo->numScreens = 0;
-
     if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
       xf86ServerName++;
     else
commit a7d398e545a4be5491248d5ccb303aa03ee1594f
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Apr 16 18:13:50 2010 +0100

    Xwin: make screens structures run-time adjustable
    
    Change g_ScreenInfo, an array of winScreenInfo elements, from a
    static array of MAXSCREENS elements, to a dynamically allocated one
    
    Fix up the validation that -screen option screen numbers are
    contiguous from zero (which possibly didn't work correctly before
    anyhow)
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Jamey Sharp<jamey at minilop.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 8c7ebf0..0ab6929 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -64,7 +64,7 @@ typedef HRESULT (*SHGETFOLDERPATHPROC)(
  */
 
 extern int			g_iNumScreens;
-extern winScreenInfo		g_ScreenInfo[];
+extern winScreenInfo *		g_ScreenInfo;
 extern char *			g_pszCommandLine;
 extern Bool			g_fSilentFatalError;
 
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 072c691..5abaa03 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -622,7 +622,7 @@ typedef struct {
  * Extern declares for general global variables
  */
 
-extern winScreenInfo		g_ScreenInfo[];
+extern winScreenInfo *		g_ScreenInfo;
 extern miPointerScreenFuncRec	g_winPointerCursorFuncs;
 extern DWORD			g_dwEvents;
 #ifdef HAS_DEVWINDOWS
diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c
index da78155..d74011c 100644
--- a/hw/xwin/winglobals.c
+++ b/hw/xwin/winglobals.c
@@ -41,7 +41,7 @@
  */
 
 int		g_iNumScreens = 0;
-winScreenInfo	g_ScreenInfo[MAXSCREENS];
+winScreenInfo * g_ScreenInfo = 0;
 #ifdef HAS_DEVWINDOWS
 int		g_fdMessageQueue = WIN_FD_INVALID;
 #endif
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 540adf7..ad4b7e9 100755
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -45,7 +45,7 @@ from The Open Group.
  */
 
 extern int			g_iNumScreens;
-extern winScreenInfo		g_ScreenInfo[];
+extern winScreenInfo *		g_ScreenInfo;
 #ifdef XWIN_CLIPBOARD
 extern Bool			g_fUnicodeClipboard;
 extern Bool			g_fClipboard;
@@ -227,6 +227,9 @@ winInitializeScreens(int maxscreens)
 
   if (maxscreens > g_iNumScreens)
     {
+      /* Reallocate the memory for DDX-specific screen info */
+      g_ScreenInfo = realloc(g_ScreenInfo, maxscreens * sizeof (winScreenInfo));
+
       /* Set default values for any new screens */
       for (i = g_iNumScreens; i < maxscreens ; i++)
         winInitializeScreen(i);
@@ -353,7 +356,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
       nScreenNum = atoi (argv[i + 1]);
 
       /* Validate the specified screen number */
-      if (nScreenNum < 0 || nScreenNum >= MAXSCREENS)
+      if (nScreenNum < 0)
         {
           ErrorF ("ddxProcessArgument - screen - Invalid screen number %d\n",
 		  nScreenNum);
diff --git a/hw/xwin/winvalargs.c b/hw/xwin/winvalargs.c
index 038e097..6f8d1c9 100755
--- a/hw/xwin/winvalargs.c
+++ b/hw/xwin/winvalargs.c
@@ -40,17 +40,24 @@
  */
 
 extern int			g_iNumScreens;
-extern winScreenInfo		g_ScreenInfo[];
+extern winScreenInfo *		g_ScreenInfo;
 extern Bool			g_fXdmcpEnabled;
 
 
 /*
- * Prototypes
+ * Verify all screens have been explicitly specified
  */
+static BOOL
+isEveryScreenExplicit(void)
+{
+  int i;
 
-Bool
-winValidateArgs (void);
+  for (i = 0; i < g_iNumScreens; i++)
+    if (!g_ScreenInfo[i].fExplicitScreen)
+      return FALSE;
 
+  return TRUE;
+}
 
 /*
  * winValidateArgs - Look for invalid argument combinations
@@ -62,6 +69,7 @@ winValidateArgs (void)
   int		i;
   int		iMaxConsecutiveScreen = 0;
   BOOL		fHasNormalScreen0 = FALSE;
+  BOOL		fImplicitScreenFound = FALSE;
 
   /*
    * Check for a malformed set of -screen parameters.
@@ -70,23 +78,14 @@ winValidateArgs (void)
    *	XWin -screen 0 -screen 2
    *	XWin -screen 1 -screen 2
    */
-  for (i = 0; i < MAXSCREENS; i++)
-    {
-      if (g_ScreenInfo[i].fExplicitScreen)
-	iMaxConsecutiveScreen = i + 1;
-    }
-  winErrorFVerb (2, "winValidateArgs - g_iNumScreens: %d "
-		 "iMaxConsecutiveScreen: %d\n",
-		 g_iNumScreens, iMaxConsecutiveScreen);
-  if (g_iNumScreens < iMaxConsecutiveScreen)
+  if (!isEveryScreenExplicit())
     {
       ErrorF ("winValidateArgs - Malformed set of screen parameter(s).  "
 	      "Screens must be specified consecutively starting with "
 	      "screen 0.  That is, you cannot have only a screen 1, nor "
 	      "could you have screen 0 and screen 2.  You instead must "
-	      "have screen 0, or screen 0 and screen 1, respectively.  Of "
-	      "you can specify as many screens as you want from 0 up to "
-	      "%d.\n", MAXSCREENS - 1);
+	      "have screen 0, or screen 0 and screen 1, respectively.  "
+	      "You can specify as many screens as you want.\n");
       return FALSE;
     }
 
commit d8454ae488cfc073cd6010c9a08d53855a0c2612
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Apr 12 20:18:13 2010 +0100

    Xwin: Simplify screen option processing
    
    Use an instance of the XWin DDX-specific screen info structure to hold
    the current default values, to simplify greatly the code for applying
    options to all screens and remove all those loops over MAXSCREENS screens
    in the command line option processing
    
    Use g_iNumScreens for tracking the current initialized screen count
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index fd286de..8c7ebf0 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -65,7 +65,6 @@ typedef HRESULT (*SHGETFOLDERPATHPROC)(
 
 extern int			g_iNumScreens;
 extern winScreenInfo		g_ScreenInfo[];
-extern int			g_iLastScreen;
 extern char *			g_pszCommandLine;
 extern Bool			g_fSilentFatalError;
 
@@ -115,9 +114,6 @@ void
 OsVendorVErrorF (const char *pszFormat, va_list va_args);
 #endif
 
-void
-winInitializeDefaultScreens (void);
-
 static Bool
 winCheckDisplayNumber (void);
 
@@ -716,22 +712,16 @@ OsVendorInit (void)
   /* Add a default screen if no screens were specified */
   if (g_iNumScreens == 0)
     {
-      winDebug ("OsVendorInit - Creating bogus screen 0\n");
-
-      /* 
-       * We need to initialize default screens if no arguments
-       * were processed.  Otherwise, the default screens would
-       * already have been initialized by ddxProcessArgument ().
-       */
-      winInitializeDefaultScreens ();
+      winDebug ("OsVendorInit - Creating default screen 0\n");
 
       /*
-       * Add a screen 0 using the defaults set by 
-       * winInitializeDefaultScreens () and any additional parameters
-       * processed by ddxProcessArgument ().
+       * We need to initialize the default screen 0 if no -screen
+       * arguments were processed.
+       *
+       * Add a screen 0 using the defaults set by winInitializeDefaultScreens()
+       * and any additional default screen parameters given
        */
-      g_iNumScreens = 1;
-      g_iLastScreen = 0;
+      winInitializeScreens(1);
 
       /* We have to flag this as an explicit screen, even though it isn't */
       g_ScreenInfo[0].fExplicitScreen = TRUE;
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index b1acd3e..072c691 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -1451,6 +1451,12 @@ Bool
 winInitCursor (ScreenPtr pScreen);
 
 /*
+ * winprocarg.c
+ */
+void
+winInitializeScreens(int maxscreens);
+
+/*
  * END DDX and DIX Function Prototypes
  */
 
diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c
index 926ce69..da78155 100644
--- a/hw/xwin/winglobals.c
+++ b/hw/xwin/winglobals.c
@@ -42,7 +42,6 @@
 
 int		g_iNumScreens = 0;
 winScreenInfo	g_ScreenInfo[MAXSCREENS];
-int		g_iLastScreen = -1;
 #ifdef HAS_DEVWINDOWS
 int		g_fdMessageQueue = WIN_FD_INVALID;
 #endif
@@ -57,7 +56,6 @@ DevPrivateKey	g_iPixmapPrivateKey = &g_iPixmapPrivateKeyIndex;
 static int	g_iWindowPrivateKeyIndex;
 DevPrivateKey	g_iWindowPrivateKey = &g_iWindowPrivateKeyIndex;
 unsigned long	g_ulServerGeneration = 0;
-Bool		g_fInitializedDefaultScreens = FALSE;
 DWORD		g_dwEnginesSupported = 0;
 HINSTANCE	g_hInstance = 0;
 HWND		g_hDlgDepthChange = NULL;
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 66da76f..540adf7 100755
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -46,8 +46,6 @@ from The Open Group.
 
 extern int			g_iNumScreens;
 extern winScreenInfo		g_ScreenInfo[];
-extern int			g_iLastScreen;
-extern Bool			g_fInitializedDefaultScreens;
 #ifdef XWIN_CLIPBOARD
 extern Bool			g_fUnicodeClipboard;
 extern Bool			g_fClipboard;
@@ -129,25 +127,25 @@ winLogVersionInfo (void);
 void OsVendorVErrorF (const char *pszFormat, va_list va_args);
 #endif
 
-void
-winInitializeDefaultScreens (void);
-
 /*
  * Process arguments on the command line
  */
 
-void
-winInitializeDefaultScreens (void)
+static int iLastScreen = -1;
+static winScreenInfo defaultScreenInfo;
+
+static void
+winInitializeScreenDefaults(void)
 {
-  int                   i;
-  DWORD			dwWidth, dwHeight;
+  DWORD dwWidth, dwHeight;
+  static Bool fInitializedScreenDefaults = FALSE;
 
-  /* Bail out early if default screens have already been initialized */
-  if (g_fInitializedDefaultScreens)
+  /* Bail out early if default screen has already been initialized */
+  if (fInitializedScreenDefaults)
     return;
 
   /* Zero the memory used for storing the screen info */
-  ZeroMemory (g_ScreenInfo, MAXSCREENS * sizeof (winScreenInfo));
+  memset(&defaultScreenInfo, 0, sizeof(winScreenInfo));
 
   /* Get default width and height */
   /*
@@ -157,62 +155,85 @@ winInitializeDefaultScreens (void)
   dwWidth = GetSystemMetrics (SM_CXSCREEN);
   dwHeight = GetSystemMetrics (SM_CYSCREEN);
 
-  winErrorFVerb (2, "winInitializeDefaultScreens - w %d h %d\n",
+  winErrorFVerb (2, "winInitializeScreenDefaults - w %d h %d\n",
 	  (int) dwWidth, (int) dwHeight);
 
   /* Set a default DPI, if no parameter was passed */
   if (monitorResolution == 0)
     monitorResolution = WIN_DEFAULT_DPI;
 
-  for (i = 0; i < MAXSCREENS; ++i)
-    {
-      g_ScreenInfo[i].dwScreen = i;
-      g_ScreenInfo[i].dwWidth  = dwWidth;
-      g_ScreenInfo[i].dwHeight = dwHeight;
-      g_ScreenInfo[i].dwUserWidth  = dwWidth;
-      g_ScreenInfo[i].dwUserHeight = dwHeight;
-      g_ScreenInfo[i].fUserGaveHeightAndWidth
-	=  WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH;
-      g_ScreenInfo[i].fUserGavePosition = FALSE;
-      g_ScreenInfo[i].dwBPP = WIN_DEFAULT_BPP;
-      g_ScreenInfo[i].dwClipUpdatesNBoxes = WIN_DEFAULT_CLIP_UPDATES_NBOXES;
+  defaultScreenInfo.dwWidth  = dwWidth;
+  defaultScreenInfo.dwHeight = dwHeight;
+  defaultScreenInfo.dwUserWidth  = dwWidth;
+  defaultScreenInfo.dwUserHeight = dwHeight;
+  defaultScreenInfo.fUserGaveHeightAndWidth = WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH;
+  defaultScreenInfo.fUserGavePosition = FALSE;
+  defaultScreenInfo.dwBPP = WIN_DEFAULT_BPP;
+  defaultScreenInfo.dwClipUpdatesNBoxes = WIN_DEFAULT_CLIP_UPDATES_NBOXES;
 #ifdef XWIN_EMULATEPSEUDO
-      g_ScreenInfo[i].fEmulatePseudo = WIN_DEFAULT_EMULATE_PSEUDO;
+  defaultScreenInfo.fEmulatePseudo = WIN_DEFAULT_EMULATE_PSEUDO;
 #endif
-      g_ScreenInfo[i].dwRefreshRate = WIN_DEFAULT_REFRESH;
-      g_ScreenInfo[i].pfb = NULL;
-      g_ScreenInfo[i].fFullScreen = FALSE;
-      g_ScreenInfo[i].fDecoration = TRUE;
+  defaultScreenInfo.dwRefreshRate = WIN_DEFAULT_REFRESH;
+  defaultScreenInfo.pfb = NULL;
+  defaultScreenInfo.fFullScreen = FALSE;
+  defaultScreenInfo.fDecoration = TRUE;
 #ifdef XWIN_MULTIWINDOWEXTWM
-      g_ScreenInfo[i].fMWExtWM = FALSE;
-      g_ScreenInfo[i].fInternalWM = FALSE;
+  defaultScreenInfo.fMWExtWM = FALSE;
+  defaultScreenInfo.fInternalWM = FALSE;
 #endif
-      g_ScreenInfo[i].fRootless = FALSE;
+  defaultScreenInfo.fRootless = FALSE;
 #ifdef XWIN_MULTIWINDOW
-      g_ScreenInfo[i].fMultiWindow = FALSE;
+  defaultScreenInfo.fMultiWindow = FALSE;
 #endif
 #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-      g_ScreenInfo[i].fMultiMonitorOverride = FALSE;
+  defaultScreenInfo.fMultiMonitorOverride = FALSE;
 #endif
-      g_ScreenInfo[i].fMultipleMonitors = FALSE;
-      g_ScreenInfo[i].fLessPointer = FALSE;
-      g_ScreenInfo[i].fScrollbars = FALSE;
-      g_ScreenInfo[i].fNoTrayIcon = FALSE;
-      g_ScreenInfo[i].iE3BTimeout = WIN_E3B_OFF;
-      g_ScreenInfo[i].dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI)
-	* 25.4;
-      g_ScreenInfo[i].dwHeight_mm = (dwHeight / WIN_DEFAULT_DPI)
-	* 25.4;
-      g_ScreenInfo[i].fUseWinKillKey = WIN_DEFAULT_WIN_KILL;
-      g_ScreenInfo[i].fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL;
-      g_ScreenInfo[i].fIgnoreInput = FALSE;
-      g_ScreenInfo[i].fExplicitScreen = FALSE;
-    }
+  defaultScreenInfo.fMultipleMonitors = FALSE;
+  defaultScreenInfo.fLessPointer = FALSE;
+  defaultScreenInfo.fScrollbars = FALSE;
+  defaultScreenInfo.fNoTrayIcon = FALSE;
+  defaultScreenInfo.iE3BTimeout = WIN_E3B_OFF;
+  defaultScreenInfo.dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI) * 25.4;
+  defaultScreenInfo.dwHeight_mm = (dwHeight / WIN_DEFAULT_DPI) * 25.4;
+  defaultScreenInfo.fUseWinKillKey = WIN_DEFAULT_WIN_KILL;
+  defaultScreenInfo.fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL;
+  defaultScreenInfo.fIgnoreInput = FALSE;
+  defaultScreenInfo.fExplicitScreen = FALSE;
+
+  /* Note that the default screen has been initialized */
+  fInitializedScreenDefaults = TRUE;
+}
+
+static void
+winInitializeScreen(int i)
+{
+  winErrorFVerb (2, "winInitializeScreen - %d\n",i);
 
-  /* Signal that the default screens have been initialized */
-  g_fInitializedDefaultScreens = TRUE;
+  /* Initialize default screen values, if needed */
+  winInitializeScreenDefaults();
 
-  winErrorFVerb (2, "winInitializeDefaultScreens - Returning\n");
+  /* Copy the default screen info */
+  g_ScreenInfo[i] = defaultScreenInfo;
+
+  /* Set the screen number */
+  g_ScreenInfo[i].dwScreen = i;
+}
+
+void
+winInitializeScreens(int maxscreens)
+{
+  int i;
+  winErrorFVerb (2, "winInitializeScreens - %i\n", maxscreens);
+
+  if (maxscreens > g_iNumScreens)
+    {
+      /* Set default values for any new screens */
+      for (i = g_iNumScreens; i < maxscreens ; i++)
+        winInitializeScreen(i);
+
+      /* Keep a count of the number of screens */
+      g_iNumScreens = maxscreens;
+    }
 }
 
 /* See Porting Layer Definition - p. 57 */
@@ -244,6 +265,7 @@ int
 ddxProcessArgument (int argc, char *argv[], int i)
 {
   static Bool		s_fBeenHere = FALSE;
+  winScreenInfo	*screenInfoPtr = NULL;
 
   /* Initialize once */
   if (!s_fBeenHere)
@@ -276,7 +298,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
 	   */
 	  winErrorFVerb (2, "ddxProcessArgument - Initializing default "
 			 "screens\n");
-	  winInitializeDefaultScreens ();
+	  winInitializeScreenDefaults();
 	}
     }
 
@@ -339,6 +361,14 @@ ddxProcessArgument (int argc, char *argv[], int i)
 	  return 0;
         }
 
+      /*
+        Initialize default values for any new screens
+
+        Note that default values can't change after a -screen option is
+        seen, so it's safe to do this for each screen as it is introduced
+      */
+      winInitializeScreens(nScreenNum+1);
+
 	  /* look for @m where m is monitor number */
 	  if (i + 2 < argc
 		  && 1 == sscanf(argv[i + 2], "@%d", (int *) &iMonitor)) 
@@ -505,14 +535,33 @@ ddxProcessArgument (int argc, char *argv[], int i)
        * before a screen number apply to all screens, whereas parameters
        * seen after a screen number apply to that screen number only.
        */
-      g_iLastScreen = nScreenNum;
-
-      /* Keep a count of the number of screens */
-      ++g_iNumScreens;
+      iLastScreen = nScreenNum;
 
       return iArgsProcessed;
     }
 
+
+  /*
+   * Is this parameter attached to a screen or global?
+   *
+   * If the parameter is for all screens (appears before
+   * any -screen option), store it in the default screen
+   * info
+   *
+   * If the parameter is for a single screen (appears
+   * after a -screen option), store it in the screen info
+   * for that screen
+   *
+   */
+  if (iLastScreen == -1)
+    {
+      screenInfoPtr = &defaultScreenInfo;
+    }
+  else
+    {
+      screenInfoPtr = &(g_ScreenInfo[iLastScreen]);
+    }
+
   /*
    * Look for the '-engine n' argument
    */
@@ -541,22 +590,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
 	  return 0;
 	}
 
-      /* Is this parameter attached to a screen or global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int		j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].dwEnginePreferred = dwEngine;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].dwEnginePreferred = dwEngine;
-	}
+      screenInfoPtr->dwEnginePreferred = dwEngine;
       
       /* Indicate that we have processed the argument */
       return 2;
@@ -567,30 +601,11 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-fullscreen"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-              if (!g_ScreenInfo[j].fMultiMonitorOverride)
-                g_ScreenInfo[j].fMultipleMonitors = FALSE;
-#endif
-	      g_ScreenInfo[j].fFullScreen = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
 #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-          if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
-            g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE;
+          if (!screenInfoPtr->fMultiMonitorOverride)
+            screenInfoPtr->fMultipleMonitors = FALSE;
 #endif
-	  g_ScreenInfo[g_iLastScreen].fFullScreen = TRUE;
-	}
+	  screenInfoPtr->fFullScreen = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -601,22 +616,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-lesspointer"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].fLessPointer = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-          g_ScreenInfo[g_iLastScreen].fLessPointer = TRUE;
-	}
+      screenInfoPtr->fLessPointer = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -627,30 +627,11 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-nodecoration"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
 #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-              if (!g_ScreenInfo[j].fMultiMonitorOverride)
-                g_ScreenInfo[j].fMultipleMonitors = FALSE;
+      if (!screenInfoPtr->fMultiMonitorOverride)
+        screenInfoPtr->fMultipleMonitors = FALSE;
 #endif
-	      g_ScreenInfo[j].fDecoration = FALSE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-          if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
-            g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE;
-#endif
-	  g_ScreenInfo[g_iLastScreen].fDecoration = FALSE;
-	}
+      screenInfoPtr->fDecoration = FALSE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -662,26 +643,9 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-mwextwm"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-              if (!g_ScreenInfo[j].fMultiMonitorOverride)
-                g_ScreenInfo[j].fMultipleMonitors = TRUE;
-	      g_ScreenInfo[j].fMWExtWM = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-          if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
-            g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE;
-	  g_ScreenInfo[g_iLastScreen].fMWExtWM = TRUE;
-	}
+      if (!screenInfoPtr->fMultiMonitorOverride)
+        screenInfoPtr->fMultipleMonitors = TRUE;
+      screenInfoPtr->fMWExtWM = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -691,28 +655,10 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-internalwm"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      if (!g_ScreenInfo[j].fMultiMonitorOverride)
-	        g_ScreenInfo[j].fMultipleMonitors = TRUE;
-	      g_ScreenInfo[j].fMWExtWM = TRUE;
-	      g_ScreenInfo[j].fInternalWM = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
-	    g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE;
-	  g_ScreenInfo[g_iLastScreen].fMWExtWM = TRUE;
-	  g_ScreenInfo[g_iLastScreen].fInternalWM = TRUE;
-	}
+      if (!screenInfoPtr->fMultiMonitorOverride)
+        screenInfoPtr->fMultipleMonitors = TRUE;
+      screenInfoPtr->fMWExtWM = TRUE;
+      screenInfoPtr->fInternalWM = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -724,30 +670,11 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-rootless"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
 #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-              if (!g_ScreenInfo[j].fMultiMonitorOverride)
-                g_ScreenInfo[j].fMultipleMonitors = FALSE;
+      if (!screenInfoPtr->fMultiMonitorOverride)
+        screenInfoPtr->fMultipleMonitors = FALSE;
 #endif
-	      g_ScreenInfo[j].fRootless = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-          if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
-            g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE;
-#endif
-	  g_ScreenInfo[g_iLastScreen].fRootless = TRUE;
-	}
+      screenInfoPtr->fRootless = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -759,30 +686,11 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-multiwindow"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-              if (!g_ScreenInfo[j].fMultiMonitorOverride)
-                g_ScreenInfo[j].fMultipleMonitors = TRUE;
-#endif
-	      g_ScreenInfo[j].fMultiWindow = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
 #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-          if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
-            g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE;
+      if (!screenInfoPtr->fMultiMonitorOverride)
+        screenInfoPtr->fMultipleMonitors = TRUE;
 #endif
-	  g_ScreenInfo[g_iLastScreen].fMultiWindow = TRUE;
-	}
+      screenInfoPtr->fMultiWindow = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -795,28 +703,10 @@ ddxProcessArgument (int argc, char *argv[], int i)
   if (IS_OPTION ("-multiplemonitors")
       || IS_OPTION ("-multimonitors"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-              g_ScreenInfo[j].fMultiMonitorOverride = TRUE;
-#endif
-	      g_ScreenInfo[j].fMultipleMonitors = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
 #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-          g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride = TRUE;
+      screenInfoPtr->fMultiMonitorOverride = TRUE;
 #endif
-	  g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE;
-	}
+      screenInfoPtr->fMultipleMonitors = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -828,28 +718,10 @@ ddxProcessArgument (int argc, char *argv[], int i)
   if (IS_OPTION ("-nomultiplemonitors")
       || IS_OPTION ("-nomultimonitors"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
 #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-              g_ScreenInfo[j].fMultiMonitorOverride = TRUE;
+      screenInfoPtr->fMultiMonitorOverride = TRUE;
 #endif
-	      g_ScreenInfo[j].fMultipleMonitors = FALSE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
-          g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride = TRUE;
-#endif
-	  g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE;
-	}
+      screenInfoPtr->fMultipleMonitors = FALSE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -861,22 +733,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-scrollbars"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].fScrollbars = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].fScrollbars = TRUE;
-	}
+      screenInfoPtr->fScrollbars = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -914,22 +771,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-ignoreinput"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].fIgnoreInput = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].fIgnoreInput = TRUE;
-	}
+      screenInfoPtr->fIgnoreInput = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -962,22 +804,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
 	  iE3BTimeout = WIN_DEFAULT_E3B_TIME;
 	}
 
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].iE3BTimeout = iE3BTimeout;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].iE3BTimeout = iE3BTimeout;
-	}
+      screenInfoPtr->iE3BTimeout = iE3BTimeout;
 
       /* Indicate that we have processed this argument */
       return iArgsProcessed;
@@ -1000,23 +827,8 @@ ddxProcessArgument (int argc, char *argv[], int i)
       /* Grab the argument */
       dwBPP = atoi (argv[i]);
 
-      /* Is this parameter attached to a screen or global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int		j;
+      screenInfoPtr->dwBPP = dwBPP;
 
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].dwBPP = dwBPP;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].dwBPP = dwBPP;
-	}
-      
       /* Indicate that we have processed the argument */
       return 2;
     }
@@ -1038,23 +850,8 @@ ddxProcessArgument (int argc, char *argv[], int i)
       /* Grab the argument */
       dwRefreshRate = atoi (argv[i]);
 
-      /* Is this parameter attached to a screen or global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int		j;
+      screenInfoPtr->dwRefreshRate = dwRefreshRate;
 
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].dwRefreshRate = dwRefreshRate;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].dwRefreshRate = dwRefreshRate;
-	}
-      
       /* Indicate that we have processed the argument */
       return 2;
     }
@@ -1076,23 +873,8 @@ ddxProcessArgument (int argc, char *argv[], int i)
       /* Grab the argument */
       dwNumBoxes = atoi (argv[i]);
 
-      /* Is this parameter attached to a screen or global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int		j;
+      screenInfoPtr->dwClipUpdatesNBoxes = dwNumBoxes;
 
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].dwClipUpdatesNBoxes = dwNumBoxes;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].dwClipUpdatesNBoxes = dwNumBoxes;
-	}
-      
       /* Indicate that we have processed the argument */
       return 2;
     }
@@ -1103,22 +885,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-emulatepseudo"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].fEmulatePseudo = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-          g_ScreenInfo[g_iLastScreen].fEmulatePseudo = TRUE;
-	}
+      screenInfoPtr->fEmulatePseudo = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -1130,22 +897,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-nowinkill"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].fUseWinKillKey = FALSE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].fUseWinKillKey = FALSE;
-	}
+      screenInfoPtr->fUseWinKillKey = FALSE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -1156,22 +908,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-winkill"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].fUseWinKillKey = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].fUseWinKillKey = TRUE;
-	}
+      screenInfoPtr->fUseWinKillKey = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -1182,22 +919,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-nounixkill"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].fUseUnixKillKey = FALSE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].fUseUnixKillKey = FALSE;
-	}
+      screenInfoPtr->fUseUnixKillKey = FALSE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -1208,22 +930,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-unixkill"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].fUseUnixKillKey = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].fUseUnixKillKey = TRUE;
-	}
+      screenInfoPtr->fUseUnixKillKey = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -1234,22 +941,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-notrayicon"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].fNoTrayIcon = TRUE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].fNoTrayIcon = TRUE;
-	}
+      screenInfoPtr->fNoTrayIcon = TRUE;
 
       /* Indicate that we have processed this argument */
       return 1;
@@ -1260,22 +952,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
    */
   if (IS_OPTION ("-trayicon"))
     {
-      /* Is this parameter attached to a screen or is it global? */
-      if (-1 == g_iLastScreen)
-	{
-	  int			j;
-
-	  /* Parameter is for all screens */
-	  for (j = 0; j < MAXSCREENS; j++)
-	    {
-	      g_ScreenInfo[j].fNoTrayIcon = FALSE;
-	    }
-	}
-      else
-	{
-	  /* Parameter is for a single screen */
-	  g_ScreenInfo[g_iLastScreen].fNoTrayIcon = FALSE;
-	}
+      screenInfoPtr->fNoTrayIcon = FALSE;
 
       /* Indicate that we have processed this argument */
       return 1;
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 953548e..4fa987c 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -196,7 +196,7 @@ winScreenInit (int index,
 
       /* 
        * In this case, some of the defaults set in
-       * winInitializeDefaultScreens () are not correct ...
+       * winInitializeScreenDefaults() are not correct ...
        */
       if (!pScreenInfo->fUserGaveHeightAndWidth)
 	{
commit b61870595ba4df06006d24ed8c07cfe781bce1b7
Author: Tiago Vignatti <tiago.vignatti at nokia.com>
Date:   Thu Apr 22 20:20:48 2010 +0300

    xfree86: track screens' installed colormaps as screen privates
    
    Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index 804fd37..1a10327 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -731,7 +731,7 @@ DGAInstallCmap(ColormapPtr cmap)
     /* We rely on the extension to check that DGA is active */ 
 
     if(!pScreenPriv->dgaColormap) 
-	pScreenPriv->savedColormap = miInstalledMaps[pScreen->myNum];
+	pScreenPriv->savedColormap = GetInstalledmiColormap(pScreen);
 
     pScreenPriv->dgaColormap = cmap;    
 
diff --git a/hw/xfree86/common/xf86cmap.c b/hw/xfree86/common/xf86cmap.c
index f60d96e..e266ffb 100644
--- a/hw/xfree86/common/xf86cmap.c
+++ b/hw/xfree86/common/xf86cmap.c
@@ -63,10 +63,10 @@
 #define SCREEN_EPILOGUE(pScreen, field, wrapper)\
     ((pScreen)->field = wrapper)
 
-#define LOAD_PALETTE(pmap, index) \
-    ((pmap == miInstalledMaps[index]) && \
+#define LOAD_PALETTE(pmap) \
+    ((pmap == GetInstalledmiColormap(pmap->pScreen)) && \
      ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) || \
-      xf86Screens[index]->vtSema || pScreenPriv->isDGAmode))
+      xf86Screens[pmap->pScreen->myNum]->vtSema || pScreenPriv->isDGAmode))
 
 
 typedef struct _CMapLink {
@@ -221,7 +221,7 @@ Bool xf86HandleColormaps(
     }
 
     /* Force the initial map to be loaded */
-    miInstalledMaps[pScreen->myNum] = NULL;
+    SetInstalledmiColormap(pScreen, NULL);
     CMapInstallColormap(pDefMap);
     return TRUE;
 }
@@ -425,11 +425,10 @@ static void
 CMapInstallColormap(ColormapPtr pmap)
 {
     ScreenPtr 	  pScreen = pmap->pScreen;
-    int		  index = pScreen->myNum;
     CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
 	&pScreen->devPrivates, CMapScreenKey);
 
-    if (pmap == miInstalledMaps[index])
+    if (pmap == GetInstalledmiColormap(pmap->pScreen))
 	return;
 
     pScreen->InstallColormap = pScreenPriv->InstallColormap;
@@ -438,15 +437,15 @@ CMapInstallColormap(ColormapPtr pmap)
 
     /* Important. We let the lower layers, namely DGA, 
        overwrite the choice of Colormap to install */
-    if (miInstalledMaps[index])
-	pmap = miInstalledMaps[index];
+    if (GetInstalledmiColormap(pmap->pScreen))
+	pmap = GetInstalledmiColormap(pmap->pScreen);
 
     if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
 	 (pmap->pVisual->class == TrueColor) &&
 	 CMapColormapUseMax(pmap->pVisual, pScreenPriv))
 	return;
 
-    if(LOAD_PALETTE(pmap, index))
+    if(LOAD_PALETTE(pmap))
 	CMapReinstallMap(pmap);
 }
 
@@ -461,8 +460,8 @@ CMapEnterVT(int index, int flags)
 	&pScreen->devPrivates, CMapScreenKey);
 
     if((*pScreenPriv->EnterVT)(index, flags)) {
-	if(miInstalledMaps[index])
-	    CMapReinstallMap(miInstalledMaps[index]);
+	if(GetInstalledmiColormap(pScreen))
+	    CMapReinstallMap(GetInstalledmiColormap(pScreen));
 	return TRUE;
     }
     return FALSE;
@@ -477,8 +476,8 @@ CMapSwitchMode(int index, DisplayModePtr mode, int flags)
 	&pScreen->devPrivates, CMapScreenKey);
 
     if((*pScreenPriv->SwitchMode)(index, mode, flags)) {
-	if(miInstalledMaps[index])
-	    CMapReinstallMap(miInstalledMaps[index]);
+	if(GetInstalledmiColormap(pScreen))
+	    CMapReinstallMap(GetInstalledmiColormap(pScreen));
 	return TRUE;
     }
     return FALSE;
@@ -497,9 +496,9 @@ CMapSetDGAMode(int index, int num, DGADevicePtr dev)
 
     pScreenPriv->isDGAmode = DGAActive(index);
 
-    if(!pScreenPriv->isDGAmode && miInstalledMaps[index] 
+    if(!pScreenPriv->isDGAmode && GetInstalledmiColormap(pScreen)
          && xf86Screens[pScreen->myNum]->vtSema)
-	CMapReinstallMap(miInstalledMaps[index]);
+	CMapReinstallMap(GetInstalledmiColormap(pScreen));
 
     return ret;
 }
@@ -649,7 +648,7 @@ CMapRefreshColors(ColormapPtr pmap, int defs, int* indices)
     }
 
 
-    if(LOAD_PALETTE(pmap, pmap->pScreen->myNum))
+    if(LOAD_PALETTE(pmap))
 	(*pScrn->LoadPalette)(pScreenPriv->pScrn, defs, indices,
  					colors, pmap->pVisual);
 
@@ -802,7 +801,7 @@ CMapSetOverscan(ColormapPtr pmap, int defs, int *indices)
     }
     if (newOverscan) {
 	pColPriv->overscan = overscan;
-	if (LOAD_PALETTE(pmap, pmap->pScreen->myNum)) {
+	if (LOAD_PALETTE(pmap)) {
 #ifdef DEBUGOVERSCAN
 	    ErrorF("SetOverscan() called from CmapSetOverscan\n");
 #endif
@@ -929,10 +928,10 @@ CMapChangeGamma(
 	pLink = pLink->next;
     }
 
-    if(miInstalledMaps[pScreen->myNum] && 
+    if(GetInstalledmiColormap(pScreen) &&
        ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
 	pScrn->vtSema || pScreenPriv->isDGAmode)) {
-	ColormapPtr pMap = miInstalledMaps[pScreen->myNum];
+	ColormapPtr pMap = GetInstalledmiColormap(pScreen);
 
 	if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
 	    (pMap->pVisual->class == TrueColor) &&
@@ -951,9 +950,9 @@ CMapChangeGamma(
 	    if(pLink) {
 		/* need to trick CMapRefreshColors() into thinking 
 		   this is the currently installed map */
-		miInstalledMaps[pScreen->myNum] = pLink->cmap;
+		SetInstalledmiColormap(pScreen, pLink->cmap);
 		CMapReinstallMap(pLink->cmap);
-		miInstalledMaps[pScreen->myNum] = pMap;
+		SetInstalledmiColormap(pScreen, pMap);
 	    }
 	} else
 	    CMapReinstallMap(pMap);
@@ -1035,10 +1034,10 @@ xf86ChangeGammaRamp(
         pLink = pLink->next;
     }
 
-    if(miInstalledMaps[pScreen->myNum] &&
+    if(GetInstalledmiColormap(pScreen) &&
        ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
         pScrn->vtSema || pScreenPriv->isDGAmode)) {
-        ColormapPtr pMap = miInstalledMaps[pScreen->myNum];
+        ColormapPtr pMap = GetInstalledmiColormap(pScreen);
 
         if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
             (pMap->pVisual->class == TrueColor) &&
@@ -1057,9 +1056,9 @@ xf86ChangeGammaRamp(
             if(pLink) {
                 /* need to trick CMapRefreshColors() into thinking
                    this is the currently installed map */
-                miInstalledMaps[pScreen->myNum] = pLink->cmap;
+                SetInstalledmiColormap(pScreen, pLink->cmap);
                 CMapReinstallMap(pLink->cmap);
-                miInstalledMaps[pScreen->myNum] = pMap;
+                SetInstalledmiColormap(pScreen, pMap);
             }
         } else
             CMapReinstallMap(pMap);
diff --git a/hw/xfree86/vgahw/vgaCmap.c b/hw/xfree86/vgahw/vgaCmap.c
index 5bd38b4..06eeb4c 100644
--- a/hw/xfree86/vgahw/vgaCmap.c
+++ b/hw/xfree86/vgahw/vgaCmap.c
@@ -50,7 +50,7 @@ vgaListInstalledColormaps(pScreen, pmaps)
   /* By the time we are processing requests, we can guarantee that there
    * is always a colormap installed */
   
-  *pmaps = miInstalledMaps[pScreen->myNum]->mid;
+  *pmaps = GetInstalledmiColormap(pScreen)->mid;
   return(1);
 }
 
@@ -62,13 +62,13 @@ vgaGetInstalledColormaps(pScreen, pmaps)
   /* By the time we are processing requests, we can guarantee that there
    * is always a colormap installed */
   
-  *pmaps = miInstalledMaps[pScreen->myNum];
+  *pmaps = GetInstalledmiColormap(pScreen);
   return(1);
 }
 
 int vgaCheckColorMap(ColormapPtr pmap)
 {
-  return (pmap != miInstalledMaps[pmap->pScreen->myNum]);
+  return (pmap != GetInstalledmiColormap(pmap->pScreen));
 }
 
 
@@ -217,7 +217,7 @@ void
 vgaInstallColormap(pmap)
      ColormapPtr	pmap;
 {
-  ColormapPtr oldmap = miInstalledMaps[pmap->pScreen->myNum];
+  ColormapPtr oldmap = GetInstalledmiColormap(pmap->pScreen);
   int         entries;
   Pixel *     ppix;
   xrgb *      prgb;
@@ -242,7 +242,7 @@ vgaInstallColormap(pmap)
   if ( oldmap != NOMAPYET)
     WalkTree( pmap->pScreen, TellLostMap, &oldmap->mid);
 
-  miInstalledMaps[pmap->pScreen->myNum] = pmap;
+  SetInstalledmiColormap(pmap->pScreen, pmap);
 
   for ( i=0; i<entries; i++) ppix[i] = i;
 
@@ -273,13 +273,13 @@ vgaUninstallColormap(pmap)
 
   ColormapPtr defColormap;
   
-  if ( pmap != miInstalledMaps[pmap->pScreen->myNum] )
+  if ( pmap != GetInstalledmiColormap(pmap->pScreen))
     return;
 
   dixLookupResourceByType((pointer *)&defColormap, pmap->pScreen->defColormap,
 			  RT_COLORMAP, serverClient, DixInstallAccess);
 
-  if (defColormap == miInstalledMaps[pmap->pScreen->myNum])
+  if (defColormap == GetInstalledmiColormap(pmap->pScreen))
     return;
 
   (*pmap->pScreen->InstallColormap) (defColormap);
commit a94f5455c71363d5047668ee093901b9e1645cf1
Author: Tiago Vignatti <tiago.vignatti at nokia.com>
Date:   Thu Apr 22 20:20:43 2010 +0300

    mi: track screens' installed colormaps as screen privates
    
    Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/mi/micmap.c b/mi/micmap.c
index e832be7..cc829fc 100644
--- a/mi/micmap.c
+++ b/mi/micmap.c
@@ -40,13 +40,14 @@
 #include "globals.h"
 #include "micmap.h"
 
-ColormapPtr miInstalledMaps[MAXSCREENS];
+static int micmapScrPrivateKeyIndex;
+DevPrivateKey micmapScrPrivateKey = &micmapScrPrivateKeyIndex;
 
 int
 miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 {
-    if (miInstalledMaps[pScreen->myNum]) {
-	*pmaps = miInstalledMaps[pScreen->myNum]->mid;
+    if (GetInstalledmiColormap(pScreen)) {
+	*pmaps = GetInstalledmiColormap(pScreen)->mid;
 	return (1);
     }
     return 0;
@@ -55,8 +56,7 @@ miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 void
 miInstallColormap(ColormapPtr pmap)
 {
-    int index = pmap->pScreen->myNum;
-    ColormapPtr oldpmap = miInstalledMaps[index];
+    ColormapPtr oldpmap = GetInstalledmiColormap(pmap->pScreen);
 
     if(pmap != oldpmap)
     {
@@ -65,7 +65,7 @@ miInstallColormap(ColormapPtr pmap)
 	if(oldpmap != (ColormapPtr)None)
 	    WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
 	/* Install pmap */
-	miInstalledMaps[index] = pmap;
+	SetInstalledmiColormap(pmap->pScreen, pmap);
 	WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
 
     }
@@ -74,8 +74,7 @@ miInstallColormap(ColormapPtr pmap)
 void
 miUninstallColormap(ColormapPtr pmap)
 {
-    int index = pmap->pScreen->myNum;
-    ColormapPtr curpmap = miInstalledMaps[index];
+    ColormapPtr curpmap = GetInstalledmiColormap(pmap->pScreen);
 
     if(pmap == curpmap)
     {
diff --git a/mi/micmap.h b/mi/micmap.h
index 5c8448a..8ad94b9 100644
--- a/mi/micmap.h
+++ b/mi/micmap.h
@@ -4,7 +4,13 @@
 #ifndef _MICMAP_H_
 #define _MICMAP_H_
 
-extern _X_EXPORT ColormapPtr miInstalledMaps[MAXSCREENS];
+#define GetInstalledmiColormap(s) \
+    ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, micmapScrPrivateKey))
+#define SetInstalledmiColormap(s,c) \
+    (dixSetPrivate(&(s)->devPrivates, micmapScrPrivateKey, c))
+
+extern _X_EXPORT DevPrivateKey micmapScrPrivateKey;
+
 
 typedef Bool (* miInitVisualsProcPtr)(VisualPtr *, DepthPtr *, int *, int *,
 					int *, VisualID *, unsigned long, int,
commit a2c716eaf6b3a4ce75382394636a0a890b5dcfe0
Author: Jamey Sharp <jamey at minilop.net>
Date:   Thu Apr 22 07:34:04 2010 +0200

    fb: track screens' installed colormaps as screen privates.
    
    Several DDXes allow each screen to have at most one (or in some cases,
    exactly one) installed colormap. These all use the same pattern: Declare
    a global-lifetime array of MAXSCREENS ColormapPtrs, and index it by
    screen number. This patch converts most of those to use screen privates
    instead.
    
    Signed-off-by: Jamey Sharp <jamey at minilop.net>
    Acked-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/fb/fbcmap.c b/fb/fbcmap.c
index 2ff3234..b775bc3 100644
--- a/fb/fbcmap.c
+++ b/fb/fbcmap.c
@@ -36,16 +36,18 @@
 #error "You should be compiling fbcmap_mi.c instead of fbcmap.c!"
 #endif
 
+static int cmapScrPrivateKeyIndex;
+static DevPrivateKey cmapScrPrivateKey = &cmapScrPrivateKeyIndex;
 
-
-ColormapPtr FbInstalledMaps[MAXSCREENS];
+#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
+#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
 
 int
 fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 {
     /* By the time we are processing requests, we can guarantee that there
      * is always a colormap installed */
-    *pmaps = FbInstalledMaps[pScreen->myNum]->mid;
+    *pmaps = GetInstalledColormap(pScreen)->mid;
     return (1);
 }
 
@@ -53,8 +55,7 @@ fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 void
 fbInstallColormap(ColormapPtr pmap)
 {
-    int index = pmap->pScreen->myNum;
-    ColormapPtr oldpmap = FbInstalledMaps[index];
+    ColormapPtr oldpmap = GetInstalledColormap(pmap->pScreen);
 
     if(pmap != oldpmap)
     {
@@ -63,7 +64,7 @@ fbInstallColormap(ColormapPtr pmap)
 	if(oldpmap != (ColormapPtr)None)
 	    WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
 	/* Install pmap */
-	FbInstalledMaps[index] = pmap;
+	SetInstalledColormap(pmap->pScreen, pmap);
 	WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
     }
 }
@@ -71,8 +72,7 @@ fbInstallColormap(ColormapPtr pmap)
 void
 fbUninstallColormap(ColormapPtr pmap)
 {
-    int index = pmap->pScreen->myNum;
-    ColormapPtr curpmap = FbInstalledMaps[index];
+    ColormapPtr curpmap = GetInstalledColormap(pmap->pScreen);
 
     if(pmap == curpmap)
     {
diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index 60915fd..b2baa19 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -427,14 +427,18 @@ ddxProcessArgument(int argc, char *argv[], int i)
     return 0;
 }
 
-static ColormapPtr InstalledMaps[MAXSCREENS];
+static int cmapScrPrivateKeyIndex;
+static DevPrivateKey cmapScrPrivateKey = &cmapScrPrivateKeyIndex;
+
+#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
+#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
 
 static int
 vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 {
     /* By the time we are processing requests, we can guarantee that there
      * is always a colormap installed */
-    *pmaps = InstalledMaps[pScreen->myNum]->mid;
+    *pmaps = GetInstalledColormap(pScreen)->mid;
     return (1);
 }
 
@@ -442,8 +446,7 @@ vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 static void
 vfbInstallColormap(ColormapPtr pmap)
 {
-    int index = pmap->pScreen->myNum;
-    ColormapPtr oldpmap = InstalledMaps[index];
+    ColormapPtr oldpmap = GetInstalledColormap(pmap->pScreen);
 
     if (pmap != oldpmap)
     {
@@ -459,7 +462,7 @@ vfbInstallColormap(ColormapPtr pmap)
 	if(oldpmap != (ColormapPtr)None)
 	    WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
 	/* Install pmap */
-	InstalledMaps[index] = pmap;
+	SetInstalledColormap(pmap->pScreen, pmap);
 	WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
 
 	entries = pmap->pVisual->ColormapEntries;
@@ -500,7 +503,7 @@ vfbInstallColormap(ColormapPtr pmap)
 static void
 vfbUninstallColormap(ColormapPtr pmap)
 {
-    ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
+    ColormapPtr curpmap = GetInstalledColormap(pmap->pScreen);
 
     if(pmap == curpmap)
     {
@@ -521,7 +524,7 @@ vfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
     XWDColor *pXWDCmap;
     int i;
 
-    if (pmap != InstalledMaps[pmap->pScreen->myNum])
+    if (pmap != GetInstalledColormap(pmap->pScreen))
     {
 	return;
     }
@@ -830,10 +833,10 @@ vfbCloseScreen(int index, ScreenPtr pScreen)
 
     /*
      * XXX probably lots of stuff to clean.  For now,
-     * clear InstalledMaps[] so that server reset works correctly.
+     * clear installed colormaps so that server reset works correctly.
      */
-    for (i = 0; i < MAXSCREENS; i++)
-	InstalledMaps[i] = NULL;
+    for (i = 0; i < screenInfo.numScreens; i++)
+	SetInstalledColormap(screenInfo.screens[i], NULL);
 
     return pScreen->CloseScreen(index, pScreen);
 }
diff --git a/hw/xnest/Color.c b/hw/xnest/Color.c
index dc74947..2e6de15 100644
--- a/hw/xnest/Color.c
+++ b/hw/xnest/Color.c
@@ -34,7 +34,11 @@ is" without express or implied warranty.
 #include "XNWindow.h"
 #include "Args.h"
 
-static ColormapPtr InstalledMaps[MAXSCREENS];
+static int cmapScrPrivateKeyIndex;
+static DevPrivateKey cmapScrPrivateKey = &cmapScrPrivateKeyIndex;
+
+#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
+#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
 
 Bool
 xnestCreateColormap(ColormapPtr pCmap)
@@ -332,11 +336,7 @@ xnestDirectUninstallColormaps(ScreenPtr pScreen)
 void
 xnestInstallColormap(ColormapPtr pCmap)
 {
-  int index;
-  ColormapPtr pOldCmap;
-  
-  index = pCmap->pScreen->myNum;
-  pOldCmap = InstalledMaps[index];
+  ColormapPtr pOldCmap = GetInstalledColormap(pCmap->pScreen);
   
   if(pCmap != pOldCmap)
     {
@@ -346,7 +346,7 @@ xnestInstallColormap(ColormapPtr pCmap)
       if(pOldCmap != (ColormapPtr)None)
 	WalkTree(pCmap->pScreen, TellLostMap, (pointer)&pOldCmap->mid);
       
-      InstalledMaps[index] = pCmap;
+      SetInstalledColormap(pCmap->pScreen, pCmap);
       WalkTree(pCmap->pScreen, TellGainedMap, (pointer)&pCmap->mid);
       
       xnestSetInstalledColormapWindows(pCmap->pScreen);
@@ -357,11 +357,7 @@ xnestInstallColormap(ColormapPtr pCmap)
 void
 xnestUninstallColormap(ColormapPtr pCmap)
 {
-  int index;
-  ColormapPtr pCurCmap;
-  
-  index = pCmap->pScreen->myNum;
-  pCurCmap = InstalledMaps[index];
+  ColormapPtr pCurCmap = GetInstalledColormap(pCmap->pScreen);
   
   if(pCmap == pCurCmap)
     {
@@ -382,7 +378,7 @@ int
 xnestListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIDs)
 {
   if (xnestInstalledDefaultColormap) {
-    *pCmapIDs = InstalledMaps[pScreen->myNum]->mid;
+    *pCmapIDs = GetInstalledColormap(pScreen)->mid;
     return 1;
   }
   else
commit e055bef055b6c726e9f3ef91a83585d13c80651d
Author: Jamey Sharp <jamey at minilop.net>
Date:   Thu Apr 22 06:08:29 2010 +0200

    xfree86: use screen privates for exclusive DGA clients
    
    Most DGA requests allow at most one client to be using DGA on each screen.
    Instead of keeping track of the current client in a MAXSCREEN-sized array,
    track it in a per-screen private.
    
    Signed-off-by: Jamey Sharp <jamey at minilop.net>
    Acked-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/dixmods/extmod/xf86dga2.c b/hw/xfree86/dixmods/extmod/xf86dga2.c
index 5367bcc..0385514 100644
--- a/hw/xfree86/dixmods/extmod/xf86dga2.c
+++ b/hw/xfree86/dixmods/extmod/xf86dga2.c
@@ -57,12 +57,12 @@ static void XDGAResetProc(ExtensionEntry *extEntry);
 
 static void DGAClientStateChange (CallbackListPtr*, pointer, pointer);
 
-static ClientPtr DGAClients[MAXSCREENS];
-
 unsigned char DGAReqCode = 0;
 int DGAErrorBase;
 int DGAEventBase;
 
+static int DGAScreenPrivateKeyIndex;
+static DevPrivateKey DGAScreenPrivateKey = &DGAScreenPrivateKeyIndex;
 static int DGAClientPrivateKeyIndex;
 static DevPrivateKey DGAClientPrivateKey = &DGAClientPrivateKeyIndex;
 static int DGACallbackRefCount = 0;
@@ -73,6 +73,11 @@ typedef struct {
     int		minor;
 } DGAPrivRec, *DGAPrivPtr;
 
+#define DGA_GETCLIENT(idx) ((ClientPtr) \
+    dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey))
+#define DGA_SETCLIENT(idx,p) \
+    dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p)
+
 #define DGA_GETPRIV(c) ((DGAPrivPtr) \
     dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
 #define DGA_SETPRIV(c,p) \
@@ -93,9 +98,6 @@ XFree86DGAExtensionInit(INITARGS)
 				StandardMinorOpcode))) {
 	int i;
 
-	for(i = 0; i < MAXSCREENS; i++)
-	     DGAClients[i] = NULL;
-
 	DGAReqCode = (unsigned char)extEntry->base;
 	DGAErrorBase = extEntry->errorBase;
 	DGAEventBase = extEntry->eventBase;
@@ -282,7 +284,7 @@ DGAClientStateChange (
     int i;
 
     for(i = 0; i < screenInfo.numScreens; i++) {
-	if(DGAClients[i] == pci->client) {
+	if(DGA_GETCLIENT(i) == pci->client) {
 	   client = pci->client;
 	   break;
 	}
@@ -294,7 +296,7 @@ DGAClientStateChange (
 	XDGAModeRec mode;
 	PixmapPtr pPix;
 
-	DGAClients[i] = NULL;
+	DGA_SETCLIENT(i, NULL);
 	DGASelectInput(i, NULL, 0);
 	DGASetMode(i, 0, &mode, &pPix);
 
@@ -311,10 +313,12 @@ ProcXDGASetMode(ClientPtr client)
     XDGAModeRec mode;
     xXDGAModeInfo info;
     PixmapPtr pPix;
+    ClientPtr owner;
     int size;
 
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
+    owner = DGA_GETCLIENT(stuff->screen);
 
     REQUEST_SIZE_MATCH(xXDGASetModeReq);
     rep.type = X_Reply;
@@ -326,16 +330,15 @@ ProcXDGASetMode(ClientPtr client)
     if (!DGAAvailable(stuff->screen))
         return DGAErrorBase + XF86DGANoDirectVideoMode;
 
-    if(DGAClients[stuff->screen] &&
-      (DGAClients[stuff->screen] != client))
+    if(owner && owner != client)
         return DGAErrorBase + XF86DGANoDirectVideoMode;
 
     if(!stuff->mode) {
-	if(DGAClients[stuff->screen]) {
+	if(owner) {
 	  if(--DGACallbackRefCount == 0)
 	    DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
 	}
-	DGAClients[stuff->screen] = NULL;
+	DGA_SETCLIENT(stuff->screen, NULL);
 	DGASelectInput(stuff->screen, NULL, 0);
 	DGASetMode(stuff->screen, 0, &mode, &pPix);
 	WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
@@ -345,12 +348,12 @@ ProcXDGASetMode(ClientPtr client)
     if(Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
 	return BadValue;
 
-    if(!DGAClients[stuff->screen]) {
+    if(!owner) {
 	if(DGACallbackRefCount++ == 0)
 	   AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
     }
 
-    DGAClients[stuff->screen] = client;
+    DGA_SETCLIENT(stuff->screen, client);
 
     if(pPix) {
 	if(AddResource(stuff->pid, RT_PIXMAP, (pointer)(pPix))) {
@@ -405,7 +408,7 @@ ProcXDGASetViewport(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGASetViewportReq);
@@ -425,7 +428,7 @@ ProcXDGAInstallColormap(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
@@ -451,12 +454,12 @@ ProcXDGASelectInput(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGASelectInputReq);
 
-    if(DGAClients[stuff->screen] == client)
+    if(DGA_GETCLIENT(stuff->screen) == client)
 	DGASelectInput(stuff->screen, client, stuff->mask);
 
     return (client->noClientException);
@@ -471,7 +474,7 @@ ProcXDGAFillRectangle(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
@@ -491,7 +494,7 @@ ProcXDGACopyArea(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGACopyAreaReq);
@@ -512,7 +515,7 @@ ProcXDGACopyTransparentArea(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq);
@@ -534,7 +537,7 @@ ProcXDGAGetViewportStatus(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq);
@@ -557,7 +560,7 @@ ProcXDGASync(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGASyncReq);
@@ -602,7 +605,7 @@ ProcXDGAChangePixmapMode(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
@@ -633,7 +636,7 @@ ProcXDGACreateColormap(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
         return BadValue;
 
-    if(DGAClients[stuff->screen] != client)
+    if(DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXDGACreateColormapReq);
@@ -713,18 +716,19 @@ ProcXF86DGADirectVideo(ClientPtr client)
     int num;
     PixmapPtr pix;
     XDGAModeRec mode;
+    ClientPtr owner;
     REQUEST(xXF86DGADirectVideoReq);
 
     if (stuff->screen > screenInfo.numScreens)
 	return BadValue;
+    owner = DGA_GETCLIENT(stuff->screen);
 
     REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
 
     if (!DGAAvailable(stuff->screen))
 	return DGAErrorBase + XF86DGANoDirectVideoMode;
 
-    if (DGAClients[stuff->screen] &&
-        (DGAClients[stuff->screen] != client))
+    if (owner && owner != client)
         return DGAErrorBase + XF86DGANoDirectVideoMode;
 
     if (stuff->enable & XF86DGADirectGraphics) {
@@ -743,19 +747,19 @@ ProcXF86DGADirectVideo(ClientPtr client)
     /* We need to track the client and attach the teardown callback */
     if (stuff->enable &
 	(XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) {
-	if (!DGAClients[stuff->screen]) {
+	if (!owner) {
 	    if (DGACallbackRefCount++ == 0)
 		AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
 	}
 
-	DGAClients[stuff->screen] = client;
+	DGA_SETCLIENT(stuff->screen, client);
     } else {
-	if (DGAClients[stuff->screen]) {
+	if (owner) {
 	    if (--DGACallbackRefCount == 0)
 		DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
 	}
 
-	DGAClients[stuff->screen] = NULL;
+	DGA_SETCLIENT(stuff->screen, NULL);
     }
 
     return (client->noClientException);
@@ -800,7 +804,7 @@ ProcXF86DGASetViewPort(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
 	return BadValue;
 
-    if (DGAClients[stuff->screen] != client)
+    if (DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
@@ -864,7 +868,7 @@ ProcXF86DGAInstallColormap(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
 	return BadValue;
 
-    if (DGAClients[stuff->screen] != client)
+    if (DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq);
@@ -913,7 +917,7 @@ ProcXF86DGAViewPortChanged(ClientPtr client)
     if (stuff->screen > screenInfo.numScreens)
 	return BadValue;
 
-    if (DGAClients[stuff->screen] != client)
+    if (DGA_GETCLIENT(stuff->screen) != client)
         return DGAErrorBase + XF86DGADirectNotActivated;
 
     REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq);
commit 7c9733d063acee04735a0e75d62e508fe4ea1163
Author: Jamey Sharp <jamey at minilop.net>
Date:   Fri Apr 23 06:41:00 2010 +0200

    xfree86: use screen privates for Xv offscreen images.
    
    This replaces a globally-allocated array that depended on MAXSCREENS.
    
    Signed-off-by: Jamey Sharp <jamey at minilop.net>
    Acked-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index bdcc4fc..1503502 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -186,7 +186,9 @@ typedef struct {
    int num;
 } OffscreenImageRec;
 
-static OffscreenImageRec OffscreenImages[MAXSCREENS];
+static int OffscreenPrivateKeyIndex;
+static DevPrivateKey OffscreenPrivateKey = &OffscreenPrivateKeyIndex;
+#define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey))
 
 Bool
 xf86XVRegisterOffscreenImages(
@@ -194,9 +196,15 @@ xf86XVRegisterOffscreenImages(
     XF86OffscreenImagePtr images,
     int num
 ){
-    OffscreenImages[pScreen->myNum].num = num;
-    OffscreenImages[pScreen->myNum].images = images;
-
+    OffscreenImageRec *OffscreenImage;
+    if(!dixRequestPrivate(OffscreenPrivateKey, sizeof(OffscreenImageRec)) ||
+       !(OffscreenImage = GetOffscreenImage(pScreen)))
+        /* Every X.org driver assumes this function always succeeds, so
+         * just die on allocation failure. */
+        FatalError("Could not allocate private storage for XV offscreen images.\n");
+
+    OffscreenImage->num = num;
+    OffscreenImage->images = images;
     return TRUE;
 }
 
@@ -205,8 +213,9 @@ xf86XVQueryOffscreenImages(
    ScreenPtr pScreen,
    int *num
 ){
-   *num = OffscreenImages[pScreen->myNum].num;
-   return OffscreenImages[pScreen->myNum].images;
+    OffscreenImageRec *OffscreenImage = GetOffscreenImage(pScreen);
+    *num = OffscreenImage->num;
+    return OffscreenImage->images;
 }
 
 
@@ -1177,9 +1186,6 @@ xf86XVCloseScreen(int i, ScreenPtr pScreen)
   XvAdaptorPtr pa;
   int c;
 
-  /* Clear offscreen images */
-  memset(&OffscreenImages[pScreen->myNum], 0, sizeof(OffscreenImages[0]));
-
   if(!ScreenPriv) return TRUE;
 
   if(ScreenPriv->videoGC) {


More information about the Xquartz-changes mailing list