[PATCH 1/2] dix: make screens structures run-time adjustable

Tiago Vignatti tiago.vignatti at nokia.com
Mon Apr 12 07:54:26 PDT 2010


It puts all global variables to be allocated inside AddScreen and whenever
a new driver is set up, these variables are reallocated. It's one step further
to the complete dynamically screens allocations.

An approach similar, defining MAXSCREENS in the the command line, was done by 
Rik Faith and James Antill. Kevin Martin rebased such work against XFree86,
back in 2005:
    https://bugs.freedesktop.org/show_bug.cgi?id=3876
    https://bugs.freedesktop.org/attachment.cgi?id=5708

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         |   10 +++-
 dix/dispatch.c        |   40 +++++++++++++++-
 dix/events.c          |    2 +
 dix/globals.c         |    6 +-
 dix/main.c            |    5 ++-
 dix/window.c          |    2 +-
 fb/fbcmap.c           |   11 +++-
 include/cursor.h      |    2 +-
 include/dixstruct.h   |    1 -
 include/globals.h     |    4 +-
 include/inputstr.h    |    2 +-
 include/misc.h        |   38 ++++++++++++++-
 include/scrnintstr.h  |    3 +-
 include/windowstr.h   |    2 +-
 mi/micmap.c           |    4 +-
 mi/micmap.h           |    2 +-
 render/render.c       |   10 ++++-
 21 files changed, 228 insertions(+), 53 deletions(-)

diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index cfeba01..8bce2cd 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, screenInfo.numScreens);
+
     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, screenInfo.numScreens);
     defmap = xalloc(sizeof(PanoramiXRes));
     defmap->type = XRT_COLORMAP;
+    defmap->info = NULL; /* NOTE above alloc unchecked */
+    MAXSCREENSALLOC_FATAL(defmap->info, screenInfo.numScreens);
     saver = xalloc(sizeof(PanoramiXRes));
     saver->type = XRT_WINDOW;
+    saver->info = NULL; /* NOTE above alloc unchecked */
+    MAXSCREENSALLOC_FATAL(saver->info, screenInfo.numScreens);
 
     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..ea24123 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, screenInfo.numScreens);
+    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, screenInfo.numScreens);
+    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, screenInfo.numScreens);
+    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, screenInfo.numScreens, 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, screenInfo.numScreens, 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, screenInfo.numScreens, 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, screenInfo.numScreens, 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, screenInfo.numScreens);
+    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, screenInfo.numScreens);
+    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..5caa036 100644
--- a/Xext/xvdisp.c
+++ b/Xext/xvdisp.c
@@ -1860,17 +1860,19 @@ 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, screenInfo.numScreens);
+
    for(i = 0; i < xvsp0->nAdaptors; i++) {
       refAdapt = xvsp0->pAdaptors + i;
 
-      bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+      bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * screenInfo.numScreens);
       
       MatchingAdaptors[0] = refAdapt;
    
@@ -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, screenInfo.numScreens);
 	 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/dispatch.c b/dix/dispatch.c
index 982c808..491c5c9 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3975,6 +3975,41 @@ static int indexForScanlinePad[ 65 ] = {
 	 3		/* 64 bits per scanline pad unit */
 };
 
+static void
+ReallocGlobals (void)
+{
+    DDXPointRec         *dixScreenOriginsNew;
+    int                 *cursorScreenDevPrivNew;
+    ScreenSaverStuffRec *savedScreenInfoNew;
+    ScreenPtr           *screensNew;
+	WindowPtr           *WindowTableNew;
+
+    /* We have to guarantee that these global variables bellow are initialized
+     * as NULL then realloc can performs just a malloc when called for the
+     * first time on them. */
+    if (serverGeneration == 1) {
+	dixScreenOriginsNew = xrealloc(dixScreenOrigins,
+            (screenInfo.numScreens + 1) * sizeof(DDXPointRec));
+	cursorScreenDevPrivNew = xrealloc(cursorScreenDevPriv,
+            (screenInfo.numScreens + 1) * sizeof(int));
+	savedScreenInfoNew = xrealloc(savedScreenInfo,
+            (screenInfo.numScreens + 1) * sizeof(ScreenSaverStuffRec));
+	screensNew = xrealloc(screenInfo.screens,
+            (screenInfo.numScreens + 1) * sizeof(struct _Screen));
+
+	dixScreenOrigins = dixScreenOriginsNew;
+	cursorScreenDevPriv = cursorScreenDevPrivNew;
+	savedScreenInfo = savedScreenInfoNew;
+	screenInfo.screens = screensNew;
+
+	cursorScreenDevPriv[screenInfo.numScreens] = 0;
+    }
+
+    WindowTableNew = xrealloc(WindowTable,
+			(screenInfo.numScreens + 1) * sizeof(WindowRec));
+    WindowTable = WindowTableNew;
+}
+
 /*
 	grow the array of screenRecs if necessary.
 	call the device-supplied initialization procedure
@@ -4000,8 +4035,6 @@ AddScreen(
     ScreenPtr pScreen;
 
     i = screenInfo.numScreens;
-    if (i == MAXSCREENS)
-	return -1;
 
     pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec));
     if (!pScreen)
@@ -4056,6 +4089,9 @@ AddScreen(
        multiple screens.
     */
     pScreen->rgf = ~0L;  /* there are no scratch GCs yet*/
