---
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.

This is my first server patch, so review gratefully accepted.

 Xext/shm.c |   60 ++++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/Xext/shm.c b/Xext/shm.c
index a6f804c..66a4db4 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -99,6 +99,11 @@ typedef struct _ShmDesc {
     unsigned long size;
 } ShmDescRec, *ShmDescPtr;
 
+typedef struct _ShmScrPrivateRec {
+    ShmFuncsPtr shmFuncs;
+    DestroyPixmapProcPtr destroyPixmap;
+} ShmScrPrivateRec;
+
 static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
 static int ShmDetachSegment(
     pointer            /* value */,
@@ -135,13 +140,16 @@ int BadShmSegCode;
 RESTYPE ShmSegType;
 static ShmDescPtr Shmsegs;
 static Bool sharedPixmaps;
-static ShmFuncsPtr shmFuncs[MAXSCREENS];
-static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+static DrawablePtr *drawables;
+static int shmScrPrivateKeyIndex;
+static DevPrivateKey shmScrPrivateKey = &shmScrPrivateKeyIndex;
 static int shmPixmapPrivateIndex;
 static DevPrivateKey shmPixmapPrivate = &shmPixmapPrivateIndex;
 static ShmFuncs miFuncs = {NULL, NULL};
 static ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL};
 
+#define ShmGetScreenPriv(s) ((ShmScrPrivateRec 
*)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey))
+
 #define VERIFY_SHMSEG(shmseg,shmdesc,client) \
 { \
     int rc; \
@@ -226,20 +234,34 @@ ShmExtensionInit(INITARGS)
     }
 #endif
 
+    drawables = xcalloc(screenInfo.numScreens, sizeof(DrawablePtr));
+    if (!drawables)
+    {
+       ErrorF("MIT-SHM extension disabled: no memory for per-screen 
drawables\n");
+       return;
+    }
+
     sharedPixmaps = xFalse;
     {
       sharedPixmaps = xTrue;
       for (i = 0; i < screenInfo.numScreens; i++)
       {
-       if (!shmFuncs[i])
-           shmFuncs[i] = &miFuncs;
-       if (!shmFuncs[i]->CreatePixmap)
+       ShmScrPrivateRec *priv = ShmGetScreenPriv(screenInfo.screens[i]);
+       if (!priv)
+       {
+           priv = xcalloc (1, sizeof (ShmScrPrivateRec));
+           dixSetPrivate(&screenInfo.screens[i]->devPrivates, 
shmScrPrivateKey, priv);
+       }
+       if (!priv->shmFuncs)
+           priv->shmFuncs = &miFuncs;
+       if (!priv->shmFuncs->CreatePixmap)
            sharedPixmaps = xFalse;
       }
       if (sharedPixmaps)
        for (i = 0; i < screenInfo.numScreens; i++)
        {
-           destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+           ShmScrPrivateRec *priv = ShmGetScreenPriv(screenInfo.screens[i]);
+           priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap;
            screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
        }
     }
@@ -261,23 +283,21 @@ static void
 ShmResetProc(ExtensionEntry *extEntry)
 {
     int i;
-
-    for (i = 0; i < MAXSCREENS; i++)
-    {
-       shmFuncs[i] = NULL;
-    }
+    for (i = 0; i < screenInfo.numScreens; i++)
+       ShmRegisterFuncs(screenInfo.screens[i], NULL);
 }
 
 void
 ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs)
 {
-    shmFuncs[pScreen->myNum] = funcs;
+    ShmGetScreenPriv(pScreen)->shmFuncs = funcs;
 }
 
 static Bool
 ShmDestroyPixmap (PixmapPtr pPixmap)
 {
     ScreenPtr      pScreen = pPixmap->drawable.pScreen;
+    ShmScrPrivateRec *priv;
     Bool           ret;
     if (pPixmap->refcnt == 1)
     {
@@ -288,9 +308,10 @@ ShmDestroyPixmap (PixmapPtr pPixmap)
            ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
     }
     
-    pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+    priv = ShmGetScreenPriv(pScreen);
+    pScreen->DestroyPixmap = priv->destroyPixmap;
     ret = (*pScreen->DestroyPixmap) (pPixmap);
-    destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+    priv->destroyPixmap = pScreen->DestroyPixmap;
     pScreen->DestroyPixmap = ShmDestroyPixmap;
     return ret;
 }
@@ -298,7 +319,7 @@ ShmDestroyPixmap (PixmapPtr pPixmap)
 void
 ShmRegisterFbFuncs(ScreenPtr pScreen)
 {
-    shmFuncs[pScreen->myNum] = &fbFuncs;
+    ShmRegisterFuncs(pScreen, &fbFuncs);
 }
 
 static int
@@ -578,7 +599,6 @@ static int
 ProcPanoramiXShmGetImage(ClientPtr client)
 {
     PanoramiXRes       *draw;
-    DrawablePtr        drawables[MAXSCREENS];
     DrawablePtr        pDraw;
     xShmGetImageReply  xgi;
     ShmDescPtr         shmdesc;
@@ -767,9 +787,11 @@ CreatePmap:
     result = (client->noClientException);
 
     FOR_NSCREENS(j) {
+       ShmScrPrivateRec *priv;
        pScreen = screenInfo.screens[j];
 
-       pMap = (*shmFuncs[j]->CreatePixmap)(pScreen, 
+       priv = ShmGetScreenPriv(pScreen);
+       pMap = (*priv->shmFuncs->CreatePixmap)(pScreen,
                                stuff->width, stuff->height, stuff->depth,
                                shmdesc->addr + stuff->offset);
 
@@ -1052,6 +1074,7 @@ ProcShmCreatePixmap(ClientPtr client)
     DepthPtr pDepth;
     int i, rc;
     ShmDescPtr shmdesc;
+    ShmScrPrivateRec *priv;
     REQUEST(xShmCreatePixmapReq);
     unsigned int width, height, depth;
     unsigned long size;
@@ -1100,7 +1123,8 @@ CreatePmap:
        return BadAlloc;
 
     VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
-    pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+    priv = ShmGetScreenPriv(pDraw->pScreen);
+    pMap = (*priv->shmFuncs->CreatePixmap)(
                            pDraw->pScreen, stuff->width,
                            stuff->height, stuff->depth,
                            shmdesc->addr + stuff->offset);
-- 
1.6.3.3

_______________________________________________
xorg-devel mailing list
xorg-devel@lists.x.org
http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to