[PATCH] Remove static MAXSCREENS limit from Xext/shm.c.

Kevin E Martin kem at freedesktop.org
Fri Oct 2 08:23:26 PDT 2009


On Thu, Oct 01, 2009 at 03:08:22PM -0700, Keith Packard wrote:
> Excerpts from Jamey Sharp's message of Wed Sep 30 22:29:39 -0700 2009:
> > ---
> > Somebody at XDC today said that getting rid of the static MAXSCREENS
> > limit from the X server would be a Good Thing, and it looked like doing
> > that to Xext/shm.c would be pretty easy, so I tried it.
> 
> Thanks for giving this a try. The canonical way to do this is to
> allocate a screen private index and then allocate memory per-screen
> instead of globally, but your patch is simpler and easier to review.
> 
> Check out mi/misprite.c and see the pattern of the form:
> 
> static int miSpriteScreenKeyIndex;
> static DevPrivateKey miSpriteScreenKey = &miSpriteScreenKeyIndex;
> 
> miSpriteInitialize:
> 
>     pScreenPriv = xalloc (sizeof (miSpriteScreenRec));
> 	...
>     dixSetPrivate(&pScreen->devPrivates, miSpriteScreenKey, pScreenPriv);
> 	
> Then, functions which need per-screen info do:
> 
>     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
> 
> You then wrap CloseScreen (in the usual way) and free your private
> structure there.

Attached below is the ancient MAXSCREENS patch.  As some might recall,
we didn't include this back in 2004 when it was first written because it
had an ABI break.  The patch will obviously need some work, and you may
not want to follow how they did the work, but I've included it here for
reference and in case it proves to be useful.  If you do find it useful
or can resurrect it, please give Rik Faith and James Antill credit for
their work.

Kevin
-------------- next part --------------
The following patch changes MAXSCREENS from a #define to an int.  The
patch is against the XFree86 CVS repository.

The goals of the patch are as follows:
    1) Allow MAXSCREENS to be determined at run time instead of compile
       time (a new -maxscreens command line flag was added).
    2) Make minimal source-code changes to the tree:
       a) The name "MAXSCREENS" was not changed -- this allowed all of
          the loops that reference MAXSCREENS to remain unchanged.
       b) MAXSCREENSALLOC is a convenience macro that allocates and
          zeros memory, allowing 1-line changes to allocate code (and
          another line to check that allocation succeeded).  Memory is
          zero'd because many routines assume that the previous static
          allocations are zero'd.  The macro is also safe to call
          multiple times since there are places in the code where the
          first use of a MAXSCREENS-sized array is difficult to
          determine (or non-deterministic).
       c) In some cases, the existing code zeros the memory.  These
          calls are unchanged, but could be removed.

Some of the changes could not be tested because we do not have the
appropriate hardware available -- it would be possible to substitute
MAXSCREENSDEFAULT for MAXSCREENS in these code paths (i.e., and leave
them as compile-time configurable code paths):
    config/cf/iPAQH3600.cf
    config/cf/itsy.cf
    programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c
    programs/Xserver/hw/kdrive/kxv.c
    programs/Xserver/hw/sun/sunInit.c
    programs/Xserver/hw/sunLynx/sunLyInit.c
    programs/Xserver/hw/xfree86/drivers/* [all the changes are similar]
    programs/Xserver/hw/xfree86/os-support/bsd/arm_video.c
    programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c
    programs/Xserver/hw/xwin/InitOutput.c

The diffstat is below, followed by the patch.

======================================================================

 config/cf/iPAQH3600.cf                                      |    2 
 config/cf/itsy.cf                                           |    2 
 programs/Xserver/GL/mesa/src/X/xf86glx.c                    |    6 
 programs/Xserver/Xext/appgroup.c                            |   13 +
 programs/Xserver/Xext/mbufbf.c                              |   19 +-
 programs/Xserver/Xext/panoramiX.c                           |   15 +
 programs/Xserver/Xext/panoramiX.h                           |    2 
 programs/Xserver/Xext/panoramiXprocs.c                      |  107 +++++++++---
 programs/Xserver/Xext/panoramiXsrv.h                        |    2 
 programs/Xserver/Xext/shm.c                                 |   29 ++-
 programs/Xserver/Xext/xf86dga2.c                            |    3 
 programs/Xserver/Xext/xprint.c                              |    4 
 programs/Xserver/Xext/xvdisp.c                              |    8 
 programs/Xserver/dbe/dbe.c                                  |    5 
 programs/Xserver/dix/cursor.c                               |   69 +++++++
 programs/Xserver/dix/dispatch.c                             |    9 +
 programs/Xserver/dix/events.c                               |    3 
 programs/Xserver/dix/extension.c                            |    5 
 programs/Xserver/dix/globals.c                              |    2 
 programs/Xserver/dix/main.c                                 |   45 ++++-
 programs/Xserver/dix/window.c                               |    2 
 programs/Xserver/fb/fbcmap.c                                |   11 -
 programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c   |   10 +
 programs/Xserver/hw/kdrive/kxv.c                            |    4 
 programs/Xserver/hw/sun/sunInit.c                           |   14 +
 programs/Xserver/hw/sunLynx/sunLyInit.c                     |    6 
 programs/Xserver/hw/vfb/InitOutput.c                        |    8 
 programs/Xserver/hw/xfree86/common/xf86Cursor.c             |   64 +++----
 programs/Xserver/hw/xfree86/common/xf86xv.c                 |    3 
 programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c          |    4 
 programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c        |    4 
 programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c          |    4 
 programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c        |    4 
 programs/Xserver/hw/xfree86/drivers/dummy/dummy_dga.c       |    4 
 programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c       |    4 
 programs/Xserver/hw/xfree86/drivers/i128/i128dga.c          |    4 
 programs/Xserver/hw/xfree86/drivers/i740/i740_dga.c         |    4 
 programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c         |    4 
 programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c         |    4 
 programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c           |    4 
 programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c      |    4 
 programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_dga.c       |    4 
 programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_dga.c       |    4 
 programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c             |    4 
 programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c          |   10 -
 programs/Xserver/hw/xfree86/drivers/nv/riva_dga.c           |    4 
 programs/Xserver/hw/xfree86/drivers/s3/s3_dga.c             |    4 
 programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c       |    4 
 programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c     |   13 +
 programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_dga.c |    4 
 programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c           |    4 
 programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c         |    4 
 programs/Xserver/hw/xfree86/drivers/trident/trident_dga.c   |    4 
 programs/Xserver/hw/xfree86/drivers/tseng/tseng_dga.c       |    4 
 programs/Xserver/hw/xfree86/os-support/bsd/arm_video.c      |    4 
 programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c    |   21 +-
 programs/Xserver/hw/xfree86/xf8_16bpp/cfbscrinit.c          |    7 
 programs/Xserver/hw/xfree86/xf8_32wid/cfbscrinit.c          |    7 
 programs/Xserver/hw/xnest/Args.c                            |    4 
 programs/Xserver/hw/xnest/Color.c                           |    6 
 programs/Xserver/hw/xnest/Init.c                            |    3 
 programs/Xserver/hw/xnest/Screen.c                          |    4 
 programs/Xserver/hw/xnest/Screen.h                          |    4 
 programs/Xserver/hw/xwin/InitOutput.c                       |    6 
 programs/Xserver/include/cursorstr.h                        |    4 
 programs/Xserver/include/dixstruct.h                        |    2 
 programs/Xserver/include/globals.h                          |    2 
 programs/Xserver/include/misc.h                             |   48 +++++
 programs/Xserver/include/scrnintstr.h                       |    2 
 programs/Xserver/include/windowstr.h                        |    2 
 programs/Xserver/lbx/lbxdix.c                               |    2 
 programs/Xserver/mi/miclipn.c                               |    4 
 programs/Xserver/mi/micmap.c                                |    3 
 programs/Xserver/mi/micmap.h                                |    2 
 programs/Xserver/mi/miexpose.c                              |    4 
 programs/Xserver/os/utils.c                                 |   14 +
 programs/Xserver/render/render.c                            |   12 +
 77 files changed, 589 insertions(+), 165 deletions(-)

Index: config/cf/iPAQH3600.cf
===================================================================
RCS file: /cvs/xc/config/cf/iPAQH3600.cf,v
retrieving revision 1.2
diff -u -p -r1.2 iPAQH3600.cf
--- config/cf/iPAQH3600.cf	10 Oct 2000 14:05:48 -0000	1.2
+++ config/cf/iPAQH3600.cf	8 Mar 2004 21:04:12 -0000
@@ -55,7 +55,7 @@
 
 #define GzipFontCompression	YES
 
-#define KdriveServerExtraDefines -DITSY -DMAXSCREENS=1
+#define KdriveServerExtraDefines -DITSY -DMAXSCREENSDEFAULT=1
 
 #define HostLinkRule(target, flags, src, libs)  cc -I$(BUILDINCDIR) -o target src
 
Index: config/cf/itsy.cf
===================================================================
RCS file: /cvs/xc/config/cf/itsy.cf,v
retrieving revision 1.2
diff -u -p -r1.2 itsy.cf
--- config/cf/itsy.cf	31 Mar 2000 20:13:11 -0000	1.2
+++ config/cf/itsy.cf	8 Mar 2004 21:04:12 -0000
@@ -54,7 +54,7 @@
 
 #define GzipFontCompression	NO
 
-#define KdriveServerExtraDefines -DITSY -DMAXSCREENS=1
+#define KdriveServerExtraDefines -DITSY -DMAXSCREENSDEFAULT=1
 
 #define HostLinkRule(target, flags, src, libs)  cc -I$(BUILDINCDIR) -o target src
 
Index: programs/Xserver/GL/mesa/src/X/xf86glx.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/GL/mesa/src/X/xf86glx.c,v
retrieving revision 1.21
diff -u -p -r1.21 xf86glx.c
--- programs/Xserver/GL/mesa/src/X/xf86glx.c	28 Oct 2003 22:50:18 -0000	1.21
+++ programs/Xserver/GL/mesa/src/X/xf86glx.c	8 Mar 2004 21:04:25 -0000
@@ -96,7 +96,7 @@ __GLXextensionInfo __glDDXExtensionInfo 
     __MESA_setVisualConfigs
 };
 
-static __MESA_screen  MESAScreens[MAXSCREENS];
+static __MESA_screen  *MESAScreens;
 
 static int                 numConfigs     = 0;
 static __GLXvisualConfig  *visualConfigs  = NULL;
@@ -268,6 +268,8 @@ static Bool init_visuals(int *nvisualp, 
     else
         numNewConfigs = NUM_FALLBACK_CONFIGS;
 
+    MAXSCREENSALLOC_RETURN(MESAScreens, FALSE);
+
     /* Alloc space for the list of new GLX visuals */
     pNewVisualConfigs = (__GLXvisualConfig *)
                      __glXMalloc(numNewConfigs * sizeof(__GLXvisualConfig));
@@ -628,6 +630,8 @@ extern void __MESA_resetExtension(void)
 
     XMesaReset();
 
