[PATCH 1/5] dix: make MAXSCREENS run-time configurable

Tiago Vignatti tiago.vignatti at nokia.com
Thu Apr 8 08:06:33 PDT 2010


Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
---
 Xext/panoramiX.c      |   12 +++++-
 Xext/panoramiX.h      |    2 +-
 Xext/panoramiXprocs.c |  121 +++++++++++++++++++++++++++++++++++++++----------
 Xext/panoramiXsrv.h   |    2 +-
 Xext/xvdisp.c         |    8 +++-
 dix/events.c          |    1 +
 dix/globals.c         |    7 ++-
 dix/main.c            |   47 +++++++++++++++++++
 dix/window.c          |    2 +-
 fb/fbcmap.c           |   11 +++-
 include/cursor.h      |    2 +-
 include/dixstruct.h   |    1 -
 include/globals.h     |    9 +++-
 include/inputstr.h    |    2 +-
 include/misc.h        |   44 +++++++++++++++++-
 include/scrnintstr.h  |    2 +-
 include/windowstr.h   |    2 +-
 mi/micmap.c           |    4 +-
 mi/micmap.h           |    2 +-
 os/utils.c            |   14 ++++++
 render/render.c       |   10 ++++-
 21 files changed, 257 insertions(+), 48 deletions(-)

diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index cfeba01..7d1b849 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -122,7 +122,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);
@@ -330,6 +330,8 @@ XineramaDestroyClip(GCPtr pGC)
 int
 XineramaDeleteResource(pointer data, XID id)
 {
+    PanoramiXRes *res = (PanoramiXRes *)data;
+    MAXSCREENSFREE(res->info);
     xfree(data);
     return 1;
 }
@@ -456,6 +458,8 @@ void PanoramiXExtensionInit(int argc, char *argv[])
     if (noPanoramiXExtension) 
 	return;
 
+    MAXSCREENSALLOC_FATAL(XineramaScreenRegions);
+
     PanoramiXNumScreens = screenInfo.numScreens;
     if (PanoramiXNumScreens == 1) {		/* Only 1 screen 	*/
 	noPanoramiXExtension = TRUE;
@@ -829,10 +833,16 @@ PanoramiXConsolidate(void)
 
     root = xalloc(sizeof(PanoramiXRes));
     root->type = XRT_WINDOW;
+    root->info = NULL; /* NOTE above alloc unchecked */
+    MAXSCREENSALLOC_FATAL(root->info);
     defmap = xalloc(sizeof(PanoramiXRes));
     defmap->type = XRT_COLORMAP;
+    defmap->info = NULL; /* NOTE above alloc unchecked */
+    MAXSCREENSALLOC_FATAL(defmap->info);
     saver = 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;
diff --git a/Xext/panoramiX.h b/Xext/panoramiX.h
index cca4c52..5d8926d 100644
--- a/Xext/panoramiX.h
+++ b/Xext/panoramiX.h
@@ -58,7 +58,7 @@ typedef struct _PanoramiXInfo {
 } PanoramiXInfo;
 
 typedef struct {
-    PanoramiXInfo info[MAXSCREENS];
+    PanoramiXInfo *info;
     RESTYPE type;
     union {
 	struct {
diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
index 6834efb..fef52e1 100644
--- a/Xext/panoramiXprocs.c
+++ b/Xext/panoramiXprocs.c
@@ -124,6 +124,13 @@ int PanoramiXCreateWindow(ClientPtr client)
         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;
@@ -159,8 +166,10 @@ int PanoramiXCreateWindow(ClientPtr client)
 
     if (result == Success)
         AddResource(newWin->info[0].id, XRT_WINDOW, newWin);
-    else 
+    else {
+        MAXSCREENSFREE(newWin->info);
         xfree(newWin);
+    }
 
     return (result);
 }
@@ -670,6 +679,12 @@ int PanoramiXCreatePixmap(ClientPtr client)
 	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++)
@@ -684,8 +699,10 @@ int PanoramiXCreatePixmap(ClientPtr client)
 
     if (result == Success)
 	AddResource(newPix->info[0].id, XRT_PIXMAP, newPix);
-    else 
-	xfree(newPix);
+    else {
+        MAXSCREENSFREE(newPix->info);
+        xfree(newPix);
+    }
 
     return (result);
 }
@@ -775,6 +792,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);
@@ -794,8 +817,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);
 }
