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