+    MAXSCREENSALLOC_FATAL(MESAScreens);
+    
     for (i = 0; i < screenInfo.numScreens; i++) {
 	for (j = 0; j < MESAScreens[i].num_vis; j++) {
 	  if (MESAScreens[i].xm_vis[j]) {
Index: programs/Xserver/Xext/appgroup.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/Xext/appgroup.c,v
retrieving revision 1.11
diff -u -p -r1.11 appgroup.c
--- programs/Xserver/Xext/appgroup.c	28 Oct 2003 23:08:43 -0000	1.11
+++ programs/Xserver/Xext/appgroup.c	8 Mar 2004 21:04:25 -0000
@@ -328,12 +328,15 @@ void CreateConnectionInfo(
     AppGroupPtr pAppGrp)
 {
     xWindowRoot* rootp;
-    xWindowRoot* roots[MAXSCREENS];
-    unsigned int rootlens[MAXSCREENS];
+    xWindowRoot* *roots = NULL;
+    unsigned int *rootlens = NULL;
     xDepth* depth;
     int olen;
     int snum, i;
 
+    MAXSCREENSALLOC_FATAL(roots);
+    MAXSCREENSALLOC_FATAL(rootlens);
+    
     rootp = (xWindowRoot*) (ConnectionInfo + connBlockScreenStart);
     for (snum = 0; snum < screenInfo.numScreens; snum++) {
 
@@ -361,7 +364,7 @@ void CreateConnectionInfo(
 	olen += rootlens[i];
     pAppGrp->ConnectionInfo = (char*) xalloc (olen);
     if (!pAppGrp->ConnectionInfo)
-	return;
+	goto done;
     memmove (pAppGrp->ConnectionInfo, ConnectionInfo, connBlockScreenStart);
     ((xConnSetup*) (pAppGrp->ConnectionInfo))->numRoots = 
 	1 + screenInfo.numScreens - screenInfo.numVideoScreens;
@@ -382,6 +385,10 @@ void CreateConnectionInfo(
     }
     pAppGrp->connSetupPrefix = connSetupPrefix;
     pAppGrp->connSetupPrefix.length = olen >> 2;
+
+  done:
+    MAXSCREENSFREE(roots);
+    MAXSCREENSFREE(rootlens);
 }
 
 static 
Index: programs/Xserver/Xext/mbufbf.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/Xext/mbufbf.c,v
retrieving revision 3.6
diff -u -p -r3.6 mbufbf.c
--- programs/Xserver/Xext/mbufbf.c	10 Nov 2003 18:21:42 -0000	3.6
+++ programs/Xserver/Xext/mbufbf.c	8 Mar 2004 21:04:26 -0000
@@ -139,12 +139,12 @@ typedef WindowPtr BufferPtr;
  * Call RegisterHdwrBuffer for every screen that has doublebuffer hardware. 
  */
 
-static int		bufNumInfo[MAXSCREENS];
-static xMbufBufferInfo	*bufInfo[MAXSCREENS];
-static DevUnion		*bufFrameBuffer[MAXSCREENS];
-static DevUnion		bufselectPlane[MAXSCREENS];
-static void		(* bufCopyBufferBitsFunc[MAXSCREENS])();
-static void		(* bufDrawSelectPlaneFunc[MAXSCREENS])();
+static int		*bufNumInfo;
+static xMbufBufferInfo	**bufInfo;
+static DevUnion		**bufFrameBuffer;
+static DevUnion		*bufselectPlane;
+static void		(** bufCopyBufferBitsFunc)();
+static void		(** bufDrawSelectPlaneFunc)();
 
 static Bool bufMultibufferInit();
 
@@ -160,6 +160,13 @@ RegisterDoubleBufferHardware(pScreen, nI
     void		(* CopyBufferBitsFunc)();
     void		(* DrawSelectPlaneFunc)();
 {
+    MAXSCREENSALLOC_FATAL(bufNumInfo);
+    MAXSCREENSALLOC_FATAL(bufInfo);
+    MAXSCREENSALLOC_FATAL(bufFrameBuffer);
+    MAXSCREENSALLOC_FATAL(bufselectPlane);
+    MAXSCREENSALLOC_FATAL(bufCopyBufferBitsFunc);
+    MAXSCREENSALLOC_FATAL(bufDrawSelectPlaneFunc);
+        
     bufNumInfo[pScreen->myNum]     = nInfo;
     bufInfo[pScreen->myNum]        = pInfo;
     bufFrameBuffer[pScreen->myNum] = frameBuffer;
Index: programs/Xserver/Xext/panoramiX.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/Xext/panoramiX.c,v
retrieving revision 3.38
diff -u -p -r3.38 panoramiX.c
--- programs/Xserver/Xext/panoramiX.c	10 Nov 2003 18:21:43 -0000	3.38
+++ programs/Xserver/Xext/panoramiX.c	8 Mar 2004 21:04:27 -0000
@@ -113,7 +113,7 @@ typedef struct {
   CloseScreenProcPtr	CloseScreen;
 } PanoramiXScreenRec, *PanoramiXScreenPtr;
 
-RegionRec XineramaScreenRegions[MAXSCREENS];
+RegionRec *XineramaScreenRegions;
 
 static void XineramaValidateGC(GCPtr, unsigned long, DrawablePtr);
 static void XineramaChangeGC(GCPtr, unsigned long);
@@ -323,6 +323,8 @@ XineramaDestroyClip(GCPtr pGC)
 int
 XineramaDeleteResource(pointer data, XID id)
 {
+    PanoramiXRes *res = (PanoramiXRes *)data;
+    MAXSCREENSFREE(res->info);
     xfree(data);
     return 1;
 }
@@ -434,6 +436,7 @@ void PanoramiXExtensionInit(int argc, ch
     
     if (noPanoramiXExtension) 
 	return;
+    MAXSCREENSALLOC_FATAL(XineramaScreenRegions);
 
     GlobalScrInfo = &screenInfo;		/* For debug visibility */
     PanoramiXNumScreens = screenInfo.numScreens;
@@ -739,8 +742,7 @@ void PanoramiXConsolidate(void)
     PanoramiXRes *root, *defmap, *saver;
     Bool        foundDepth, missingDepth;
 
-    if(!PanoramiXVisualTable)
-	PanoramiXVisualTable = xcalloc(256 * MAXSCREENS, sizeof(XID));
+    MAXSCREENSCALLOC_FATAL(PanoramiXVisualTable, 256);
 
     pScreen = screenInfo.screens[0];
     pVisual = pScreen->visuals; 
@@ -848,11 +850,16 @@ void PanoramiXConsolidate(void)
 
     root = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes));
     root->type = XRT_WINDOW;
+    root->info = NULL; /* NOTE above alloc unchecked */
+    MAXSCREENSALLOC_FATAL(root->info);
     defmap = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes));
     defmap->type = XRT_COLORMAP;
+    defmap->info = NULL; /* NOTE above alloc unchecked */
+    MAXSCREENSALLOC_FATAL(defmap->info);
     saver = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes));
     saver->type = XRT_WINDOW;
-
+    saver->info = NULL; /* NOTE above alloc unchecked */
+    MAXSCREENSALLOC_FATAL(saver->info);
 
     for (i =  0; i < PanoramiXNumScreens; i++) {
 	root->info[i].id = WindowTable[i]->drawable.id;
Index: programs/Xserver/Xext/panoramiX.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/Xext/panoramiX.h,v
retrieving revision 1.6
diff -u -p -r1.6 panoramiX.h
--- programs/Xserver/Xext/panoramiX.h	23 Mar 2003 04:56:02 -0000	1.6
+++ programs/Xserver/Xext/panoramiX.h	8 Mar 2004 21:04:27 -0000
@@ -46,7 +46,7 @@ typedef struct _PanoramiXInfo {
 } PanoramiXInfo;
 
 typedef struct {
-    PanoramiXInfo info[MAXSCREENS];
+    PanoramiXInfo *info;
     RESTYPE type;
     union {
 	struct {
Index: programs/Xserver/Xext/panoramiXprocs.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/Xext/panoramiXprocs.c,v
retrieving revision 3.37
diff -u -p -r3.37 panoramiXprocs.c
--- programs/Xserver/Xext/panoramiXprocs.c	10 Nov 2003 18:21:43 -0000	3.37
+++ programs/Xserver/Xext/panoramiXprocs.c	8 Mar 2004 21:04:29 -0000
@@ -130,6 +130,12 @@ int PanoramiXCreateWindow(ClientPtr clie
         return BadAlloc;
 
     newWin->type = XRT_WINDOW;
+    newWin->info = NULL;
+    MAXSCREENSALLOC(newWin->info);
+    if (!newWin->info) {
+        xfree(newWin);
+        return BadAlloc;
+    }
     newWin->u.win.visibility = VisibilityNotViewable;
     newWin->u.win.class = stuff->class;
     newWin->u.win.root = FALSE;
@@ -165,9 +171,11 @@ int PanoramiXCreateWindow(ClientPtr clie
 
     if (result == Success)
         AddResource(newWin->info[0].id, XRT_WINDOW, newWin);
-    else 
+    else {
+        MAXSCREENSFREE(newWin->info);
         xfree(newWin);
-
+    }
+    
     return (result);
 }
 
@@ -660,6 +668,12 @@ int PanoramiXCreatePixmap(ClientPtr clie
 	return BadAlloc;
 
     newPix->type = XRT_PIXMAP;
+    newPix->info = NULL;
+    MAXSCREENSALLOC(newPix->info);
+    if (!newPix->info) {
+        xfree(newPix);
+        return BadAlloc;
+    }
     newPix->u.pix.shared = FALSE;
     newPix->info[0].id = stuff->pid;
     for(j = 1; j < PanoramiXNumScreens; j++)
@@ -674,8 +688,10 @@ int PanoramiXCreatePixmap(ClientPtr clie
 
     if (result == Success)
 	AddResource(newPix->info[0].id, XRT_PIXMAP, newPix);
-    else 
-	xfree(newPix);
+    else {
+        MAXSCREENSFREE(newPix->info);
+        xfree(newPix);
+    }
 
     return (result);
 }
@@ -760,6 +776,12 @@ int PanoramiXCreateGC(ClientPtr client)
         return BadAlloc;
 
     newGC->type = XRT_GC;
+    newGC->info = NULL;
+    MAXSCREENSALLOC(newGC->info);
+    if (!newGC->info) {
+        xfree(newGC);
+        return BadAlloc;
+    }
     newGC->info[0].id = stuff->gc;
     for(j = 1; j < PanoramiXNumScreens; j++)
         newGC->info[j].id = FakeClientID(client->index);
@@ -779,8 +801,10 @@ int PanoramiXCreateGC(ClientPtr client)
 
     if (result == Success)
         AddResource(newGC->info[0].id, XRT_GC, newGC);
-    else 
+    else {
+        MAXSCREENSFREE(newGC->info);
         xfree(newGC);
+    }
 
     return (result);
 }
@@ -1022,18 +1046,22 @@ int PanoramiXCopyArea(ClientPtr client)
     srcx = stuff->srcX; srcy = stuff->srcY;
     dstx = stuff->dstX; dsty = stuff->dstY;
     if((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) {
-	DrawablePtr drawables[MAXSCREENS];
+	DrawablePtr *drawables = NULL;
 	DrawablePtr pDst;
 	GCPtr pGC;
         char *data;
 	int pitch;
 
+        MAXSCREENSALLOC_RETURN(drawables, BadAlloc);
+
 	FOR_NSCREENS(j)
 	    VERIFY_DRAWABLE(drawables[j], src->info[j].id, client);
 
 	pitch = PixmapBytePad(stuff->width, drawables[0]->depth); 
-	if(!(data = xcalloc(1, stuff->height * pitch)))
+	if(!(data = xcalloc(1, stuff->height * pitch))) {
+            MAXSCREENSFREE(drawables);
 	    return BadAlloc;
+        }
 
 	XineramaGetImageData(drawables, srcx, srcy, 
 		stuff->width, stuff->height, ZPixmap, ~0, data, pitch, 
@@ -1045,6 +1073,7 @@ int PanoramiXCopyArea(ClientPtr client)
 
 	    if(drawables[0]->depth != pDst->depth) {
 		client->errorValue = stuff->dstDrawable;
+                MAXSCREENSFREE(drawables);
 		xfree(data);
 		return (BadMatch);
 	    }
@@ -1056,13 +1085,16 @@ int PanoramiXCopyArea(ClientPtr client)
 	    if(dstShared) break;
 	}
 
+        MAXSCREENSFREE(drawables);
 	xfree(data);
 
 	result = Success;
     } else {
 	DrawablePtr pDst = NULL, pSrc = NULL;
 	GCPtr pGC = NULL;
-	RegionPtr pRgn[MAXSCREENS];
+	RegionPtr *pRgn = NULL;
+
+        MAXSCREENSALLOC_RETURN(pRgn, BadAlloc);
 
 	FOR_NSCREENS_BACKWARD(j) {
 	    stuff->dstDrawable = dst->info[j].id;
@@ -1084,6 +1116,7 @@ int PanoramiXCopyArea(ClientPtr client)
 		if ((pDst->pScreen != pSrc->pScreen) || 
 		    (pDst->depth != pSrc->depth)) {
 			client->errorValue = stuff->dstDrawable;
+                        MAXSCREENSFREE(pRgn);
 			return (BadMatch);
    		}
  	    } else
@@ -1121,7 +1154,8 @@ int PanoramiXCopyArea(ClientPtr client)
 		client, &totalReg, stuff->dstDrawable, X_CopyArea, 0);
 	    REGION_UNINIT(pScreen, &totalReg);
 	}
-	
+        MAXSCREENSFREE(pRgn);
+
 	result = client->noClientException;
     }
 
@@ -1138,29 +1172,39 @@ int PanoramiXCopyPlane(ClientPtr client)
     Bool		srcShared, dstShared;
     DrawablePtr 	psrcDraw, pdstDraw = NULL;
     GCPtr 		pGC = NULL;
-    RegionPtr 		pRgn[MAXSCREENS];
+    RegionPtr 		*pRgn = NULL;
     REQUEST(xCopyPlaneReq);
 
     REQUEST_SIZE_MATCH(xCopyPlaneReq);
 
+    MAXSCREENSALLOC_RETURN(pRgn, BadAlloc);
+
     if(!(src = (PanoramiXRes *)SecurityLookupIDByClass(
-		client, stuff->srcDrawable, XRC_DRAWABLE, SecurityReadAccess)))
-	return BadDrawable;    
+             client, stuff->srcDrawable, XRC_DRAWABLE, SecurityReadAccess))) {
+        MAXSCREENSFREE(pRgn);
+	return BadDrawable;
+    }
 
     srcShared = IS_SHARED_PIXMAP(src);
 
     if(!(dst = (PanoramiXRes *)SecurityLookupIDByClass(
-		client, stuff->dstDrawable, XRC_DRAWABLE, SecurityWriteAccess)))
+             client, stuff->dstDrawable, XRC_DRAWABLE, SecurityWriteAccess))) {
+        MAXSCREENSFREE(pRgn);
 	return BadDrawable;
+    }
 
     dstShared = IS_SHARED_PIXMAP(dst);
 
-    if(dstShared && srcShared)
+    if(dstShared && srcShared) {
+        MAXSCREENSFREE(pRgn);
 	return (* SavedProcVector[X_CopyPlane])(client);
+    }
 
     if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
-		client, stuff->gc, XRT_GC, SecurityReadAccess)))
+             client, stuff->gc, XRT_GC, SecurityReadAccess))) {
+        MAXSCREENSFREE(pRgn);
 	return BadGC;
+    }
 
     if((dst->type == XRT_WINDOW) && dst->u.win.root)
 	dstIsRoot = TRUE;
@@ -1189,6 +1233,7 @@ int PanoramiXCopyPlane(ClientPtr client)
                                  SecurityReadAccess);
             if (pdstDraw->pScreen != psrcDraw->pScreen) {
 		client->errorValue = stuff->dstDrawable;
+                MAXSCREENSFREE(pRgn);
 		return (BadMatch);
 	    }
 	} else
@@ -1197,7 +1242,8 @@ int PanoramiXCopyPlane(ClientPtr client)
 	if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
 		(stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
 	    client->errorValue = stuff->bitPlane;
-	    return(BadValue);
+            MAXSCREENSFREE(pRgn);
+ 	    return(BadValue);
 	}
 
 	pRgn[j] = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, 
@@ -1229,6 +1275,7 @@ int PanoramiXCopyPlane(ClientPtr client)
 	REGION_UNINIT(pScreen, &totalReg);
     }
 
+    MAXSCREENSFREE(pRgn);
     return (client->noClientException);
 }
 
@@ -1746,7 +1793,7 @@ int PanoramiXPutImage(ClientPtr client)
 
 int PanoramiXGetImage(ClientPtr client)
 {
-    DrawablePtr 	drawables[MAXSCREENS];
+    DrawablePtr 	*drawables = NULL;
     DrawablePtr 	pDraw;
     PanoramiXRes	*draw;
     xGetImageReply	xgi;
@@ -1806,6 +1853,7 @@ int PanoramiXGetImage(ClientPtr client)
 	    return(BadMatch);
     }
 
+    MAXSCREENSALLOC_RETURN(drawables, BadAlloc);
     drawables[0] = pDraw;
     for(i = 1; i < PanoramiXNumScreens; i++)
 	VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
@@ -1840,8 +1888,10 @@ int PanoramiXGetImage(ClientPtr client)
 	    linesPerBuf = h;
     }
     length = linesPerBuf * widthBytesLine;
-    if(!(pBuf = xalloc(length)))
+    if(!(pBuf = xalloc(length))) {
+        MAXSCREENSFREE(drawables);
 	return (BadAlloc);
+    }
 
     WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
 
@@ -1886,6 +1936,7 @@ int PanoramiXGetImage(ClientPtr client)
             }
 	}
     }
+    MAXSCREENSFREE(drawables);
     xfree(pBuf);
     return (client->noClientException);
 }