@@ -1050,12 +1075,14 @@ 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;
 	DrawablePtr pDst;
 	GCPtr pGC;
         char *data;
 	int pitch, rc;
 
+    MAXSCREENSALLOC_RETURN(drawables, BadAlloc);
+
 	FOR_NSCREENS(j) {
 	    rc = dixLookupDrawable(drawables+j, src->info[j].id, client, 0,
 				   DixGetAttrAccess);
@@ -1064,8 +1091,10 @@ int PanoramiXCopyArea(ClientPtr 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, 
@@ -1076,6 +1105,7 @@ int PanoramiXCopyArea(ClientPtr client)
 	    VALIDATE_DRAWABLE_AND_GC(dst->info[j].id, pDst, DixWriteAccess);
 	    if(drawables[0]->depth != pDst->depth) {
 		client->errorValue = stuff->dstDrawable;
+        MAXSCREENSFREE(drawables);
 		xfree(data);
 		return (BadMatch);
 	    }
@@ -1087,15 +1117,18 @@ 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;
 	int rc;
 
+    MAXSCREENSALLOC_RETURN(pRgn, BadAlloc);
+
 	FOR_NSCREENS_BACKWARD(j) {
 	    stuff->dstDrawable = dst->info[j].id;
 	    stuff->srcDrawable = src->info[j].id;
@@ -1120,6 +1153,7 @@ int PanoramiXCopyArea(ClientPtr client)
 		if ((pDst->pScreen != pSrc->pScreen) || 
 		    (pDst->depth != pSrc->depth)) {
 			client->errorValue = stuff->dstDrawable;
+            MAXSCREENSFREE(pRgn);
 			return (BadMatch);
    		}
  	    } else
@@ -1157,7 +1191,9 @@ int PanoramiXCopyArea(ClientPtr client)
 		client, &totalReg, stuff->dstDrawable, X_CopyArea, 0);
 	    REGION_UNINIT(pScreen, &totalReg);
 	}
-	
+
+    MAXSCREENSFREE(pRgn);
+
 	result = client->noClientException;
     }
 
@@ -1174,32 +1210,42 @@ int PanoramiXCopyPlane(ClientPtr client)
     Bool		srcShared, dstShared;
     DrawablePtr 	psrcDraw, pdstDraw = NULL;
     GCPtr 		pGC = NULL;
-    RegionPtr 		pRgn[MAXSCREENS];
+    RegionPtr		*pRgn;
     REQUEST(xCopyPlaneReq);
 
     REQUEST_SIZE_MATCH(xCopyPlaneReq);
 
+    MAXSCREENSALLOC_RETURN(pRgn, BadAlloc);
+
     rc = dixLookupResourceByClass((pointer *)&src, stuff->srcDrawable,
 				  XRC_DRAWABLE, client, DixReadAccess);
-    if (rc != Success)
-	return (rc == BadValue) ? BadDrawable : rc;
+    if (rc != Success) {
+        MAXSCREENSFREE(pRgn);
+        return (rc == BadValue) ? BadDrawable : rc;
+    }
 
     srcShared = IS_SHARED_PIXMAP(src);
 
     rc = dixLookupResourceByClass((pointer *)&dst, stuff->dstDrawable,
 				  XRC_DRAWABLE, client, DixWriteAccess);
-    if (rc != Success)
-	return (rc == BadValue) ? BadDrawable : rc;
+    if (rc != Success) {
+        MAXSCREENSFREE(pRgn);
+        return (rc == BadValue) ? BadDrawable : rc;
+    }
 
     dstShared = IS_SHARED_PIXMAP(dst);
 
-    if(dstShared && srcShared)
-	return (* SavedProcVector[X_CopyPlane])(client);
+    if(dstShared && srcShared) {
+        MAXSCREENSFREE(pRgn);
+        return (* SavedProcVector[X_CopyPlane])(client);
+    }
 
     rc = dixLookupResourceByType((pointer *)&gc, stuff->gc, XRT_GC,
 				 client, DixReadAccess);