+
+    ReallocGlobals();
+
     WindowTable[i] = NullWindow;
     screenInfo.screens[i] = pScreen;
     screenInfo.numScreens++;
diff --git a/dix/events.c b/dix/events.c
index 6541652..026b53c 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2945,6 +2945,8 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
         DeviceIntPtr it;
 
         pDev->spriteInfo->sprite = (SpritePtr)xcalloc(1, sizeof(SpriteRec));
+        MAXSCREENSALLOC_FATAL(pDev->spriteInfo->sprite->windows,
+                              screenInfo.numScreens);
         if (!pDev->spriteInfo->sprite)
             FatalError("InitializeSprite: failed to allocate sprite struct");
 
diff --git a/dix/globals.c b/dix/globals.c
index c24a94f..2964666 100644
--- a/dix/globals.c
+++ b/dix/globals.c
@@ -83,7 +83,7 @@ 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 +125,7 @@ CursorPtr rootCursor;
 Bool party_like_its_1989 = FALSE;
 Bool whiteRoot = FALSE;
 
-int cursorScreenDevPriv[MAXSCREENS];
+int *cursorScreenDevPriv = NULL;
 
 TimeStamp currentTime;
 TimeStamp lastDeviceEventTime;
@@ -138,4 +138,4 @@ char *ConnectionInfo;
 
 CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
 
-DDXPointRec dixScreenOrigins[MAXSCREENS];
+DDXPointRec *dixScreenOrigins = NULL;
diff --git a/dix/main.c b/dix/main.c
index f023536..6e34c72 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -172,6 +172,7 @@ int main(int argc, char *argv[], char *envp[])
 	OsInit();
 	if(serverGeneration == 1)
 	{
+	    screenInfo.screens = NULL;
 	    CreateWellKnownSockets();
 	    InitProcVectors();
 	    for (i=1; i<MAXCLIENTS; i++)
@@ -190,7 +191,6 @@ int main(int argc, char *argv[], char *envp[])
 	    FatalError("couldn't init server resources");
 
 	SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
-	screenInfo.arraySize = MAXSCREENS;
 	screenInfo.numScreens = 0;
 
 	InitAtoms();
@@ -320,6 +320,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..2192575 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 = NULL;
 
 static int FocusPrivatesKeyIndex;
 DevPrivateKey FocusPrivatesKey = &FocusPrivatesKeyIndex;
diff --git a/fb/fbcmap.c b/fb/fbcmap.c
index 2ff3234..28f9ed1 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, screenInfo.numScreens);
     *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, screenInfo.numScreens);
+    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, screenInfo.numScreens);
+    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..01c085e 100644
--- a/include/globals.h
+++ b/include/globals.h
@@ -19,11 +19,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..80f8c65 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -80,9 +80,41 @@ OF THIS SOFTWARE.
 
 #include <stddef.h>
 
-#ifndef MAXSCREENS
-#define MAXSCREENS	16
-#endif
+#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 = xalloc((size) * sizeof(*(o)));                 \
+            if (!o && fatal) FatalError(MAXSCREEN_FAILED_TXT #o);       \
+        }                                                               \
+    } while (0)
+#define _MAXSCREENSALLOCR(o,size,retval)                                \
+    do {                                                                \
+        if (!o) {                                                       \
+            o = xalloc((size) * sizeof(*(o)));                 \
+            if (!o) return retval;                                      \
+        }                                                               \
+    } while (0)
+
+#define MAXSCREENSFREE(o)                                               \
+    do {                                                                \
+        if (o) xfree(o);                                                \
+        o = NULL;                                                       \
+    } while (0)
+
+#define MAXSCREENSALLOC(o, size)              _MAXSCREENSALLOCF(o,size,  0)
+#define MAXSCREENSALLOC_FATAL(o, size)        _MAXSCREENSALLOCF(o,size,  1)
+#define MAXSCREENSALLOC_RETURN(o, size, r)    _MAXSCREENSALLOCR(o,size, (r))
+#define MAXSCREENSALLOCPLUSONE(o, size)       _MAXSCREENSALLOCF(o,size+1,0)
+#define MAXSCREENSALLOCPLUSONE_FATAL(o, size) _MAXSCREENSALLOCF(o,size+1,1)
+#define MAXSCREENSCALLOC(o, size, m)          _MAXSCREENSALLOCF(o,size*(m),0)
+#define MAXSCREENSCALLOC_FATAL(o, size, m)    _MAXSCREENSALLOCF(o,size*(m),1)
+
 #define MAXCLIENTS	256
 #define MAXEXTENSIONS   128
 #define MAXFORMATS	8
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index c42119d..4826b5c 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -615,9 +615,8 @@ typedef struct _ScreenInfo {
     int		numPixmapFormats;
     PixmapFormatRec
 		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..cceed92 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, screenInfo.numScreens, 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/render/render.c b/render/render.c
index 2d9e47a..c5e044b 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, screenInfo.numScreens);
+    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