@@ -2070,6 +2121,12 @@ int PanoramiXCreateColormap(ClientPtr cl
 
     if(!(newCmap = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
         return BadAlloc;
+    newCmap->info = NULL;
+    MAXSCREENSALLOC(newCmap->info);
+    if (!newCmap->info) {
+        xfree(newCmap);
+        return BadAlloc;
+    }
 
     newCmap->type = XRT_COLORMAP;
     newCmap->info[0].id = stuff->mid;
@@ -2087,8 +2144,10 @@ int PanoramiXCreateColormap(ClientPtr cl
  
     if (result == Success)
         AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
-    else 
+    else {
+        MAXSCREENSFREE(newCmap->info);
         xfree(newCmap);
+    }
 
     return (result);
 }
@@ -2139,6 +2198,12 @@ PanoramiXCopyColormapAndFree(ClientPtr c
 
     if(!(newCmap = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
         return BadAlloc;
+    newCmap->info = NULL;
+    MAXSCREENSALLOC(newCmap->info);
+    if (!newCmap->info) {
+        xfree(newCmap);
+        return BadAlloc;
+    }
 
     newCmap->type = XRT_COLORMAP;
     newCmap->info[0].id = stuff->mid;
@@ -2154,8 +2219,10 @@ PanoramiXCopyColormapAndFree(ClientPtr c
 
     if (result == Success)
         AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
-    else 
+    else {
+        MAXSCREENSFREE(newCmap->info);
         xfree(newCmap);
+    }
 
     return (result);
 }
Index: programs/Xserver/Xext/panoramiXsrv.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/Xext/panoramiXsrv.h,v
retrieving revision 1.9
diff -u -p -r1.9 panoramiXsrv.h
--- programs/Xserver/Xext/panoramiXsrv.h	11 Aug 2001 21:00:06 -0000	1.9
+++ programs/Xserver/Xext/panoramiXsrv.h	8 Mar 2004 21:04:29 -0000
@@ -20,7 +20,7 @@ extern WindowPtr PanoramiXChangeWindow(i
 extern Bool XineramaRegisterConnectionBlockCallback(void (*func)(void));
 extern int XineramaDeleteResource(pointer, XID);
 
-extern RegionRec XineramaScreenRegions[MAXSCREENS];
+extern RegionRec *XineramaScreenRegions;
 
 extern unsigned long XRC_DRAWABLE;
 extern unsigned long XRT_WINDOW;
Index: programs/Xserver/Xext/shm.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/Xext/shm.c,v
retrieving revision 3.42
diff -u -p -r3.42 shm.c
--- programs/Xserver/Xext/shm.c	18 Dec 2003 10:15:24 -0000	3.42
+++ programs/Xserver/Xext/shm.c	8 Mar 2004 21:04:30 -0000
@@ -117,9 +117,9 @@ RESTYPE ShmSegType;
 static ShmDescPtr Shmsegs;
 static Bool sharedPixmaps;
 static int pixmapFormat;
-static int shmPixFormat[MAXSCREENS];
-static ShmFuncsPtr shmFuncs[MAXSCREENS];
-static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+static int *shmPixFormat;
+static ShmFuncsPtr *shmFuncs;
+static DestroyPixmapProcPtr *destroyPixmap;
 #ifdef PIXPRIV
 static int  shmPixmapPrivate;
 #endif
@@ -212,6 +212,10 @@ ShmExtensionInit(INITARGS)
     }
 #endif
 
+    MAXSCREENSALLOC_FATAL(shmPixFormat);
+    MAXSCREENSALLOC_FATAL(shmFuncs);
+    MAXSCREENSALLOC_FATAL(destroyPixmap);
+
     sharedPixmaps = xFalse;
     pixmapFormat = 0;
     {
@@ -269,6 +273,7 @@ ExtensionEntry	*extEntry;
 {
     int i;
 
+    MAXSCREEN_ASSERT_INIT();
     for (i = 0; i < MAXSCREENS; i++)
     {
 	shmFuncs[i] = (ShmFuncsPtr)NULL;
@@ -331,6 +336,13 @@ void
 ShmRegisterFbFuncs(pScreen)
     ScreenPtr pScreen;
 {
+                                /* Initialize here because miScreenInit
+                                 * calls ShmRegisterFbFuncs before
+                                 * ShmExtensionInit. */
+    MAXSCREENSALLOC_FATAL(shmPixFormat);
+    MAXSCREENSALLOC_FATAL(shmFuncs);
+    MAXSCREENSALLOC_FATAL(destroyPixmap);
+
     shmFuncs[pScreen->myNum] = &fbFuncs;
 }
 
@@ -603,7 +615,7 @@ static int 
 ProcPanoramiXShmGetImage(ClientPtr client)
 {
     PanoramiXRes	*draw;
-    DrawablePtr 	drawables[MAXSCREENS];
+    DrawablePtr 	*drawables = NULL;
     DrawablePtr 	pDraw;
     xShmGetImageReply	xgi;
     ShmDescPtr		shmdesc;
@@ -660,6 +672,7 @@ ProcPanoramiXShmGetImage(ClientPtr clien
 	    return(BadMatch);
     }
 
+    MAXSCREENSALLOC_RETURN(drawables, BadAlloc);
     drawables[0] = pDraw;
     for(i = 1; i < PanoramiXNumScreens; i++)
 	VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
@@ -710,6 +723,7 @@ ProcPanoramiXShmGetImage(ClientPtr clien
     }
     WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
 
+    MAXSCREENSFREE(drawables);
     return(client->noClientException);
 }
 
@@ -754,6 +768,12 @@ CreatePmap:
 
     if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
 	return BadAlloc;
+    newPix->info = NULL;
+    MAXSCREENSALLOC(newPix->info);
+    if (!newPix->info) {
+        xfree(newPix);
+        return BadAlloc;
+    }
 
     newPix->type = XRT_PIXMAP;
     newPix->u.pix.shared = TRUE;
@@ -793,6 +813,7 @@ CreatePmap:
 	    (*pScreen->DestroyPixmap)(pMap);
 	    FreeResource(newPix->info[j].id, RT_NONE);
 	}
+        MAXSCREENSFREE(newPix->info);
 	xfree(newPix);
     } else 
 	AddResource(stuff->pid, XRT_PIXMAP, newPix);
Index: programs/Xserver/Xext/xf86dga2.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/Xext/xf86dga2.c,v
retrieving revision 1.18
diff -u -p -r1.18 xf86dga2.c
--- programs/Xserver/Xext/xf86dga2.c	16 Jul 2003 01:38:30 -0000	1.18
+++ programs/Xserver/Xext/xf86dga2.c	8 Mar 2004 21:04:30 -0000
@@ -57,7 +57,7 @@ static void XDGAResetProc(ExtensionEntry
 
 static void DGAClientStateChange (CallbackListPtr*, pointer, pointer);
 
-static ClientPtr DGAClients[MAXSCREENS];
+static ClientPtr *DGAClients;
 
 unsigned char DGAReqCode = 0;
 int DGAErrorBase;
@@ -89,6 +89,7 @@ XFree86DGAExtensionInit(INITARGS)
 				StandardMinorOpcode))) {
 	int i;
 
+        MAXSCREENSALLOC_FATAL(DGAClients);
 	for(i = 0; i < MAXSCREENS; i++)
 	     DGAClients[i] = NULL;
 
Index: programs/Xserver/Xext/xprint.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/Xext/xprint.c,v
retrieving revision 1.15
diff -u -p -r1.15 xprint.c
--- programs/Xserver/Xext/xprint.c	28 Oct 2003 23:08:44 -0000	1.15
+++ programs/Xserver/Xext/xprint.c	8 Mar 2004 21:04:32 -0000
@@ -227,7 +227,7 @@ typedef struct _XpStDocRec {
 #define GET_DOC_DATA_STARTED (1 << 4)
 #define JOB_GET_DATA (1 << 5)
     
-static XpScreenPtr XpScreens[MAXSCREENS];
+static XpScreenPtr *XpScreens;
 static unsigned char XpReqCode;
 static int XpEventBase;
 static int XpErrorBase;
@@ -317,6 +317,7 @@ XpExtensionInit(INITARGS)
 	XpGeneration = serverGeneration;
     }
 
+    MAXSCREENSALLOC_FATAL(XpScreens);
     for(i = 0; i < MAXSCREENS; i++)
     {
 	/*
@@ -694,6 +695,7 @@ ProcXpQueryScreens(ClientPtr client)
     rep = (xPrintQueryScreensReply *)xalloc(sz_xPrintQueryScreensReply);
     pWinId = (WINDOW *)(rep + 1);
 
+    MAXSCREEN_ASSERT_INIT();
     for(i = 0, numPrintScreens = 0, totalSize = sz_xPrintQueryScreensReply; 
 	i < MAXSCREENS; i++)
     {
Index: programs/Xserver/Xext/xvdisp.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/Xext/xvdisp.c,v
retrieving revision 1.29
diff -u -p -r1.29 xvdisp.c
--- programs/Xserver/Xext/xvdisp.c	2 Oct 2003 13:29:39 -0000	1.29
+++ programs/Xserver/Xext/xvdisp.c	8 Mar 2004 21:04:34 -0000
@@ -2111,12 +2111,14 @@ void XineramifyXv(void)
    XvScreenPtr xvsp;
    Bool isOverlay, hasOverlay;
    PanoramiXRes *port;
-   XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+   XvAdaptorPtr *MatchingAdaptors = NULL;
    int i, j, k, l;
 
    XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
 
    if(!xvsp0) return;
+
+   MAXSCREENSALLOC_FATAL(MatchingAdaptors);
    
    for(i = 0; i < xvsp0->nAdaptors; i++) {
       refAdapt = xvsp0->pAdaptors + i;
@@ -2196,6 +2198,8 @@ void XineramifyXv(void)
       for(j = 0; j < refAdapt->nPorts; j++) {
          if(!(port = xalloc(sizeof(PanoramiXRes))))
 	    break;
+         port->info = NULL;
+         MAXSCREENSALLOC_FATAL(port->info);
 	 port->info[0].id = MatchingAdaptors[0]->base_id + j;
 	 AddResource(port->info[0].id, XvXRTPort, port);
 
@@ -2207,6 +2211,8 @@ void XineramifyXv(void)
 	 } 
       }
    }
+
+   MAXSCREENSFREE(MatchingAdaptors);
 }
 
 #endif
Index: programs/Xserver/dbe/dbe.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/dbe/dbe.c,v
retrieving revision 3.11
diff -u -p -r3.11 dbe.c
--- programs/Xserver/dbe/dbe.c	28 Oct 2001 03:33:04 -0000	3.11
+++ programs/Xserver/dbe/dbe.c	8 Mar 2004 21:04:36 -0000
@@ -53,7 +53,7 @@
 /* GLOBALS */
 
 /* Per-screen initialization functions [init'ed by DbeRegisterFunction()] */
-static Bool	(* DbeInitFunct[MAXSCREENS])();	/* pScreen, pDbeScreenPriv */
+static Bool	(** DbeInitFunct)();	/* pScreen, pDbeScreenPriv */
 
 /* These are static globals copied to DBE's screen private for use by DDX */
 static int	dbeScreenPrivIndex;
@@ -130,6 +130,7 @@ DbeRegisterFunction(pScreen, funct)
      */
     if (firstRegistrationPass)
     {
+        MAXSCREENSALLOC_FATAL(DbeInitFunct);
         for (i = 0; i < MAXSCREENS; i++)
         {
             DbeInitFunct[i] = NULL;
@@ -1824,6 +1825,8 @@ DbeExtensionInit()
     if(!noPanoramiXExtension) return;
 #endif
 
+    MAXSCREENSALLOC_FATAL(DbeInitFunct);
+
     /* Allocate private pointers in windows and screens. */
 
     if ((dbeScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
Index: programs/Xserver/dix/cursor.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/dix/cursor.c,v
retrieving revision 3.9
diff -u -p -r3.9 cursor.c
--- programs/Xserver/dix/cursor.c	17 Nov 2003 22:20:33 -0000	3.9
+++ programs/Xserver/dix/cursor.c	8 Mar 2004 21:04:36 -0000
@@ -73,6 +73,7 @@ FreeCursorBits(CursorBitsPtr bits)
 {
     if (--bits->refcnt > 0)
 	return;
+    MAXSCREENSFREE(bits->devPriv);
     xfree(bits->source);
     xfree(bits->mask);
 #ifdef ARGB_CURSOR
@@ -169,12 +170,22 @@ AllocCursorARGB(psrcbits, pmaskbits, arg
 
     pCurs = (CursorPtr)xalloc(sizeof(CursorRec) + sizeof(CursorBits));
     if (!pCurs)
-    {
-	xfree(psrcbits);
-	xfree(pmaskbits);
-	return (CursorPtr)NULL;
-    }
+        goto mfail_pcurs;
+    
+    pCurs->devPriv = NULL;
+    MAXSCREENSALLOC(pCurs->devPriv);
+    if (!pCurs->devPriv)
+        goto mfail_pcurs_devpriv;
+
     bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec));
+    if (!bits)
+        goto mfail_bits;
+
+    bits->devPriv = NULL;
+    MAXSCREENSALLOC(bits->devPriv);
+    if (!bits->devPriv)
+        goto mfail_bits_devpriv;
+
     bits->source = psrcbits;
     bits->mask = pmaskbits;
 #ifdef ARGB_CURSOR
@@ -211,12 +222,31 @@ AllocCursorARGB(psrcbits, pmaskbits, arg
 		pscr = screenInfo.screens[nscr];
 		( *pscr->UnrealizeCursor)( pscr, pCurs);
 	    }
+            /* JFIXME: Note bits->refcnt should be == -1 here, so bits itself
+             * will leak */
 	    FreeCursorBits(bits);
+            ErrorF("***** BITS REFCNT = %d\n", bits->refcnt);
+
+            /* do it by hand as the above takes care of bits, which also does
+             * psrcbits/pmaskbits */
+            MAXSCREENSFREE(pCurs->devPriv);
 	    xfree(pCurs);
 	    return (CursorPtr)NULL;
 	}
     }
     return pCurs;
+
+ mfail_bits_devpriv:
+    xfree(bits);
+ mfail_bits:
+    MAXSCREENSFREE(pCurs->devPriv);
+ mfail_pcurs_devpriv:
+    xfree(pCurs);
+ mfail_pcurs:
+    
+    xfree(psrcbits);
+    xfree(pmaskbits);
+    return NULL;
 }
 
 CursorPtr 
@@ -287,6 +317,12 @@ AllocGlyphCursor(source, sourceChar, mas
 	pCurs = (CursorPtr)xalloc(sizeof(CursorRec));
 	if (!pCurs)
 	    return BadAlloc;
+        pCurs->devPriv = NULL;
+        MAXSCREENSALLOC(pCurs->devPriv);
+        if (!pCurs->devPriv) {
+            xfree(pCurs);
+            return BadAlloc;
+        }
 	bits = pShare->bits;
 	bits->refcnt++;
     }
@@ -347,6 +383,27 @@ AllocGlyphCursor(source, sourceChar, mas
 	    xfree(srcbits);
 	    return BadAlloc;
 	}
+        pCurs->devPriv = NULL;
+        MAXSCREENSALLOC(pCurs->devPriv);
+        if (!pCurs->devPriv) {
+            if (sourcefont == maskfont)
+                xfree(bits);
+	    xfree(pCurs);
+	    xfree(mskbits);
+	    xfree(srcbits);
+	    return BadAlloc;
+        }
+        bits->devPriv = NULL;
+        MAXSCREENSALLOC(bits->devPriv);
+        if (!bits->devPriv) {
+            MAXSCREENSFREE(pCurs->devPriv);
+            if (sourcefont == maskfont)
+                xfree(bits);
+	    xfree(pCurs);
+	    xfree(mskbits);
+	    xfree(srcbits);
+	    return BadAlloc;
+        }
 	bits->source = srcbits;
 	bits->mask = mskbits;
 #ifdef ARGB_CURSOR
@@ -364,6 +421,8 @@ AllocGlyphCursor(source, sourceChar, mas
 	    pShare = (GlyphSharePtr)xalloc(sizeof(GlyphShare));
 	    if (!pShare)
 	    {
+                MAXSCREENSFREE(pCurs->devPriv);
+                xfree(pCurs);
 		FreeCursorBits(bits);
 		return BadAlloc;
 	    }
Index: programs/Xserver/dix/dispatch.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/dix/dispatch.c,v
retrieving revision 3.33
diff -u -p -r3.33 dispatch.c
--- programs/Xserver/dix/dispatch.c	17 Nov 2003 22:20:33 -0000	3.33
+++ programs/Xserver/dix/dispatch.c	8 Mar 2004 21:04:38 -0000
@@ -3648,6 +3648,7 @@ CloseDownClient(client)
 #ifdef SMART_SCHEDULE
 	SmartLastClient = NullClient;
 #endif
+        MAXSCREENSFREE(client->screenPrivate);
 	xfree(client);
 
 	while (!clients[currentMaxClients-1])
@@ -3813,10 +3814,17 @@ NextAvailableClient(ospriv)
     clients[i] = client = (ClientPtr)xalloc(totalClientSize);
     if (!client)
 	return (ClientPtr)NULL;
+    clients[i]->screenPrivate = NULL;
+    MAXSCREENSALLOC(clients[i]->screenPrivate);
+    if (!clients[i]->screenPrivate) {
+	xfree(client);
+        return (ClientPtr)NULL;
+    }
     InitClient(client, i, ospriv);
     InitClientPrivates(client);
     if (!InitClientResources(client))
     {
+        MAXSCREENSFREE(clients[i]->screenPrivate);
 	xfree(client);
 	return (ClientPtr)NULL;
     }
@@ -3825,6 +3833,7 @@ NextAvailableClient(ospriv)
     if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
     {
 	FreeClientResources(client);
+        MAXSCREENSFREE(clients[i]->screenPrivate);
 	xfree(client);
 	return (ClientPtr)NULL;
     }
Index: programs/Xserver/dix/events.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/dix/events.c,v
retrieving revision 3.52
diff -u -p -r3.52 events.c
--- programs/Xserver/dix/events.c	23 Jan 2004 07:23:34 -0000	3.52
+++ programs/Xserver/dix/events.c	8 Mar 2004 21:04:42 -0000
@@ -194,7 +194,7 @@ static  struct {
     ScreenPtr	screen;		/* all others are in Screen 0 coordinates */
     RegionRec   Reg1;	        /* Region 1 for confining motion */
     RegionRec   Reg2;		/* Region 2 for confining virtual motion */
-    WindowPtr   windows[MAXSCREENS];
+    WindowPtr   *windows;
     WindowPtr	confineWin;	/* confine window */ 
 #endif
 } sprite;			/* info about the cursor sprite */
@@ -3907,6 +3907,7 @@ InitEvents()
 {
     int i;
 
+    MAXSCREENSALLOC_FATAL(sprite.windows);
     sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
     inputInfo.numDevices = 0;
     inputInfo.devices = (DeviceIntPtr)NULL;
Index: programs/Xserver/dix/extension.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/dix/extension.c,v
retrieving revision 3.12
diff -u -p -r3.12 extension.c
--- programs/Xserver/dix/extension.c	19 Feb 2002 11:09:22 -0000	3.12
+++ programs/Xserver/dix/extension.c	8 Mar 2004 21:04:42 -0000
@@ -70,7 +70,7 @@ SOFTWARE.
 #define LAST_EVENT  128
 #define LAST_ERROR 255
 
-ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+ScreenProcEntry *AuxillaryScreenProcs;
 
 static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
 
@@ -291,6 +291,7 @@ CloseDownExtensions()
     extensions = (ExtensionEntry **)NULL;
     lastEvent = EXTENSION_EVENT_BASE;
     lastError = FirstExtensionError;
+    MAXSCREENSALLOC_FATAL(AuxillaryScreenProcs);
     for (i=0; i<MAXSCREENS; i++)
     {
 	register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
@@ -419,6 +420,7 @@ LookupProc(name, pGC)
 {
     register int i;
     register ScreenProcEntry *spentry;
+    MAXSCREENSALLOC_RETURN(AuxillaryScreenProcs, NULL);
     spentry  = &AuxillaryScreenProcs[pGC->pScreen->myNum];
     if (spentry->num)    
     {
@@ -449,6 +451,7 @@ RegisterScreenProc(name, pScreen, proc)
     char *newname;
     int i;
 
+    MAXSCREENSALLOC_RETURN(AuxillaryScreenProcs, FALSE);
     spentry = &AuxillaryScreenProcs[pScreen->myNum];
     /* first replace duplicates */
     if (spentry->num)
Index: programs/Xserver/dix/globals.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/dix/globals.c,v
retrieving revision 1.13
diff -u -p -r1.13 globals.c
--- programs/Xserver/dix/globals.c	3 Dec 2003 17:11:29 -0000	1.13
+++ programs/Xserver/dix/globals.c	8 Mar 2004 21:04:43 -0000
@@ -146,4 +146,4 @@ CARD32 TimeOutValue = DEFAULT_TIMEOUT * 
 int	argcGlobal;
 char	**argvGlobal;
 
-DDXPointRec dixScreenOrigins[MAXSCREENS];
+DDXPointRec *dixScreenOrigins;
Index: programs/Xserver/dix/main.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/dix/main.c,v
retrieving revision 3.44
diff -u -p -r3.44 main.c
--- programs/Xserver/dix/main.c	17 Nov 2003 22:20:34 -0000	3.44
+++ programs/Xserver/dix/main.c	8 Mar 2004 21:04:43 -0000
@@ -234,6 +234,45 @@ static int indexForScanlinePad[ 65 ] = {
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 #endif
 
+int        MAXSCREENS;
+static int MAXSCREENS_USED;
+
+void *MaxScreensAlloc(unsigned long size)
+{
+    void *buf;
+    
+    if (!MAXSCREENS)
+        FatalError("MaxScreensAlloc called before SetMaxScreens");
+
+    MAXSCREENS_USED = 1;
+    buf = xalloc(size);
+    if (buf)
+        memset(buf, 0, size);
+    
+    return buf;
+}
+
+void MaxScreensFree(void *object)
+{
+    if (object) xfree(object);
+}
+
+void SetMaxScreens(int maxscreens)
+{
+    if (MAXSCREENS_USED)
+        FatalError("SetMaxScreens called after first use");
+    MAXSCREENS = maxscreens > 0 ? maxscreens : MAXSCREENSDEFAULT;
+}
+
+static void InitGlobals(void)
+{
+    if (!MAXSCREENS) SetMaxScreens(MAXSCREENSDEFAULT);
+    
+    MAXSCREENSALLOC_FATAL(dixScreenOrigins);
+    MAXSCREENSALLOC_FATAL(savedScreenInfo);
+    MAXSCREENSALLOC_FATAL(screenInfo.screens);
+}
+
 int
 main(int argc, char *argv[], char *envp[])
 {
@@ -278,6 +317,8 @@ main(int argc, char *argv[], char *envp[
     if (xauthfile) InitAuthorization (xauthfile);
     ProcessCommandLine(argc, argv);
 
+    InitGlobals();              /* Called after ProcessCommandLine */
+
     alwaysCheckForInput[0] = 0;
     alwaysCheckForInput[1] = 1;
     while(1)
@@ -309,6 +350,8 @@ main(int argc, char *argv[], char *envp[
 	    serverClient = (ClientPtr)xalloc(sizeof(ClientRec));
 	    if (!serverClient)
 		FatalError("couldn't create server client");
+            serverClient->screenPrivate = NULL;
+            MAXSCREENSALLOC_FATAL(serverClient->screenPrivate);
 	    InitClient(serverClient, 0, (pointer)NULL);
 	}
 	else
@@ -323,7 +366,7 @@ main(int argc, char *argv[], char *envp[
 	screenInfo.arraySize = MAXSCREENS;
 	screenInfo.numScreens = 0;
 	screenInfo.numVideoScreens = -1;
-	WindowTable = (WindowPtr *)xalloc(MAXSCREENS * sizeof(WindowPtr));
+        MAXSCREENSALLOC(WindowTable);
 	if (!WindowTable)
 	    FatalError("couldn't create root window table");
 
Index: programs/Xserver/dix/window.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/dix/window.c,v
retrieving revision 3.37
diff -u -p -r3.37 window.c
--- programs/Xserver/dix/window.c	17 Nov 2003 22:20:35 -0000	3.37
+++ programs/Xserver/dix/window.c	8 Mar 2004 21:04:46 -0000
@@ -115,7 +115,7 @@ static unsigned char _back_msb[4] = {0x1
 
 int screenIsSaved = SCREEN_SAVER_OFF;
 
-ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+ScreenSaverStuffRec *savedScreenInfo;
 
 #if 0
 extern void DeleteWindowFromAnyEvents();
Index: programs/Xserver/fb/fbcmap.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/fb/fbcmap.c,v
retrieving revision 1.6
diff -u -p -r1.6 fbcmap.c
--- programs/Xserver/fb/fbcmap.c	28 Oct 2001 03:33:08 -0000	1.6
+++ programs/Xserver/fb/fbcmap.c	8 Mar 2004 21:04:46 -0000
@@ -38,13 +38,14 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "fb.h"
 
 #ifndef XFree86Server
-ColormapPtr FbInstalledMaps[MAXSCREENS];
+ColormapPtr *FbInstalledMaps;
 
 int
 fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 {
     /* By the time we are processing requests, we can guarantee that there
      * is always a colormap installed */
+    MAXSCREENSALLOC_FATAL(FbInstalledMaps);
     *pmaps = FbInstalledMaps[pScreen->myNum]->mid;
     return (1);
 }
@@ -54,8 +55,10 @@ void
 fbInstallColormap(ColormapPtr pmap)
 {
     int index = pmap->pScreen->myNum;
-    ColormapPtr oldpmap = FbInstalledMaps[index];
+    ColormapPtr oldpmap;
 
+    MAXSCREENSALLOC_FATAL(FbInstalledMaps);
+    oldpmap = FbInstalledMaps[index];
     if(pmap != oldpmap)
     {
 	/* Uninstall pInstalledMap. No hardware changes required, just
@@ -72,8 +75,10 @@ void
 fbUninstallColormap(ColormapPtr pmap)
 {
     int index = pmap->pScreen->myNum;
-    ColormapPtr curpmap = FbInstalledMaps[index];
+    ColormapPtr curpmap;
 
+    MAXSCREENSALLOC_FATAL(FbInstalledMaps);
+    curpmap = FbInstalledMaps[index];
     if(pmap == curpmap)
     {
 	if (pmap->mid != pmap->pScreen->defColormap)
Index: programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c,v
retrieving revision 1.4
diff -u -p -r1.4 fullscreen.c
--- programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c	9 Dec 2003 04:41:27 -0000	1.4
+++ programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c	8 Mar 2004 21:04:47 -0000
@@ -53,7 +53,7 @@ typedef struct {
 static int                  fsScreenIndex;
 static CGDirectDisplayID   *quartzDisplayList = NULL;
 static int                  quartzNumScreens = 0;
-static FSScreenPtr          quartzScreens[MAXSCREENS];
+static FSScreenPtr         *quartzScreens;
 
 static int                  darwinCmapPrivateIndex = -1;
 static unsigned long        darwinCmapGeneration = 0;
@@ -201,6 +201,7 @@ static void FSCapture(void)
 
     if (quartzRootless) return;
 
+    MAXSCREENSALLOC_FATAL(quartzScreens);
     for (i = 0; i < quartzNumScreens; i++) {
         FSScreenPtr fsDisplayInfo = quartzScreens[i];
         CGDirectDisplayID cgID = fsDisplayInfo->displayID;
@@ -500,6 +501,13 @@ static Bool FSSetupScreen(
     FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
     CGDirectDisplayID cgID = fsDisplayInfo->displayID;
 
+    MAXSCREENSALLOC(quartzScreens);
+    if (!quartzScreens) {
+        ErrorF("Failed to initalize screens for screen %i.\n",
+               index);
+        return False;
+    }
+
     // Initialize shadow framebuffer support
     if (! shadowInit(pScreen, FSShadowUpdate, NULL)) {
         ErrorF("Failed to initalize shadow framebuffer for screen %i.\n",
Index: programs/Xserver/hw/kdrive/kxv.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/kdrive/kxv.c,v
retrieving revision 1.5
diff -u -p -r1.5 kxv.c
--- programs/Xserver/hw/kdrive/kxv.c	10 Nov 2003 18:21:48 -0000	1.5
+++ programs/Xserver/hw/kdrive/kxv.c	8 Mar 2004 21:04:48 -0000
@@ -1748,7 +1748,7 @@ typedef struct {
    int num;
 } OffscreenImageRec;
 
-static OffscreenImageRec OffscreenImages[MAXSCREENS];
+static OffscreenImageRec *OffscreenImages;
 static Bool offscreenInited = FALSE;
 
 Bool 
@@ -1758,7 +1758,7 @@ KdXVRegisterOffscreenImages(
     int num
 ){
     if(!offscreenInited) {
-	bzero(OffscreenImages, sizeof(OffscreenImages[MAXSCREENS]));
+        MAXSCREENSALLOC_RETURN(OffscreenImages, FALSE);
 	offscreenInited = TRUE;
     }
   
Index: programs/Xserver/hw/sun/sunInit.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/sun/sunInit.c,v
retrieving revision 3.13
diff -u -p -r3.13 sunInit.c
--- programs/Xserver/hw/sun/sunInit.c	17 Nov 2003 22:20:36 -0000	3.13
+++ programs/Xserver/hw/sun/sunInit.c	8 Mar 2004 21:04:49 -0000
@@ -234,26 +234,26 @@ static char *fallbackList[] = {
 static char *fallbackList[] = {
 #ifndef i386 /* { */
     CGTWO0DEV, CGTWO1DEV, CGTWO2DEV,
-#if (MAXSCREENS == 4)
+#if (MAXSCREENSDEFAULT == 4)
     CGTWO3DEV,
 #endif
 #endif /* } */
     CGTHREE0DEV,
 #ifndef i386 /* { */
     CGTHREE1DEV, CGTHREE2DEV,
-#if (MAXSCREENS == 4)
+#if (MAXSCREENSDEFAULT == 4)
     CGTHREE3DEV,
 #endif
 #endif /* } */
 #ifdef FBTYPE_SUNFAST_COLOR /* { */
     CGSIX0DEV, CGSIX1DEV, CGSIX2DEV,
-#if (MAXSCREENS == 4)
+#if (MAXSCREENSDEFAULT == 4)
     CGSIX3DEV,
 #endif
 #endif /* } */
 #ifndef i386 /* { */
     CGFOUR0DEV, BWTWO0DEV, BWTWO1DEV, BWTWO2DEV,
-#if (MAXSCREENS == 4)
+#if (MAXSCREENSDEFAULT == 4)
     BWTWO3DEV,
 #endif
 #endif /* } */
@@ -271,7 +271,7 @@ static char *fallbackList[] = {
 
 #define FALLBACK_LIST_LEN sizeof fallbackList / sizeof fallbackList[0]
 
-fbFd sunFbs[MAXSCREENS];
+fbFd *sunFbs;
 
 static PixmapFormatRec	formats[] = {
     { 1, 1, BITMAP_SCANLINE_PAD	} /* 1-bit deep */
@@ -435,6 +435,7 @@ static char** GetDeviceList (argc, argv)
     if (!cmdList)
 	envList = getenv ("XDEVICE");
 
+    MAXSCREEN_ASSERT_INIT();
     if (cmdList || envList) {
 	char	*_tmpa;
 	char	*_tmpb;
@@ -514,6 +515,7 @@ void OsVendorInit(
 )
 {
     static int inited;
+    MAXSCREEN_ASSERT_INIT();
     if (!inited) {
 #ifndef i386
 	struct rlimit rl;
@@ -582,6 +584,8 @@ void InitOutput(pScreenInfo, argc, argv)
     static int	setup_on_exit = 0;
     extern Bool	RunFromSmartParent;
 
+    MAXSCREENSALLOC_FATAL(sunFbs);
+
     if (!monitorResolution)
 	monitorResolution = 90;
     if (RunFromSmartParent)
Index: programs/Xserver/hw/sunLynx/sunLyInit.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/sunLynx/sunLyInit.c,v
retrieving revision 3.9
diff -u -p -r3.9 sunLyInit.c
--- programs/Xserver/hw/sunLynx/sunLyInit.c	17 Nov 2003 22:20:37 -0000	3.9
+++ programs/Xserver/hw/sunLynx/sunLyInit.c	8 Mar 2004 21:04:50 -0000
@@ -175,7 +175,7 @@ static char *fallbackList[] = {
 
 #define FALLBACK_LIST_LEN sizeof fallbackList / sizeof fallbackList[0]
 
-fbFd sunFbs[MAXSCREENS];
+fbFd *sunFbs;
 
 static PixmapFormatRec	formats[] = {
     { 1, 1, BITMAP_SCANLINE_PAD	} /* 1-bit deep */
@@ -330,6 +330,7 @@ void sunNonBlockConsoleOff(
 	}
     }
 #endif
+    MAXSCREEN_ASSERT_INIT();
     for (i = 0; i < MAXSCREENS; i++) {
     	if (sunFbs[i].fbuf) {
     		smem_create(NULL, (char*)sunFbs[i].fbuf, 0, SM_DETACH);
@@ -373,6 +374,7 @@ static char** GetDeviceList (argc, argv)
     if (!cmdList)
 	envList = getenv ("XDEVICE");
 
+    MAXSCREEN_ASSERT_INIT();
     if (cmdList || envList) {
 	char	*_tmpa;
 	char	*_tmpb;
@@ -492,6 +494,8 @@ void InitOutput(pScreenInfo, argc, argv)
     static int	setup_on_exit = 0;
     extern Bool	RunFromSmartParent;
 
+    MAXSCREENSALLOC(sunFbs);
+
     if (!monitorResolution)
 	monitorResolution = 90;
 
Index: programs/Xserver/hw/vfb/InitOutput.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/vfb/InitOutput.c,v
retrieving revision 3.26
diff -u -p -r3.26 InitOutput.c
--- programs/Xserver/hw/vfb/InitOutput.c	16 Nov 2003 03:16:59 -0000	3.26
+++ programs/Xserver/hw/vfb/InitOutput.c	8 Mar 2004 21:04:50 -0000
@@ -104,7 +104,7 @@ typedef struct
 } vfbScreenInfo, *vfbScreenInfoPtr;
 
 static int vfbNumScreens;
-static vfbScreenInfo vfbScreens[MAXSCREENS];
+static vfbScreenInfo *vfbScreens;
 static Bool vfbPixmapDepths[33];
 #ifdef HAS_MMAP
 static char *pfbdir = NULL;
@@ -138,6 +138,7 @@ vfbInitializeDefaultScreens(void)
 {
     int i;
 
+    MAXSCREENSALLOC_FATAL(vfbScreens);
     for (i = 0; i < MAXSCREENS; i++)
     {
 	vfbScreens[i].scrnum = i;
@@ -273,6 +274,8 @@ ddxUseMsg()
 #endif
 }
 
+static ColormapPtr *InstalledMaps;
+
 int
 ddxProcessArgument(int argc, char *argv[], int i)
 {
@@ -280,6 +283,7 @@ ddxProcessArgument(int argc, char *argv[
 
     if (firstTime)
     {
+        MAXSCREENSALLOC_FATAL(InstalledMaps);
 	vfbInitializeDefaultScreens();
 	vfbInitializePixmapDepths();
         firstTime = FALSE;
@@ -486,8 +490,6 @@ vfbMultiDepthGetImage(DrawablePtr pDrawa
     }
 }
 
-static ColormapPtr InstalledMaps[MAXSCREENS];
-
 static int
 vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 {
Index: programs/Xserver/hw/xfree86/common/xf86Cursor.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/common/xf86Cursor.c,v
retrieving revision 3.38
diff -u -p -r3.38 xf86Cursor.c
--- programs/Xserver/hw/xfree86/common/xf86Cursor.c	13 Feb 2004 23:58:36 -0000	3.38
+++ programs/Xserver/hw/xfree86/common/xf86Cursor.c	8 Mar 2004 21:04:51 -0000
@@ -104,7 +104,7 @@ static miPointerScreenFuncRec xf86Pointe
 #endif
 };
 
-static xf86ScreenLayoutRec xf86ScreenLayout[MAXSCREENS];
+static xf86ScreenLayoutRec *xf86ScreenLayout;
 
 static Bool HardEdges;
 
@@ -557,15 +557,18 @@ FillOutEdge(xf86EdgePtr pEdge, int limit
 	pEdge->end = limit;    
 }
 
-/*
- * xf86InitOrigins() can deal with a maximum of 32 screens
- * on 32 bit architectures, 64 on 64 bit architectures.
- */
+/* xf86InitOrigins() used to use a bitmask so that it was limited to 32
+ * screens on a 32-bit architecture, and 64 screens on a 64-bit
+ * architecture.  Instead of using a bitmask, we use an array; instead
+ * of copying screensLeft to prevScreensLeft and comparing to see if
+ * anything changed, we introduce the "changed" variable.  Another way
+ * to implement this function is presented in
+ * Xserver/hw/dmx/dmxcursor.c. */
 
 void
 xf86InitOrigins(void)
 {
-    unsigned long screensLeft, prevScreensLeft, mask;
+    int *screensLeft = NULL;
     screenLayoutPtr screen;
     ScreenPtr pScreen;
     int x1, x2, y1, y2, left, right, top, bottom;
@@ -576,13 +579,14 @@ xf86InitOrigins(void)
     /* need to have this set up with a config file option */
     HardEdges = FALSE;
 
-    bzero(xf86ScreenLayout, MAXSCREENS * sizeof(xf86ScreenLayoutRec));
+    MAXSCREENSALLOC_FATAL(xf86ScreenLayout);
+    MAXSCREENSALLOC_FATAL(screensLeft);
+    for (i = 0; i < xf86NumScreens; i++) screensLeft[i] = 1;
 	
-    screensLeft = prevScreensLeft = (1 << xf86NumScreens) - 1;
-
     while(1) {
-	for(mask = screensLeft, i = 0; mask; mask >>= 1, i++) {
-	    if(!(mask & 1L)) continue;
+        int changed = 0;
+	for(i = 0; i < xf86NumScreens; i++) {
+	    if (!screensLeft[i]) continue;
 
 	    screen = &xf86ConfigLayout.screens[i];
 
@@ -622,50 +626,50 @@ xf86InitOrigins(void)
 	    case PosAbsolute:
 		dixScreenOrigins[i].x = screen->x;
 		dixScreenOrigins[i].y = screen->y;
-		screensLeft &= ~(1 << i);
+                ++changed, screensLeft[i] = 0;
 		break;
 	    case PosRelative:
 		ref = screen->refscreen->screennum;
-		if(screensLeft & (1 << ref)) break;
+		if(screensLeft[ref]) break;
 		dixScreenOrigins[i].x = dixScreenOrigins[ref].x + screen->x;
 		dixScreenOrigins[i].y = dixScreenOrigins[ref].y + screen->y;
-		screensLeft &= ~(1 << i);
+                ++changed, screensLeft[i] = 0;
 		break;
 	    case PosRightOf:
 		ref = screen->refscreen->screennum;
-		if(screensLeft & (1 << ref)) break;
+		if(screensLeft[ref]) break;
 		pScreen = xf86Screens[ref]->pScreen;
 		dixScreenOrigins[i].x = 
 			dixScreenOrigins[ref].x + pScreen->width;
 		dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
-		screensLeft &= ~(1 << i);
+                ++changed, screensLeft[i] = 0;
 		break;
 	    case PosLeftOf:
 		ref = screen->refscreen->screennum;
-		if(screensLeft & (1 << ref)) break;
+		if(screensLeft[ref]) break;
 		pScreen = xf86Screens[i]->pScreen;
 		dixScreenOrigins[i].x = 
 			dixScreenOrigins[ref].x - pScreen->width;
 		dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
-		screensLeft &= ~(1 << i);
+                ++changed, screensLeft[i] = 0;
 		break;
 	    case PosBelow:
 		ref = screen->refscreen->screennum;
-		if(screensLeft & (1 << ref)) break;
+		if(screensLeft[ref]) break;
 		pScreen = xf86Screens[ref]->pScreen;
 		dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
 		dixScreenOrigins[i].y = 
 			dixScreenOrigins[ref].y + pScreen->height;
-		screensLeft &= ~(1 << i);
+                ++changed, screensLeft[i] = 0;
 		break;
 	    case PosAbove:
 		ref = screen->refscreen->screennum;
-		if(screensLeft & (1 << ref)) break;
+		if(screensLeft[ref]) break;
 		pScreen = xf86Screens[i]->pScreen;
 		dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
 		dixScreenOrigins[i].y = 
 			dixScreenOrigins[ref].y - pScreen->height;
-		screensLeft &= ~(1 << i);
+                ++changed, screensLeft[i] = 0;
 		break;
 	    default:
 		ErrorF("Illegal placement keyword in Layout!\n");
@@ -674,21 +678,20 @@ xf86InitOrigins(void)
 
 	}
 
-	if(!screensLeft) break;
-
-	if(screensLeft == prevScreensLeft) {
+	if(!changed) {
+            int n, count;
 	/* All the remaining screens are referencing each other.
 	   Assign a value to one of them and go through again */
-	    i = 0;
-	    while(!((1 << i) & screensLeft)){ i++; }
+            for (i = 0; i < xf86NumScreens; i++)
+                if (screensLeft[i]) break;
+            if (i >= xf86NumScreens) break; /* Finished */
 
 	    ref = xf86ConfigLayout.screens[i].refscreen->screennum;
 	    dixScreenOrigins[ref].x = dixScreenOrigins[ref].y = 0;
-	    screensLeft &= ~(1 << ref);
+            screensLeft[ref] = 0;
 	}
-
-	prevScreensLeft = screensLeft;
     }
+    MAXSCREENSFREE(screensLeft);
 
     /* justify the topmost and leftmost to (0,0) */
     minX = dixScreenOrigins[0].x;
@@ -789,6 +792,7 @@ xf86ReconfigureLayout(void)
 {
     int i;
 
+    MAXSCREEN_ASSERT_INIT();
     for (i = 0; i < MAXSCREENS; i++) {
 	xf86ScreenLayoutPtr sl = &xf86ScreenLayout[i];
 	/* we don't have to zero these, xf86InitOrigins() takes care of that */
Index: programs/Xserver/hw/xfree86/common/xf86xv.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/common/xf86xv.c,v
retrieving revision 1.38
diff -u -p -r1.38 xf86xv.c
--- programs/Xserver/hw/xfree86/common/xf86xv.c	19 Feb 2004 22:38:12 -0000	1.38
+++ programs/Xserver/hw/xfree86/common/xf86xv.c	8 Mar 2004 21:04:52 -0000
@@ -191,7 +191,7 @@ typedef struct {
    int num;
 } OffscreenImageRec;
 
-static OffscreenImageRec OffscreenImages[MAXSCREENS];
+static OffscreenImageRec *OffscreenImages;
 
 Bool
 xf86XVRegisterOffscreenImages(
@@ -199,6 +199,7 @@ xf86XVRegisterOffscreenImages(
     XF86OffscreenImagePtr images,
     int num
 ){
+    MAXSCREENSALLOC_FATAL(OffscreenImages);
     OffscreenImages[pScreen->myNum].num = num;
     OffscreenImages[pScreen->myNum].images = images;
 
Index: programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c,v
retrieving revision 1.10
diff -u -p -r1.10 r128_dga.c
--- programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c	10 Nov 2003 18:41:20 -0000	1.10
+++ programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c	8 Mar 2004 21:04:53 -0000
@@ -227,10 +227,12 @@ R128_SetMode(
    ScrnInfoPtr pScrn,
    DGAModePtr pMode
 ){
-   static R128FBLayout SavedLayouts[MAXSCREENS];
+   static R128FBLayout *SavedLayouts;
    int indx = pScrn->pScreen->myNum;
    R128InfoPtr info = R128PTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(SavedLayouts);
+
    if(!pMode) { /* restore the original mode */
 	/* put the ScreenParameters back */
 	if(info->DGAactive)
Index: programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c,v
retrieving revision 1.12
diff -u -p -r1.12 radeon_dga.c
--- programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c	10 Nov 2003 18:41:22 -0000	1.12
+++ programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c	8 Mar 2004 21:04:53 -0000
@@ -250,10 +250,12 @@ Bool RADEONDGAInit(ScreenPtr pScreen)
 
 static Bool RADEON_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
 {
-    static RADEONFBLayout  SavedLayouts[MAXSCREENS];
+    static RADEONFBLayout  *SavedLayouts;
     int                    indx = pScrn->pScreen->myNum;
     RADEONInfoPtr          info = RADEONPTR(pScrn);
 
+    MAXSCREENSALLOC_FATAL(SavedLayouts);
+
     if (!pMode) { /* restore the original mode */
 	/* put the ScreenParameters back */
 	if (info->DGAactive)
Index: programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c,v
retrieving revision 1.5
diff -u -p -r1.5 ct_dga.c
--- programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c	25 Nov 2002 14:04:58 -0000	1.5
+++ programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c	8 Mar 2004 21:04:53 -0000
@@ -187,11 +187,13 @@ CHIPS_SetMode(
    ScrnInfoPtr pScrn,
    DGAModePtr pMode
 ){
-   static int OldDisplayWidth[MAXSCREENS];
+   static int *OldDisplayWidth;
    int index = pScrn->pScreen->myNum;
 
    CHIPSPtr cPtr = CHIPSPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+
    if (!pMode) { /* restore the original mode */
 	/* put the ScreenParameters back */
        if (cPtr->DGAactive) {
Index: programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c,v
retrieving revision 1.7
diff -u -p -r1.7 cir_dga.c
--- programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c	1 Oct 2001 13:44:05 -0000	1.7
+++ programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c	8 Mar 2004 21:04:54 -0000
@@ -157,10 +157,12 @@ Cir_SetMode(
    DGAModePtr pMode
 ){
    CirPtr pCir = CIRPTR(pScrn);
-   static int OldDisplayWidth[MAXSCREENS];
+   static int *OldDisplayWidth;
    int index = pScrn->pScreen->myNum;
    Bool ret = FALSE;
 
+   MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+
    if(!pMode) { /* restore the original mode */
 	/* put the ScreenParameters back */
 	pScrn->displayWidth = OldDisplayWidth[index];
Index: programs/Xserver/hw/xfree86/drivers/dummy/dummy_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/dummy/dummy_dga.c,v
retrieving revision 1.1
diff -u -p -r1.1 dummy_dga.c
--- programs/Xserver/hw/xfree86/drivers/dummy/dummy_dga.c	18 Sep 2002 08:54:55 -0000	1.1
+++ programs/Xserver/hw/xfree86/drivers/dummy/dummy_dga.c	8 Mar 2004 21:04:54 -0000
@@ -102,7 +102,7 @@ DUMMYDGAInit(ScreenPtr pScreen)
    return DGAInit(pScreen, &DUMMYDGAFuncs, modes, num);  
 }
 
-static DisplayModePtr DUMMYSavedDGAModes[MAXSCREENS];
+static DisplayModePtr *DUMMYSavedDGAModes;
 
 static Bool
 DUMMY_SetMode(
@@ -112,6 +112,8 @@ DUMMY_SetMode(
    int index = pScrn->pScreen->myNum;
    DUMMYPtr pDUMMY = DUMMYPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(DUMMYSavedDGAModes);
+
    if(!pMode) { /* restore the original mode */
  	if(pDUMMY->DGAactive) {	
 	    pScrn->currentMode = DUMMYSavedDGAModes[index];
Index: programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c,v
retrieving revision 1.4
diff -u -p -r1.4 glint_dga.c
--- programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c	16 Dec 2001 21:36:50 -0000	1.4
+++ programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c	8 Mar 2004 21:04:54 -0000
@@ -157,10 +157,12 @@ GLINT_SetMode(
    ScrnInfoPtr pScrn,
    DGAModePtr pMode
 ){
-   static int OldDisplayWidth[MAXSCREENS];
+   static int *OldDisplayWidth;
    int index = pScrn->pScreen->myNum;
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+
    if(!pMode) { /* restore the original mode */
 	/* put the ScreenParameters back */
 	
Index: programs/Xserver/hw/xfree86/drivers/i128/i128dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/i128/i128dga.c,v
retrieving revision 1.4
diff -u -p -r1.4 i128dga.c
--- programs/Xserver/hw/xfree86/drivers/i128/i128dga.c	9 Oct 2002 16:38:19 -0000	1.4
+++ programs/Xserver/hw/xfree86/drivers/i128/i128dga.c	8 Mar 2004 21:04:54 -0000
@@ -141,11 +141,13 @@ I128_SetMode(
    ScrnInfoPtr pScrn,
    DGAModePtr pMode
 ){
-   static int OldDisplayWidth[MAXSCREENS];
+   static int *OldDisplayWidth;
    int index = pScrn->pScreen->myNum;
 
    I128Ptr pI128 = I128PTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+
    if(!pMode) { /* restore the original mode */
 	/* put the ScreenParameters back */
 	
Index: programs/Xserver/hw/xfree86/drivers/i740/i740_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_dga.c,v
retrieving revision 1.2
diff -u -p -r1.2 i740_dga.c
--- programs/Xserver/hw/xfree86/drivers/i740/i740_dga.c	12 Feb 2003 21:46:42 -0000	1.2
+++ programs/Xserver/hw/xfree86/drivers/i740/i740_dga.c	8 Mar 2004 21:04:55 -0000
@@ -134,13 +134,15 @@ Bool I740DGAInit(ScreenPtr pScreen)
   return DGAInit(pScreen, &I740DGAFuncs, modes, num);  
 }
 
-static DisplayModePtr I740SavedDGAModes[MAXSCREENS];
+static DisplayModePtr *I740SavedDGAModes;
 
 static Bool I740_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
 {
   int index = pScrn->pScreen->myNum;
   I740Ptr pI740 = I740PTR(pScrn);
 
+  MAXSCREENSALLOC_FATAL(I740SavedDGAModes);
+
   if(!pMode) { /* restore the original mode */
     if(pI740->DGAactive) {
       pScrn->currentMode = I740SavedDGAModes[index];
Index: programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c,v
retrieving revision 1.6
diff -u -p -r1.6 i810_dga.c
--- programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c	26 Feb 2003 04:19:36 -0000	1.6
+++ programs/Xserver/hw/xfree86/drivers/i810/i810_dga.c	8 Mar 2004 21:04:55 -0000
@@ -151,7 +151,7 @@ I810DGAInit(ScreenPtr pScreen)
    return DGAInit(pScreen, &I810DGAFuncs, modes, num);
 }
 
-static DisplayModePtr I810SavedDGAModes[MAXSCREENS];
+static DisplayModePtr *I810SavedDGAModes;
 
 static Bool
 I810_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
@@ -161,6 +161,8 @@ I810_SetMode(ScrnInfoPtr pScrn, DGAModeP
 
    MARKER();
 
+   MAXSCREENSALLOC_FATAL(I810SavedDGAModes);
+
    if (!pMode) {			/* restore the original mode */
       DPRINTF(PFX, "Restoring original mode (from DGA mode)\n");
       if (pI810->DGAactive) {
Index: programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c,v
retrieving revision 1.3
diff -u -p -r1.3 i830_dga.c
--- programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c	26 Feb 2003 04:11:23 -0000	1.3
+++ programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c	8 Mar 2004 21:04:57 -0000
@@ -151,7 +151,7 @@ I830DGAInit(ScreenPtr pScreen)
    return DGAInit(pScreen, &I830DGAFuncs, modes, num);
 }
 
-static DisplayModePtr I830SavedDGAModes[MAXSCREENS];
+static DisplayModePtr *I830SavedDGAModes;
 
 static Bool
 I830_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
@@ -161,6 +161,8 @@ I830_SetMode(ScrnInfoPtr pScrn, DGAModeP
 
    MARKER();
 
+   MAXSCREENSALLOC_FATAL(I830SavedDGAModes);
+
    if (!pMode) {			/* restore the original mode */
       DPRINTF(PFX, "Restoring original mode (from DGA mode)\n");
       if (pI830->DGAactive) {
Index: programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c,v
retrieving revision 1.17
diff -u -p -r1.17 mga_dga.c
--- programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c	8 Oct 2003 15:48:41 -0000	1.17
+++ programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c	8 Mar 2004 21:04:57 -0000
@@ -293,11 +293,13 @@ MGA_SetMode(
    ScrnInfoPtr pScrn,
    DGAModePtr pMode
 ){
-   static MGAFBLayout SavedLayouts[MAXSCREENS];
+   static MGAFBLayout *SavedLayouts;
    int index = pScrn->pScreen->myNum;
 
    MGAPtr pMga = MGAPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(SavedLayouts);
+
    if(!pMode) { /* restore the original mode */
       if(pMga->DGAactive)
         memcpy(&pMga->CurrentLayout, &SavedLayouts[index], sizeof(MGAFBLayout));
Index: programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c,v
retrieving revision 1.5
diff -u -p -r1.5 neo_dga.c
--- programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c	4 Apr 2002 14:05:44 -0000	1.5
+++ programs/Xserver/hw/xfree86/drivers/neomagic/neo_dga.c	8 Mar 2004 21:04:58 -0000
@@ -140,7 +140,7 @@ NEODGAInit(ScreenPtr pScreen)
    return DGAInit(pScreen, &NEODGAFuncs, modes, num);  
 }
 
-static DisplayModePtr NEOSavedDGAModes[MAXSCREENS];
+static DisplayModePtr *NEOSavedDGAModes;
 
 static Bool
 NEO_SetMode(
@@ -150,6 +150,8 @@ NEO_SetMode(
    int index = pScrn->pScreen->myNum;
    NEOPtr pNEO = NEOPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(NEOSavedDGAModes);
+
    if(!pMode) { /* restore the original mode */
  	if(pNEO->DGAactive) {	
 	    pScrn->currentMode = NEOSavedDGAModes[index];
Index: programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_dga.c,v
retrieving revision 1.2
diff -u -p -r1.2 nsc_gx1_dga.c
--- programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_dga.c	14 Jan 2003 09:34:31 -0000	1.2
+++ programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_dga.c	8 Mar 2004 21:04:58 -0000
@@ -307,10 +307,12 @@ GX1DGAInit(ScreenPtr pScreen)
 static Bool
 GX1_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
 {
-   static int OldDisplayWidth[MAXSCREENS];
+   static int *OldDisplayWidth;
    int index = pScrn->pScreen->myNum;
    GeodePtr pGeode = GEODEPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+
    DEBUGMSG(0, (0, X_NONE, "GX1_SetMode\n"));
    if (!pMode) {
       /* restore the original mode
Index: programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_dga.c,v
retrieving revision 1.2
diff -u -p -r1.2 nsc_gx2_dga.c
--- programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_dga.c	14 Jan 2003 09:34:32 -0000	1.2
+++ programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_dga.c	8 Mar 2004 21:04:59 -0000
@@ -306,10 +306,12 @@ GX2DGAInit(ScreenPtr pScreen)
 static Bool
 GX2_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
 {
-   static int OldDisplayWidth[MAXSCREENS];
+   static int *OldDisplayWidth;
    int index = pScrn->pScreen->myNum;
    GeodePtr pGeode = GEODEPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+
    DEBUGMSG(0, (0, X_NONE, "GX2_SetMode\n"));
    if (!pMode) {
       /* restore the original mode
Index: programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c,v
retrieving revision 1.12
diff -u -p -r1.12 nv_dga.c
--- programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c	31 Jul 2003 20:24:29 -0000	1.12
+++ programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c	8 Mar 2004 21:04:59 -0000
@@ -179,11 +179,13 @@ NV_SetMode(
    ScrnInfoPtr pScrn,
    DGAModePtr pMode
 ){
-   static NVFBLayout SavedLayouts[MAXSCREENS];
+   static NVFBLayout *SavedLayouts;
    int index = pScrn->pScreen->myNum;
 
    NVPtr pNv = NVPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(SavedLayouts);
+
    if(!pMode) { /* restore the original mode */
       if(pNv->DGAactive)
         memcpy(&pNv->CurrentLayout, &SavedLayouts[index], sizeof(NVFBLayout));
Index: programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v
retrieving revision 1.123
diff -u -p -r1.123 nv_driver.c
--- programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c	13 Jan 2004 19:03:28 -0000	1.123
+++ programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c	8 Mar 2004 21:05:00 -0000
@@ -500,8 +500,8 @@ NVProbe(DriverPtr drv, int flags)
     int i;
     GDevPtr *devSections;
     int *usedChips;
-    SymTabRec NVChipsets[MAX_CHIPS + 1];
-    PciChipsets NVPciChipsets[MAX_CHIPS + 1];
+    SymTabRec *NVChipsets;
+    PciChipsets *NVPciChipsets;
     pciVideoPtr *ppPci;
     int numDevSections;
     int numUsed;
@@ -516,6 +516,9 @@ NVProbe(DriverPtr drv, int flags)
 
     numUsed = 0;
 
+    MAXSCREENSALLOCPLUSONE_FATAL(NVChipsets);
+    MAXSCREENSALLOCPLUSONE_FATAL(NVPciChipsets);
+
     /* Create the NVChipsets and NVPciChipsets from found devices */
     while (*ppPci && (numUsed < MAX_CHIPS)) {
         if(((*ppPci)->vendor == PCI_VENDOR_NVIDIA_SGS) || 
@@ -574,6 +577,9 @@ NVProbe(DriverPtr drv, int flags)
     numUsed = xf86MatchPciInstances(NV_NAME, 0, NVChipsets, NVPciChipsets,
                                     devSections, numDevSections, drv,
                                     &usedChips);
+
+    MAXSCREENSFREE(NVChipsets);
+    MAXSCREENSFREE(NVPciChipsets);
                         
     if (numUsed <= 0) 
         return FALSE;
Index: programs/Xserver/hw/xfree86/drivers/nv/riva_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_dga.c,v
retrieving revision 1.1
diff -u -p -r1.1 riva_dga.c
--- programs/Xserver/hw/xfree86/drivers/nv/riva_dga.c	31 Jul 2003 20:24:29 -0000	1.1
+++ programs/Xserver/hw/xfree86/drivers/nv/riva_dga.c	8 Mar 2004 21:05:01 -0000
@@ -172,11 +172,13 @@ Riva_SetMode(
    ScrnInfoPtr pScrn,
    DGAModePtr pMode
 ){
-   static RivaFBLayout SavedLayouts[MAXSCREENS];
+   static RivaFBLayout *SavedLayouts;
    int index = pScrn->pScreen->myNum;
 
    RivaPtr pRiva = RivaPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(SavedLayouts);
+
    if(!pMode) { /* restore the original mode */
       if(pRiva->DGAactive)
         memcpy(&pRiva->CurrentLayout, &SavedLayouts[index], sizeof(RivaFBLayout));
Index: programs/Xserver/hw/xfree86/drivers/s3/s3_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_dga.c,v
retrieving revision 1.1
diff -u -p -r1.1 s3_dga.c
--- programs/Xserver/hw/xfree86/drivers/s3/s3_dga.c	2 Jul 2001 10:46:04 -0000	1.1
+++ programs/Xserver/hw/xfree86/drivers/s3/s3_dga.c	8 Mar 2004 21:05:01 -0000
@@ -222,9 +222,11 @@ Bool S3DGAInit(ScreenPtr pScreen)
 static Bool S3_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
 {
 	S3Ptr pS3 = S3PTR(pScrn);
-	static S3FBLayout SavedLayouts[MAXSCREENS];
+	static S3FBLayout *SavedLayouts;
 	int indx = pScrn->pScreen->myNum;
 
+        MAXSCREENSALLOC_FATAL(SavedLayouts);
+
 	if (!pMode) {
 		if (pS3->DGAactive) {
 			memcpy(&pS3->CurrentLayout, &SavedLayouts[indx],
Index: programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c,v
retrieving revision 1.8
diff -u -p -r1.8 s3v_dga.c
--- programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c	13 Feb 2004 23:58:43 -0000	1.8
+++ programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c	8 Mar 2004 21:05:01 -0000
@@ -234,11 +234,13 @@ S3V_SetMode(
    ScrnInfoPtr pScrn,
    DGAModePtr pMode
 ){
-   static int OldDisplayWidth[MAXSCREENS];
+   static int *OldDisplayWidth;
    int index = pScrn->pScreen->myNum;
 
    S3VPtr ps3v = S3VPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+
    if(!pMode) { /* restore the original mode */
 	/* put the ScreenParameters back */
 	
Index: programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c,v
retrieving revision 1.7
diff -u -p -r1.7 savage_dga.c
--- programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c	13 Feb 2004 23:58:44 -0000	1.7
+++ programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c	8 Mar 2004 21:05:02 -0000
@@ -280,13 +280,18 @@ Savage_SetMode(
     ScrnInfoPtr pScrn,
     DGAModePtr pMode
 ){
-    static int OldDisplayWidth[MAXSCREENS];
-    static int OldBitsPerPixel[MAXSCREENS];
-    static int OldDepth[MAXSCREENS];
-    static DisplayModePtr OldMode[MAXSCREENS];
+    static int *OldDisplayWidth;
+    static int *OldBitsPerPixel;
+    static int *OldDepth;
+    static DisplayModePtr *OldMode;
     int index = pScrn->pScreen->myNum;
     SavagePtr psav = SAVPTR(pScrn);
 
+    MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+    MAXSCREENSALLOC_FATAL(OldBitsPerPixel);
+    MAXSCREENSALLOC_FATAL(OldDepth);
+    MAXSCREENSALLOC_FATAL(OldMode);
+
     if(!pMode) { /* restore the original mode */
 	/* put the ScreenParameters back */
 
Index: programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_dga.c,v
retrieving revision 1.2
diff -u -p -r1.2 smi_dga.c
--- programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_dga.c	15 Feb 2001 18:20:33 -0000	1.2
+++ programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_dga.c	8 Mar 2004 21:05:02 -0000
@@ -159,12 +159,14 @@ SMI_DGAInit(ScreenPtr pScreen)
 static Bool
 SMI_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
 {
-	static int OldDisplayWidth[MAXSCREENS];
+	static int *OldDisplayWidth;
 	int index = pScrn->pScreen->myNum;
 	SMIPtr pSmi = SMIPTR(pScrn);
 
 	ENTER_PROC("SMI_SetMode");
 
+        MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+
 	if (pMode == NULL)
 	{	/* restore the original mode */
 
Index: programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c,v
retrieving revision 1.13
diff -u -p -r1.13 sis_dga.c
--- programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c	4 Jan 2004 18:08:00 -0000	1.13
+++ programs/Xserver/hw/xfree86/drivers/sis/sis_dga.c	8 Mar 2004 21:05:03 -0000
@@ -273,10 +273,12 @@ SIS_SetMode(
    ScrnInfoPtr pScrn,
    DGAModePtr pMode
 ){
-   static SISFBLayout BackupLayouts[MAXSCREENS];
+   static SISFBLayout *BackupLayouts;
    int index = pScrn->pScreen->myNum;
    SISPtr pSiS = SISPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(BackupLayouts);
+
     if(!pMode) { /* restore the original mode */
 
         if(pSiS->DGAactive) {
Index: programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c,v
retrieving revision 1.6
diff -u -p -r1.6 tdfx_dga.c
--- programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c	21 Mar 2001 17:02:26 -0000	1.6
+++ programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c	8 Mar 2004 21:05:03 -0000
@@ -101,11 +101,13 @@ TDFXDGAInit(ScreenPtr pScreen)
 static Bool
 TDFX_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
 {
-   static DisplayModePtr OldModes[MAXSCREENS];
+   static DisplayModePtr *OldModes;
    int index = pScrn->pScreen->myNum;
 
    TDFXPtr pTDFX = TDFXPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(OldModes);
+
    if (!pMode) { /* restore the original mode */
      /* put the ScreenParameters back */
      if(pTDFX->DGAactive) {
Index: programs/Xserver/hw/xfree86/drivers/trident/trident_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dga.c,v
retrieving revision 1.5
diff -u -p -r1.5 trident_dga.c
--- programs/Xserver/hw/xfree86/drivers/trident/trident_dga.c	5 Sep 2003 22:07:28 -0000	1.5
+++ programs/Xserver/hw/xfree86/drivers/trident/trident_dga.c	8 Mar 2004 21:05:03 -0000
@@ -166,10 +166,12 @@ TRIDENT_SetMode(
    ScrnInfoPtr pScrn,
    DGAModePtr pMode
 ){
-   static int OldDisplayWidth[MAXSCREENS];
+   static int *OldDisplayWidth;
    int index = pScrn->pScreen->myNum;
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
+   MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+
    if(!pMode) { /* restore the original mode */
 	/* put the ScreenParameters back */
 	
Index: programs/Xserver/hw/xfree86/drivers/tseng/tseng_dga.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_dga.c,v
retrieving revision 1.2
diff -u -p -r1.2 tseng_dga.c
--- programs/Xserver/hw/xfree86/drivers/tseng/tseng_dga.c	1 Oct 2001 13:44:11 -0000	1.2
+++ programs/Xserver/hw/xfree86/drivers/tseng/tseng_dga.c	8 Mar 2004 21:05:04 -0000
@@ -151,10 +151,12 @@ Tseng_SetMode(
    DGAModePtr pMode
 ){
    TsengPtr pTseng = TsengPTR(pScrn);
-   static int OldDisplayWidth[MAXSCREENS];
+   static int *OldDisplayWidth;
    int index = pScrn->pScreen->myNum;
    Bool ret;
 
+   MAXSCREENSALLOC_FATAL(OldDisplayWidth);
+
    if(!pMode) { /* restore the original mode */
 	/* put the ScreenParameters back */
 	pScrn->displayWidth = OldDisplayWidth[index];
Index: programs/Xserver/hw/xfree86/os-support/bsd/arm_video.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/os-support/bsd/arm_video.c,v
retrieving revision 1.2
diff -u -p -r1.2 arm_video.c
--- programs/Xserver/hw/xfree86/os-support/bsd/arm_video.c	14 Mar 2003 13:46:03 -0000	1.2
+++ programs/Xserver/hw/xfree86/os-support/bsd/arm_video.c	8 Mar 2004 21:05:05 -0000
@@ -550,7 +550,7 @@ xf86EnableInterrupts()
 #define	DEV_MEM_IOBASE	0x43000000
 #endif
 
-static Bool ScreenEnabled[MAXSCREENS];
+static Bool *ScreenEnabled;
 static Bool ExtendedEnabled = FALSE;
 static Bool InitDone = FALSE;
 
@@ -567,6 +567,7 @@ int ScreenNum;
 	int *Size;
 #endif
 
+        MAXSCREENSALLOC_FATAL(ScreenEnabled);
 	ScreenEnabled[ScreenNum] = TRUE;
 
 	if (ExtendedEnabled)
@@ -650,6 +651,7 @@ int ScreenNum;
         struct memAccess *memInfoP;
 #endif
 
+        MAXSCREENSALLOC_FATAL(ScreenEnabled);
 	ScreenEnabled[ScreenNum] = FALSE;
 
 #ifdef __arm32__
Index: programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c,v
retrieving revision 1.7
diff -u -p -r1.7 dgux_video.c
--- programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c	14 Mar 2003 13:46:05 -0000	1.7
+++ programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c	8 Mar 2004 21:05:05 -0000
@@ -124,7 +124,7 @@ unsigned long Size;
 #define ALWAYS_USE_EXTENDED
 #ifdef ALWAYS_USE_EXTENDED
 
-static Bool ScreenEnabled[MAXSCREENS];
+static Bool *ScreenEnabled;
 static Bool ExtendedEnabled = FALSE;
 static Bool InitDone = FALSE;
 
@@ -135,6 +135,7 @@ int ScreenNum;
 	if (!InitDone)
 	{
 		int i;
+                MAXSCREENSALLOC_FATAL(ScreenEnabled);
 		for (i = 0; i < MAXSCREENS; i++)
 			ScreenEnabled[i] = FALSE;
 		InitDone = TRUE;
@@ -157,6 +158,7 @@ int ScreenNum;
 {
 	int i;
 
+        MAXSCREENSALLOC_FATAL(ScreenEnabled);
 	ScreenEnabled[ScreenNum] = TRUE;
 
 	if (ExtendedEnabled)
@@ -178,6 +180,7 @@ int ScreenNum;
 {
 	int i;
 
+        MAXSCREENSALLOC_FATAL(ScreenEnabled);
 	ScreenEnabled[ScreenNum] = FALSE;
 
 	if (!ExtendedEnabled)
@@ -199,10 +202,10 @@ int ScreenNum;
 #define NON_EXTENDED	1
 #define EXTENDED	2
 
-static unsigned *EnabledPorts[MAXSCREENS];
-static int NumEnabledPorts[MAXSCREENS];
-static Bool ScreenEnabled[MAXSCREENS];
-static Bool ExtendedPorts[MAXSCREENS];
+static unsigned *EnabledPorts;
+static int *NumEnabledPorts;
+static Bool *ScreenEnabled;
+static Bool *ExtendedPorts;
 static Bool ExtendedEnabled = FALSE;
 static Bool InitDone = FALSE;
 static struct kd_disparam OrigParams;
@@ -212,6 +215,11 @@ int ScreenNum;
 {
 	if (!InitDone)
 	{
+		MAXSCREENSALLOC_FATAL(EnablePorts);
+		MAXSCREENSALLOC_FATAL(NumEnablePorts);
+		MAXSCREENSALLOC_FATAL(ScreenEnabled);
+		MAXSCREENSALLOC_FATAL(ExtendedPorts);
+                /* FIXME xf86InitPortLists isn't defined anywhere in tree */
 		xf86InitPortLists(EnabledPorts, NumEnabledPorts, ScreenEnabled,
 				  ExtendedPorts, MAXSCREENS);
 		if (ioctl(xf86Info.consoleFd, KDDISPTYPE, &OrigParams) < 0)
@@ -327,7 +335,8 @@ int ScreenNum;
 	struct kd_disparam param;
 	int i, j;
 
-	if (!ScreenEnabled[ScreenNum])
+        MAXSCREEN_ASSERT_INIT();
+        if (!ScreenEnabled[ScreenNum])
 		return;
 
 	ScreenEnabled[ScreenNum] = FALSE;
Index: programs/Xserver/hw/xfree86/xf8_16bpp/cfbscrinit.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbscrinit.c,v
retrieving revision 1.8
diff -u -p -r1.8 cfbscrinit.c
--- programs/Xserver/hw/xfree86/xf8_16bpp/cfbscrinit.c	17 Feb 2003 16:08:30 -0000	1.8
+++ programs/Xserver/hw/xfree86/xf8_16bpp/cfbscrinit.c	8 Mar 2004 21:05:06 -0000
@@ -347,10 +347,13 @@ cfb8_16EnableDisableFBAccess(int index, 
 {
     ScreenPtr pScreen = xf86Screens[index]->pScreen;
     cfb8_16ScreenPtr pScreenPriv = CFB8_16_GET_SCREEN_PRIVATE(pScreen);
-    static DevUnion devPrivates8[MAXSCREENS];
-    static DevUnion devPrivates16[MAXSCREENS];
+    static DevUnion *devPrivates8;
+    static DevUnion *devPrivates16;
     PixmapPtr	pix8, pix16;
 
+    MAXSCREENSALLOC_FATAL(devPrivates8);
+    MAXSCREENSALLOC_FATAL(devPrivates16);
+
     pix8 = (PixmapPtr) pScreenPriv->pix8;
     pix16 = (PixmapPtr) pScreenPriv->pix16;
 
Index: programs/Xserver/hw/xfree86/xf8_32wid/cfbscrinit.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/xf8_32wid/cfbscrinit.c,v
retrieving revision 1.1
diff -u -p -r1.1 cfbscrinit.c
--- programs/Xserver/hw/xfree86/xf8_32wid/cfbscrinit.c	21 May 2000 01:02:43 -0000	1.1
+++ programs/Xserver/hw/xfree86/xf8_32wid/cfbscrinit.c	8 Mar 2004 21:05:07 -0000
@@ -359,10 +359,13 @@ cfb8_32WidEnableDisableFBAccess(int inde
 {
 	ScreenPtr pScreen = xf86Screens[index]->pScreen;
 	cfb8_32WidScreenPtr pScreenPriv = CFB8_32WID_GET_SCREEN_PRIVATE(pScreen);
-	static DevUnion devPrivates8[MAXSCREENS];
-	static DevUnion devPrivates32[MAXSCREENS];
+	static DevUnion *devPrivates8;
+	static DevUnion *devPrivates32;
 	PixmapPtr	pix8, pix32;
 
+        MAXSCREENSALLOC_FATAL(devPrivates8);
+        MAXSCREENSALLOC_FATAL(devPrivates32);
+
 	pix8 = (PixmapPtr) pScreenPriv->pix8;
 	pix32 = (PixmapPtr) pScreenPriv->pix32;
 
Index: programs/Xserver/hw/xnest/Args.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xnest/Args.c,v
retrieving revision 1.2
diff -u -p -r1.2 Args.c
--- programs/Xserver/hw/xnest/Args.c	16 Nov 2003 05:05:20 -0000	1.2
+++ programs/Xserver/hw/xnest/Args.c	8 Mar 2004 21:05:07 -0000
@@ -149,13 +149,13 @@ ddxProcessArgument (int argc, char *argv
   }
   if (!strcmp(argv[i], "-scrns")) {
     if (++i < argc && sscanf(argv[i], "%i", &xnestNumScreens) == 1) {
-      if (xnestNumScreens > 0) {
+        if (xnestNumScreens > 0) SetMaxScreens(xnestNumScreens);
+        else                     return 0;
 	if (xnestNumScreens > MAXSCREENS) {
 	  ErrorF("Maximum number of screens is %d.\n", MAXSCREENS);
 	  xnestNumScreens = MAXSCREENS;
 	}
 	return 2;
-      }
     }
     return 0;
   }
Index: programs/Xserver/hw/xnest/Color.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xnest/Color.c,v
retrieving revision 1.4
diff -u -p -r1.4 Color.c
--- programs/Xserver/hw/xnest/Color.c	16 Nov 2003 05:05:20 -0000	1.4
+++ programs/Xserver/hw/xnest/Color.c	8 Mar 2004 21:05:07 -0000
@@ -32,7 +32,7 @@ is" without express or implied warranty.
 #include "XNWindow.h"
 #include "Args.h"
 
-static ColormapPtr InstalledMaps[MAXSCREENS];
+static ColormapPtr *InstalledMaps;
 
 Bool
 xnestCreateColormap(ColormapPtr pCmap)
@@ -330,6 +330,8 @@ xnestInstallColormap(ColormapPtr pCmap)
 {
   int index;
   ColormapPtr pOldCmap;
+
+  MAXSCREENSALLOC_FATAL(InstalledMaps);
   
   index = pCmap->pScreen->myNum;
   pOldCmap = InstalledMaps[index];
@@ -356,6 +358,8 @@ xnestUninstallColormap(ColormapPtr pCmap
   int index;
   ColormapPtr pCurCmap;
   
+  MAXSCREENSALLOC_FATAL(InstalledMaps);
+
   index = pCmap->pScreen->myNum;
   pCurCmap = InstalledMaps[index];
   
Index: programs/Xserver/hw/xnest/Init.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xnest/Init.c,v
retrieving revision 3.25
diff -u -p -r3.25 Init.c
--- programs/Xserver/hw/xnest/Init.c	16 Nov 2003 05:05:20 -0000	3.25
+++ programs/Xserver/hw/xnest/Init.c	8 Mar 2004 21:05:07 -0000
@@ -48,6 +48,9 @@ InitOutput(ScreenInfo *screenInfo, int a
 {
   int i, j;
 
+  MAXSCREENSALLOC_FATAL(xnestDefaultWindows);
+  MAXSCREENSALLOC_FATAL(xnestScreenSaverWindows);
+
   xnestOpenDisplay(argc, argv);
   
   screenInfo->imageByteOrder = ImageByteOrder(xnestDisplay);
Index: programs/Xserver/hw/xnest/Screen.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xnest/Screen.c,v
retrieving revision 3.13
diff -u -p -r3.13 Screen.c
--- programs/Xserver/hw/xnest/Screen.c	16 Nov 2003 05:05:20 -0000	3.13
+++ programs/Xserver/hw/xnest/Screen.c	8 Mar 2004 21:05:08 -0000
@@ -40,8 +40,8 @@ is" without express or implied warranty.
 #include "mipointer.h"
 #include "Args.h"
 
-Window xnestDefaultWindows[MAXSCREENS];
-Window xnestScreenSaverWindows[MAXSCREENS];
+Window *xnestDefaultWindows;
+Window *xnestScreenSaverWindows;
 
 #ifdef GLXEXT
 extern void GlxWrapInitVisuals(miInitVisualsProcPtr *);
Index: programs/Xserver/hw/xnest/Screen.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xnest/Screen.h,v
retrieving revision 1.2
diff -u -p -r1.2 Screen.h
--- programs/Xserver/hw/xnest/Screen.h	16 Nov 2003 05:05:20 -0000	1.2
+++ programs/Xserver/hw/xnest/Screen.h	8 Mar 2004 21:05:08 -0000
@@ -17,8 +17,8 @@ is" without express or implied warranty.
 #ifndef XNESTSCREEN_H
 #define XNESTSCREEN_H
 
-extern Window xnestDefaultWindows[MAXSCREENS];
-extern Window xnestScreenSaverWindows[MAXSCREENS];
+extern Window *xnestDefaultWindows;
+extern Window *xnestScreenSaverWindows;
 
 ScreenPtr xnestScreen(Window window);
 Bool xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[]);
Index: programs/Xserver/hw/xwin/InitOutput.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xwin/InitOutput.c,v
retrieving revision 1.35
diff -u -p -r1.35 InitOutput.c
--- programs/Xserver/hw/xwin/InitOutput.c	8 Oct 2003 11:13:02 -0000	1.35
+++ programs/Xserver/hw/xwin/InitOutput.c	8 Mar 2004 21:05:08 -0000
@@ -37,7 +37,7 @@ from The Open Group.
  */
 
 int		g_iNumScreens = 0;
-winScreenInfo	g_ScreenInfo[MAXSCREENS];
+winScreenInfo	*g_ScreenInfo;
 int		g_iLastScreen = -1;
 int		g_fdMessageQueue = WIN_FD_INVALID;
 int		g_iScreenPrivateIndex = -1;
@@ -117,6 +117,7 @@ winInitializeDefaultScreens (void)
   if (g_fInitializedDefaultScreens)
     return;
 
+  MAXSCREENSALLOC_FATAL(g_ScreenInfo);
   /* Zero the memory used for storing the screen info */
   ZeroMemory (g_ScreenInfo, MAXSCREENS * sizeof (winScreenInfo));
 
@@ -425,6 +426,7 @@ ddxProcessArgument (int argc, char *argv
   ErrorF ("ddxProcessArgument - arg: %s\n", argv[i]);
 #endif
   
+  MAXSCREEN_ASSERT_INIT();
   /*
    * Look for the '-screen scr_num [width height]' argument
    */
@@ -1274,6 +1276,8 @@ InitOutput (ScreenInfo *screenInfo, int 
   if (!winReadConfigfile ())
     ErrorF ("InitOutput - Error reading config file\n");
 
+  MAXSCREENSALLOC_FATAL(g_ScreenInfo);
+
   /* Setup global screen info parameters */
   screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
   screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
Index: programs/Xserver/include/cursorstr.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/include/cursorstr.h,v
retrieving revision 1.9
diff -u -p -r1.9 cursorstr.h
--- programs/Xserver/include/cursorstr.h	12 Jan 2003 02:44:27 -0000	1.9
+++ programs/Xserver/include/cursorstr.h	8 Mar 2004 21:05:09 -0000
@@ -65,7 +65,7 @@ typedef struct _CursorBits {
     Bool emptyMask;				/* all zeros mask */
     unsigned short width, height, xhot, yhot;	/* metrics */
     int refcnt;					/* can be shared */
-    pointer devPriv[MAXSCREENS];		/* set by pScr->RealizeCursor*/
+    pointer *devPriv;				/* set by pScr->RealizeCursor*/
 #ifdef ARGB_CURSOR
     CARD32 *argb;				/* full-color alpha blended */
 #endif
@@ -76,7 +76,7 @@ typedef struct _Cursor {
     unsigned short foreRed, foreGreen, foreBlue; /* device-independent color */
     unsigned short backRed, backGreen, backBlue; /* device-independent color */
     int refcnt;
-    pointer devPriv[MAXSCREENS];		/* set by pScr->RealizeCursor*/
+    pointer *devPriv;				/* set by pScr->RealizeCursor*/
 } CursorRec;
 
 typedef struct _CursorMetric {
Index: programs/Xserver/include/dixstruct.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/include/dixstruct.h,v
retrieving revision 3.20
diff -u -p -r3.20 dixstruct.h
--- programs/Xserver/include/dixstruct.h	3 Nov 2003 05:11:59 -0000	3.20
+++ programs/Xserver/include/dixstruct.h	8 Mar 2004 21:05:09 -0000
@@ -87,7 +87,7 @@ typedef struct _Client {
     GContext    lastGCID;
     pointer    *saveSet;
     int         numSaved;
-    pointer     screenPrivate[MAXSCREENS];
+    pointer     *screenPrivate;
     int         (**requestVector) (
 		ClientPtr /* pClient */);
     CARD32	req_len;		/* length of current request */
Index: programs/Xserver/include/globals.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/include/globals.h,v
retrieving revision 1.4
diff -u -p -r1.4 globals.h
--- programs/Xserver/include/globals.h	28 Jun 2000 18:21:22 -0000	1.4
+++ programs/Xserver/include/globals.h	8 Mar 2004 21:05:09 -0000
@@ -23,7 +23,7 @@ extern WindowPtr *WindowTable;
 extern int GrabInProgress;
 extern Bool noTestExtensions;
 
-extern DDXPointRec dixScreenOrigins[MAXSCREENS];
+extern DDXPointRec *dixScreenOrigins;
 
 #ifdef DPMSExtension
 extern CARD32 defaultDPMSStandbyTime;
Index: programs/Xserver/include/misc.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/include/misc.h,v
retrieving revision 3.29
diff -u -p -r3.29 misc.h
--- programs/Xserver/include/misc.h	27 Apr 2003 21:31:04 -0000	3.29
+++ programs/Xserver/include/misc.h	8 Mar 2004 21:05:09 -0000
@@ -89,9 +89,51 @@ extern unsigned long serverGeneration;
 #endif
 #endif
 
-#ifndef MAXSCREENS
-#define MAXSCREENS	16
-#endif
+#define MAXSCREENSDEFAULT 1
+extern int  MAXSCREENS;
+extern void *MaxScreensAlloc(unsigned long size);
+extern void MaxScreensFree(void *object);
+extern void SetMaxScreens(int maxscreens);
+
+/* assert that init has been done */
+#define MAXSCREEN_ASSERT_INIT() do {                                    \
+    MaxScreensFree(MaxScreensAlloc(1)); } while (0)
+
+#define MAXSCREEN_MAKECONSTSTR1(x) #x
+#define MAXSCREEN_MAKECONSTSTR2(x) MAXSCREEN_MAKECONSTSTR1(x)
+
+#define MAXSCREEN_FAILED_TXT "Failed at ["                              \
+   MAXSCREEN_MAKECONSTSTR2(__LINE__) ":" __FILE__ "] to allocate object: "
+
+#define _MAXSCREENSALLOCF(o,size,fatal)                                 \
+    do {                                                                \
+        if (!o) {                                                       \
+            o = MaxScreensAlloc((size) * sizeof(*(o)));                 \
+            if (!o && fatal) FatalError(MAXSCREEN_FAILED_TXT #o);       \
+        }                                                               \
+    } while (0)
+#define _MAXSCREENSALLOCR(o,size,retval)                                \
+    do {                                                                \
+        if (!o) {                                                       \
+            o = MaxScreensAlloc((size) * sizeof(*(o)));                 \
+            if (!o) return retval;                                      \
+        }                                                               \
+    } while (0)
+        
+#define MAXSCREENSFREE(o)                                               \
+    do {                                                                \
+        if (o) MaxScreensFree(o);                                       \
+        o = NULL;                                                       \
+    } while (0)
+
+#define MAXSCREENSALLOC(o)              _MAXSCREENSALLOCF(o,MAXSCREENS,  0)
+#define MAXSCREENSALLOC_FATAL(o)        _MAXSCREENSALLOCF(o,MAXSCREENS,  1)
+#define MAXSCREENSALLOC_RETURN(o,r)     _MAXSCREENSALLOCR(o,MAXSCREENS, (r))
+#define MAXSCREENSALLOCPLUSONE(o)       _MAXSCREENSALLOCF(o,MAXSCREENS+1,0)
+#define MAXSCREENSALLOCPLUSONE_FATAL(o) _MAXSCREENSALLOCF(o,MAXSCREENS+1,1)
+#define MAXSCREENSCALLOC(o,m)           _MAXSCREENSALLOCF(o,MAXSCREENS*(m),0)
+#define MAXSCREENSCALLOC_FATAL(o,m)     _MAXSCREENSALLOCF(o,MAXSCREENS*(m),1)
+
 #define MAXCLIENTS	256
 #define MAXDITS		1
 #define MAXEXTENSIONS	128
Index: programs/Xserver/include/scrnintstr.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/include/scrnintstr.h,v
retrieving revision 1.13
diff -u -p -r1.13 scrnintstr.h
--- programs/Xserver/include/scrnintstr.h	16 Jul 2003 01:38:53 -0000	1.13
+++ programs/Xserver/include/scrnintstr.h	8 Mar 2004 21:05:10 -0000
@@ -719,7 +719,7 @@ typedef struct _ScreenInfo {
 		formats[MAXFORMATS];
     int		arraySize;
     int		numScreens;
-    ScreenPtr	screens[MAXSCREENS];
+    ScreenPtr	*screens;
     int		numVideoScreens;
 } ScreenInfo;
 
Index: programs/Xserver/include/windowstr.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/include/windowstr.h,v
retrieving revision 1.7
diff -u -p -r1.7 windowstr.h
--- programs/Xserver/include/windowstr.h	27 Apr 2003 21:31:05 -0000	1.7
+++ programs/Xserver/include/windowstr.h	8 Mar 2004 21:05:10 -0000
@@ -201,7 +201,7 @@ typedef struct _ScreenSaverStuff {
 #define HasSaverWindow(i)   (savedScreenInfo[i].pWindow != NullWindow)
 
 extern int screenIsSaved;
-extern ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+extern ScreenSaverStuffRec *savedScreenInfo;
 
 /*
  * this is the configuration parameter "NO_BACK_SAVE"
Index: programs/Xserver/lbx/lbxdix.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/lbx/lbxdix.c,v
retrieving revision 1.8
diff -u -p -r1.8 lbxdix.c
--- programs/Xserver/lbx/lbxdix.c	14 Dec 2001 19:59:59 -0000	1.8
+++ programs/Xserver/lbx/lbxdix.c	8 Mar 2004 21:05:11 -0000
@@ -123,6 +123,8 @@ LbxSendConnSetup(ClientPtr   client,
     client->sequence = 0;
     dataBuf[0] = client->clientAsMask;
 
+    MAXSCREEN_ASSERT_INIT();
+
     csp.success = TRUE;
     csp.majorVersion = connSetupPrefix.majorVersion;
     csp.minorVersion = connSetupPrefix.minorVersion;
Index: programs/Xserver/mi/miclipn.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/mi/miclipn.c,v
retrieving revision 1.4
diff -u -p -r1.4 miclipn.c
--- programs/Xserver/mi/miclipn.c	14 Dec 2001 20:00:21 -0000	1.4
+++ programs/Xserver/mi/miclipn.c	8 Mar 2004 21:05:11 -0000
@@ -34,7 +34,7 @@ from The Open Group.
 #include "mi.h"
 
 static void	(*clipNotify)(WindowPtr,int,int) = 0;
-static void	(*ClipNotifies[MAXSCREENS])(WindowPtr,int,int);
+static void	(**ClipNotifies)(WindowPtr,int,int);
 
 static void
 miClipNotifyWrapper(
@@ -67,6 +67,8 @@ miClipNotify (
 {
     int i;
 
+    MAXSCREENSALLOC_FATAL(ClipNotifies);
+
     clipNotify = func;
     if (clipGeneration != serverGeneration)
     {
Index: programs/Xserver/mi/micmap.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/mi/micmap.c,v
retrieving revision 1.11
diff -u -p -r1.11 micmap.c
--- programs/Xserver/mi/micmap.c	29 May 2001 22:24:06 -0000	1.11
+++ programs/Xserver/mi/micmap.c	8 Mar 2004 21:05:11 -0000
@@ -44,7 +44,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "globals.h"
 #include "micmap.h"
 
-ColormapPtr miInstalledMaps[MAXSCREENS];
+ColormapPtr *miInstalledMaps;
 
 static Bool miDoInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
 		int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
@@ -482,6 +482,7 @@ miInitVisuals(VisualPtr *visualp, DepthP
 		unsigned long sizes, int bitsPerRGB, int preferredVis)
 
 {
+    MAXSCREENSALLOC_RETURN(miInstalledMaps, FALSE);
     if (miInitVisualsProc)
 	return miInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
 				 rootDepthp, defaultVisp, sizes, bitsPerRGB,
Index: programs/Xserver/mi/micmap.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/mi/micmap.h,v
retrieving revision 1.7
diff -u -p -r1.7 micmap.h
--- programs/Xserver/mi/micmap.h	20 Sep 2000 00:09:15 -0000	1.7
+++ programs/Xserver/mi/micmap.h	8 Mar 2004 21:05:11 -0000
@@ -5,7 +5,7 @@
 #ifndef _MICMAP_H_
 #define _MICMAP_H_
 
-extern ColormapPtr miInstalledMaps[MAXSCREENS];
+extern ColormapPtr *miInstalledMaps;
 
 typedef Bool (* miInitVisualsProcPtr)(VisualPtr *, DepthPtr *, int *, int *,
 					int *, VisualID *, unsigned long, int,
Index: programs/Xserver/mi/miexpose.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/mi/miexpose.c,v
retrieving revision 3.10
diff -u -p -r3.10 miexpose.c
--- programs/Xserver/mi/miexpose.c	10 Nov 2003 18:22:49 -0000	3.10
+++ programs/Xserver/mi/miexpose.c	8 Mar 2004 21:05:12 -0000
@@ -579,7 +579,7 @@ border tile in the resource table.
 
 static RESTYPE ResType = 0;
 static int numGCs = 0;
-static GCPtr	screenContext[MAXSCREENS];
+static GCPtr	*screenContext;
 
 /*ARGSUSED*/
 static int
@@ -729,6 +729,8 @@ int what;
 	/*
 	 * draw the background to the root window
 	 */
+        MAXSCREENSALLOC_FATAL(screenContext);
+
 	if (screenContext[i] == (GCPtr)NULL)
 	{
 	    if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
Index: programs/Xserver/os/utils.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/os/utils.c,v
retrieving revision 3.97
diff -u -p -r3.97 utils.c
--- programs/Xserver/os/utils.c	9 Jan 2004 00:35:06 -0000	3.97
+++ programs/Xserver/os/utils.c	8 Mar 2004 21:05:13 -0000
@@ -514,6 +514,7 @@ void UseMsg(void)
     ErrorF("-logo                  enable logo in screen saver\n");
     ErrorF("nologo                 disable logo in screen saver\n");
 #endif
+    ErrorF("-maxscreens int        maximum number of screens available\n");
     ErrorF("-nolisten string       don't listen on protocol\n");
     ErrorF("-p #                   screen-saver pattern duration (minutes)\n");
     ErrorF("-pn                    accept failure to listen on all ports\n");
@@ -865,6 +866,19 @@ ProcessCommandLine(int argc, char *argv[
 	    defaultScreenSaverBlanking = DontPreferBlanking;
 	else if ( strcmp( argv[i], "-wm") == 0)
 	    defaultBackingStore = WhenMapped;
+        else if ( strcmp( argv[i], "-maxscreens") == 0) {
+            if(++i < argc) {
+                int maxscreens = atoi(argv[i]);
+                
+                if (maxscreens > 0) {
+                    SetMaxScreens(maxscreens);
+                } else {
+                    UseMsg();
+                }
+            } else {
+                UseMsg();
+            }
+        }
         else if ( strcmp( argv[i], "-maxbigreqsize") == 0) {
              if(++i < argc) {
                  int reqSizeArg = atoi(argv[i]);
Index: programs/Xserver/render/render.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/render/render.c,v
retrieving revision 1.28
diff -u -p -r1.28 render.c
--- programs/Xserver/render/render.c	3 Nov 2003 05:12:02 -0000	1.28
+++ programs/Xserver/render/render.c	8 Mar 2004 21:05:15 -0000
@@ -2321,6 +2321,12 @@ PanoramiXRenderCreatePicture (ClientPtr 
     if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
 	return BadAlloc;
     newPict->type = XRT_PICTURE;
+    newPict->info = NULL;
+    MAXSCREENSALLOC(newPict->info);
+    if (!newPict->info) {
+        xfree(newPict);
+        return BadAlloc;
+    }
     newPict->info[0].id = stuff->pid;
     
     if (refDraw->type == XRT_WINDOW &&
@@ -2343,8 +2349,10 @@ PanoramiXRenderCreatePicture (ClientPtr 
 
     if (result == Success)
 	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
-    else 
-	xfree(newPict);
+    else {
+        xfree(newPict->info);
+        xfree(newPict);
+    }
 
     return (result);
 }


More information about the xorg-devel mailing list