-    if (rc != Success)
-	return (rc == BadValue) ? BadGC : rc;
+    if (rc != Success) {
+        MAXSCREENSFREE(pRgn);
+        return (rc == BadValue) ? BadGC : rc;
+    }
 
     if((dst->type == XRT_WINDOW) && dst->u.win.root)
 	dstIsRoot = TRUE;
@@ -1231,6 +1277,7 @@ int PanoramiXCopyPlane(ClientPtr client)
 
             if (pdstDraw->pScreen != psrcDraw->pScreen) {
 		client->errorValue = stuff->dstDrawable;
+        MAXSCREENSFREE(pRgn);
 		return (BadMatch);
 	    }
 	} else
@@ -1239,6 +1286,7 @@ int PanoramiXCopyPlane(ClientPtr client)
 	if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
 		(stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
 	    client->errorValue = stuff->bitPlane;
+        MAXSCREENSFREE(pRgn);
 	    return(BadValue);
 	}
 
@@ -1271,6 +1319,7 @@ int PanoramiXCopyPlane(ClientPtr client)
 	REGION_UNINIT(pScreen, &totalReg);
     }
 
+    MAXSCREENSFREE(pRgn);
     return (client->noClientException);
 }
 
@@ -1805,7 +1854,7 @@ int PanoramiXPutImage(ClientPtr client)
 
 int PanoramiXGetImage(ClientPtr client)
 {
-    DrawablePtr 	drawables[MAXSCREENS];
+    DrawablePtr 	*drawables;
     DrawablePtr 	pDraw;
     PanoramiXRes	*draw;
     xGetImageReply	xgi;
@@ -1869,12 +1918,15 @@ int PanoramiXGetImage(ClientPtr client)
 	    return(BadMatch);
     }
 
+    MAXSCREENSALLOC_RETURN(drawables, BadAlloc);
     drawables[0] = pDraw;
     for(i = 1; i < PanoramiXNumScreens; i++) {
 	rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0,
 			       DixGetAttrAccess);
-	if (rc != Success)
-	    return rc;
+	if (rc != Success) {
+        MAXSCREENSFREE(drawables);
+        return rc;
+	}
     }
 
     xgi.visual = wVisual (((WindowPtr) pDraw));
@@ -1907,8 +1959,10 @@ int PanoramiXGetImage(ClientPtr client)
 	    linesPerBuf = h;
     }
     length = linesPerBuf * widthBytesLine;
-    if(!(pBuf = xalloc(length)))
-	return (BadAlloc);
+    if(!(pBuf = xalloc(length))) {
+        MAXSCREENSFREE(drawables);
+        return (BadAlloc);
+    }
 
     WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
 
@@ -1953,6 +2007,7 @@ int PanoramiXGetImage(ClientPtr client)
             }
 	}
     }
+    MAXSCREENSFREE(drawables);
     xfree(pBuf);
     return (client->noClientException);
 }
@@ -2144,6 +2199,13 @@ int PanoramiXCreateColormap(ClientPtr client)
     if(!(newCmap = 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;
     for(j = 1; j < PanoramiXNumScreens; j++)
@@ -2160,8 +2222,10 @@ int PanoramiXCreateColormap(ClientPtr client)
  
     if (result == Success)
         AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
-    else 
+    else {
+        MAXSCREENSFREE(newCmap->info);
         xfree(newCmap);
+    }
 
     return (result);
 }
@@ -2215,6 +2279,13 @@ PanoramiXCopyColormapAndFree(ClientPtr client)
     if(!(newCmap = 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;
     for(j = 1; j < PanoramiXNumScreens; j++)
@@ -2229,8 +2300,10 @@ PanoramiXCopyColormapAndFree(ClientPtr client)
 
     if (result == Success)
         AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
-    else 
+    else {
+        MAXSCREENSFREE(newCmap->info);
         xfree(newCmap);
+    }
 
     return (result);
 }
diff --git a/Xext/panoramiXsrv.h b/Xext/panoramiXsrv.h
index c77b119..2288508 100644
--- a/Xext/panoramiXsrv.h
+++ b/Xext/panoramiXsrv.h
@@ -22,7 +22,7 @@ extern _X_EXPORT int XineramaDeleteResource(pointer, XID);
 
 extern _X_EXPORT void XineramaReinitData(ScreenPtr);
 
-extern _X_EXPORT RegionRec XineramaScreenRegions[MAXSCREENS];
+extern _X_EXPORT RegionRec *XineramaScreenRegions;
 
 extern _X_EXPORT unsigned long XRC_DRAWABLE;
 extern _X_EXPORT unsigned long XRT_WINDOW;
diff --git a/Xext/xvdisp.c b/Xext/xvdisp.c
index b6fc34f..60088d3 100644
--- a/Xext/xvdisp.c
+++ b/Xext/xvdisp.c
@@ -1860,13 +1860,15 @@ void XineramifyXv(void)
    XvScreenPtr xvsp;
    Bool isOverlay, hasOverlay;
    PanoramiXRes *port;
-   XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+   XvAdaptorPtr *MatchingAdaptors;
    int i, j, k, l;
 
    XvXRTPort = CreateNewResourceType(XineramaDeleteResource, "XvXRTPort");
 
    if (!xvsp0 || !XvXRTPort) return;
 
+   MAXSCREENSALLOC_FATAL(MatchingAdaptors);
+
    for(i = 0; i < xvsp0->nAdaptors; i++) {
       refAdapt = xvsp0->pAdaptors + i;
 
@@ -1945,6 +1947,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);
 
@@ -1964,6 +1968,8 @@ void XineramifyXv(void)
    XvProcVector[xv_SetPortAttribute]	= XineramaXvSetPortAttribute;
    XvProcVector[xv_PutImage]		= XineramaXvPutImage;
    XvProcVector[xv_ShmPutImage]		= XineramaXvShmPutImage;
+
+   MAXSCREENSFREE(MatchingAdaptors);
 }
 #endif /* PANORAMIX */
 
diff --git a/dix/events.c b/dix/events.c
index 6541652..7d19424 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2945,6 +2945,7 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
         DeviceIntPtr it;
 
         pDev->spriteInfo->sprite = (SpritePtr)xcalloc(1, sizeof(SpriteRec));
+        MAXSCREENSALLOC_FATAL(pDev->spriteInfo->sprite->windows);
         if (!pDev->spriteInfo->sprite)
             FatalError("InitializeSprite: failed to allocate sprite struct");
 
diff --git a/dix/globals.c b/dix/globals.c
index c24a94f..0158b2d 100644
--- a/dix/globals.c
+++ b/dix/globals.c
@@ -78,12 +78,13 @@ PtrCtrl defaultPointerControl = {
 	DEFAULT_PTR_THRESHOLD,
 	0};
 
+int        MAXSCREENS;
 ClientPtr  clients[MAXCLIENTS];
 ClientPtr  serverClient;
 int  currentMaxClients;   /* current size of clients array */
 long maxBigRequestSize = MAX_BIG_REQUEST_SIZE;
 
-WindowPtr WindowTable[MAXSCREENS];
+WindowPtr *WindowTable;
 
 unsigned long globalSerialNumber = 0;
 unsigned long serverGeneration = 0;
@@ -125,7 +126,7 @@ CursorPtr rootCursor;
 Bool party_like_its_1989 = FALSE;
 Bool whiteRoot = FALSE;
 
-int cursorScreenDevPriv[MAXSCREENS];
+int *cursorScreenDevPriv;
 
 TimeStamp currentTime;
 TimeStamp lastDeviceEventTime;
@@ -138,4 +139,4 @@ char *ConnectionInfo;
 
 CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
 
-DDXPointRec dixScreenOrigins[MAXSCREENS];
+DDXPointRec *dixScreenOrigins;
diff --git a/dix/main.c b/dix/main.c
index f023536..edd66a1 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -120,6 +120,44 @@ extern void Dispatch(void);
 
 extern void InitProcVectors(void);
 
+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(cursorScreenDevPriv);
+    MAXSCREENSALLOC_FATAL(savedScreenInfo);
+    MAXSCREENSALLOC_FATAL(screenInfo.screens);
+}
+
 #ifdef XQUARTZ
 #include <pthread.h>
 
@@ -151,6 +189,8 @@ int main(int argc, char *argv[], char *envp[])
 
     ProcessCommandLine(argc, argv);
 
+    InitGlobals();
+
     alwaysCheckForInput[0] = 0;
     alwaysCheckForInput[1] = 1;
     while(1)
@@ -193,6 +233,10 @@ int main(int argc, char *argv[], char *envp[])
 	screenInfo.arraySize = MAXSCREENS;
 	screenInfo.numScreens = 0;
 
+	MAXSCREENSALLOC(WindowTable);
+	if (!WindowTable)
+	    FatalError("couldn't create root window table");
+
 	InitAtoms();
 	InitEvents();
 	InitSelections();
@@ -320,6 +364,9 @@ int main(int argc, char *argv[], char *envp[])
 	    xfree(screenInfo.screens[i]);
 	    screenInfo.numScreens = i;
 	}
+
+	xfree(WindowTable);
+	WindowTable = NULL;
 	FreeFonts();
 
 	FreeAuditTimer();
diff --git a/dix/window.c b/dix/window.c
index c7201df..6237188 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -151,7 +151,7 @@ WindowSeekDeviceCursor(WindowPtr pWin,
 
 int screenIsSaved = SCREEN_SAVER_OFF;
 
-ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+ScreenSaverStuffRec *savedScreenInfo;
 
 static int FocusPrivatesKeyIndex;
 DevPrivateKey FocusPrivatesKey = &FocusPrivatesKeyIndex;
diff --git a/fb/fbcmap.c b/fb/fbcmap.c
index 2ff3234..3b0d1f4 100644
--- a/fb/fbcmap.c
+++ b/fb/fbcmap.c
@@ -38,13 +38,14 @@
 
 
 
-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)
diff --git a/include/cursor.h b/include/cursor.h
index acc95c3..e9a79d2 100644
--- a/include/cursor.h
+++ b/include/cursor.h
@@ -64,7 +64,7 @@ struct _DeviceIntRec;
 typedef struct _Cursor *CursorPtr;
 typedef struct _CursorMetric *CursorMetricPtr;
 
-extern _X_EXPORT int cursorScreenDevPriv[MAXSCREENS];
+extern _X_EXPORT int *cursorScreenDevPriv;
 #define CursorScreenKey(pScreen) (cursorScreenDevPriv + (pScreen)->myNum)
 
 extern _X_EXPORT CursorPtr rootCursor;
diff --git a/include/dixstruct.h b/include/dixstruct.h
index 696b793..2a2317a 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -101,7 +101,6 @@ typedef struct _Client {
 					 * killed */
     SaveSetElt	*saveSet;
     int         numSaved;
-    void	*unused_screenPrivate[16];
     int         (**requestVector) (
 		ClientPtr /* pClient */);
     CARD32	req_len;		/* length of current request */
diff --git a/include/globals.h b/include/globals.h
index 82e86c3..32e05ac 100644
--- a/include/globals.h
+++ b/include/globals.h
@@ -6,6 +6,11 @@
 
 /* Global X server variables that are visible to mi, dix, os, and ddx */
 
+extern _X_EXPORT int    MAXSCREENS;
+extern _X_EXPORT void   *MaxScreensAlloc(unsigned long size);
+extern _X_EXPORT void   MaxScreensFree(void *object);
+extern _X_EXPORT void   SetMaxScreens(int maxscreens);
+
 extern _X_EXPORT CARD32 defaultScreenSaverTime;
 extern _X_EXPORT CARD32 defaultScreenSaverInterval;
 extern _X_EXPORT CARD32 ScreenSaverTime;
@@ -19,11 +24,11 @@ extern _X_EXPORT char *defaultFontPath;
 extern _X_EXPORT int monitorResolution;
 extern _X_EXPORT int defaultColorVisualClass;
 
-extern _X_EXPORT WindowPtr WindowTable[MAXSCREENS];
+extern _X_EXPORT WindowPtr *WindowTable;
 extern _X_EXPORT int GrabInProgress;
 extern _X_EXPORT Bool noTestExtensions;
 
-extern _X_EXPORT DDXPointRec dixScreenOrigins[MAXSCREENS];
+extern _X_EXPORT DDXPointRec *dixScreenOrigins;
 
 extern _X_EXPORT char *ConnectionInfo;
 
diff --git a/include/inputstr.h b/include/inputstr.h
index de4026c..8f2899b 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -374,7 +374,7 @@ typedef 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
     /* The window trace information is used at dix/events.c to avoid having
diff --git a/include/misc.h b/include/misc.h
index 62d813e..0c80ab7 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -80,9 +80,47 @@ OF THIS SOFTWARE.
 
 #include <stddef.h>
 
-#ifndef MAXSCREENS
-#define MAXSCREENS	16
-#endif
+#define MAXSCREENSDEFAULT 16
+
+/* 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 MAXEXTENSIONS   128
 #define MAXFORMATS	8
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index c42119d..df64ac1 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -617,7 +617,7 @@ typedef struct _ScreenInfo {
 		formats[MAXFORMATS];
     int		arraySize;
     int		numScreens;
-    ScreenPtr	screens[MAXSCREENS];
+    ScreenPtr	*screens;
     int		unused;
 } ScreenInfo;
 
diff --git a/include/windowstr.h b/include/windowstr.h
index 96bee9b..1c90410 100644
--- a/include/windowstr.h
+++ b/include/windowstr.h
@@ -222,6 +222,6 @@ typedef struct _ScreenSaverStuff {
 #define HasSaverWindow(i)   (savedScreenInfo[i].pWindow != NullWindow)
 
 extern _X_EXPORT int screenIsSaved;
-extern _X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+extern _X_EXPORT ScreenSaverStuffRec *savedScreenInfo;
 
 #endif /* WINDOWSTRUCT_H */
diff --git a/mi/micmap.c b/mi/micmap.c
index e832be7..d506e3f 100644
--- a/mi/micmap.c
+++ b/mi/micmap.c
@@ -40,7 +40,7 @@
 #include "globals.h"
 #include "micmap.h"
 
-ColormapPtr miInstalledMaps[MAXSCREENS];
+ColormapPtr *miInstalledMaps;
 
 int
 miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
@@ -512,6 +512,8 @@ miInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
     int		*preferredCVCs, *prefp;
     int		first_depth;
 
+    MAXSCREENSALLOC_RETURN(miInstalledMaps, FALSE);
+
     /* none specified, we'll guess from pixmap formats */
     if (!miVisuals) 
     {
diff --git a/mi/micmap.h b/mi/micmap.h
index 5c8448a..5e12502 100644
--- a/mi/micmap.h
+++ b/mi/micmap.h
@@ -4,7 +4,7 @@
 #ifndef _MICMAP_H_
 #define _MICMAP_H_
 
-extern _X_EXPORT ColormapPtr miInstalledMaps[MAXSCREENS];
+extern _X_EXPORT ColormapPtr *miInstalledMaps;
 
 typedef Bool (* miInitVisualsProcPtr)(VisualPtr *, DepthPtr *, int *, int *,
 					int *, VisualID *, unsigned long, int,
diff --git a/os/utils.c b/os/utils.c
index 127b47b..500855f 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -506,6 +506,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("-noreset               don't reset after last client exists\n");
     ErrorF("-reset                 reset after last client exists\n");
@@ -847,6 +848,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], "-wr") == 0)
             whiteRoot = TRUE;
         else if ( strcmp( argv[i], "-maxbigreqsize") == 0) {
diff --git a/render/render.c b/render/render.c
index 2d9e47a..3c29b33 100644
--- a/render/render.c
+++ b/render/render.c
@@ -2693,6 +2693,12 @@ PanoramiXRenderCreatePicture (ClientPtr client)
     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 &&
@@ -2715,8 +2721,10 @@ PanoramiXRenderCreatePicture (ClientPtr client)
 
     if (result == Success)
 	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
-    else 
+    else {
+	xfree(newPict->info);
 	xfree(newPict);
+    }
 
     return (result);
 }
-- 
1.6.0.4



More information about the xorg-devel mailing list