Remove static MAXSCREENS limit from Xext/shm.c

Dynamically allocate per-screen data in the SHM extension, instead of
having a single static-sized array.

Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Daniel Stone <daniel@fooishbar.org>
This commit is contained in:
Jamey Sharp 2009-10-08 13:29:27 +11:00 committed by Daniel Stone
parent 4df3e8c805
commit b422b532f3

View File

@ -99,6 +99,12 @@ typedef struct _ShmDesc {
unsigned long size; unsigned long size;
} ShmDescRec, *ShmDescPtr; } ShmDescRec, *ShmDescPtr;
typedef struct _ShmScrPrivateRec {
CloseScreenProcPtr CloseScreen;
ShmFuncsPtr shmFuncs;
DestroyPixmapProcPtr destroyPixmap;
} ShmScrPrivateRec;
static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS); static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
static int ShmDetachSegment( static int ShmDetachSegment(
pointer /* value */, pointer /* value */,
@ -135,13 +141,16 @@ int BadShmSegCode;
RESTYPE ShmSegType; RESTYPE ShmSegType;
static ShmDescPtr Shmsegs; static ShmDescPtr Shmsegs;
static Bool sharedPixmaps; static Bool sharedPixmaps;
static ShmFuncsPtr shmFuncs[MAXSCREENS]; static DrawablePtr *drawables;
static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS]; static int shmScrPrivateKeyIndex;
static DevPrivateKey shmScrPrivateKey = &shmScrPrivateKeyIndex;
static int shmPixmapPrivateIndex; static int shmPixmapPrivateIndex;
static DevPrivateKey shmPixmapPrivate = &shmPixmapPrivateIndex; static DevPrivateKey shmPixmapPrivate = &shmPixmapPrivateIndex;
static ShmFuncs miFuncs = {NULL, NULL}; static ShmFuncs miFuncs = {NULL, NULL};
static ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL}; static ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL};
#define ShmGetScreenPriv(s) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey))
#define VERIFY_SHMSEG(shmseg,shmdesc,client) \ #define VERIFY_SHMSEG(shmseg,shmdesc,client) \
{ \ { \
int rc; \ int rc; \
@ -212,6 +221,30 @@ static Bool CheckForShmSyscall(void)
#endif #endif
static Bool
ShmCloseScreen(int i, ScreenPtr pScreen)
{
ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
pScreen->CloseScreen = screen_priv->CloseScreen;
dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL);
xfree (screen_priv);
return (*pScreen->CloseScreen) (i, pScreen);
}
static ShmScrPrivateRec *
ShmInitScreenPriv(ScreenPtr pScreen)
{
ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
if (!screen_priv)
{
screen_priv = xcalloc (1, sizeof (ShmScrPrivateRec));
screen_priv->CloseScreen = pScreen->CloseScreen;
dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, screen_priv);
pScreen->CloseScreen = ShmCloseScreen;
}
return screen_priv;
}
void void
ShmExtensionInit(INITARGS) ShmExtensionInit(INITARGS)
{ {
@ -226,20 +259,29 @@ ShmExtensionInit(INITARGS)
} }
#endif #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 = xFalse;
{ {
sharedPixmaps = xTrue; sharedPixmaps = xTrue;
for (i = 0; i < screenInfo.numScreens; i++) for (i = 0; i < screenInfo.numScreens; i++)
{ {
if (!shmFuncs[i]) ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]);
shmFuncs[i] = &miFuncs; if (!screen_priv->shmFuncs)
if (!shmFuncs[i]->CreatePixmap) screen_priv->shmFuncs = &miFuncs;
if (!screen_priv->shmFuncs->CreatePixmap)
sharedPixmaps = xFalse; sharedPixmaps = xFalse;
} }
if (sharedPixmaps) if (sharedPixmaps)
for (i = 0; i < screenInfo.numScreens; i++) for (i = 0; i < screenInfo.numScreens; i++)
{ {
destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap; ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]);
screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap;
screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap; screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
} }
} }
@ -261,23 +303,21 @@ static void
ShmResetProc(ExtensionEntry *extEntry) ShmResetProc(ExtensionEntry *extEntry)
{ {
int i; int i;
for (i = 0; i < screenInfo.numScreens; i++)
for (i = 0; i < MAXSCREENS; i++) ShmRegisterFuncs(screenInfo.screens[i], NULL);
{
shmFuncs[i] = NULL;
}
} }
void void
ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs) ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs)
{ {
shmFuncs[pScreen->myNum] = funcs; ShmInitScreenPriv(pScreen)->shmFuncs = funcs;
} }
static Bool static Bool
ShmDestroyPixmap (PixmapPtr pPixmap) ShmDestroyPixmap (PixmapPtr pPixmap)
{ {
ScreenPtr pScreen = pPixmap->drawable.pScreen; ScreenPtr pScreen = pPixmap->drawable.pScreen;
ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
Bool ret; Bool ret;
if (pPixmap->refcnt == 1) if (pPixmap->refcnt == 1)
{ {
@ -288,9 +328,9 @@ ShmDestroyPixmap (PixmapPtr pPixmap)
ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id); ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
} }
pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum]; pScreen->DestroyPixmap = screen_priv->destroyPixmap;
ret = (*pScreen->DestroyPixmap) (pPixmap); ret = (*pScreen->DestroyPixmap) (pPixmap);
destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap; screen_priv->destroyPixmap = pScreen->DestroyPixmap;
pScreen->DestroyPixmap = ShmDestroyPixmap; pScreen->DestroyPixmap = ShmDestroyPixmap;
return ret; return ret;
} }
@ -298,7 +338,7 @@ ShmDestroyPixmap (PixmapPtr pPixmap)
void void
ShmRegisterFbFuncs(ScreenPtr pScreen) ShmRegisterFbFuncs(ScreenPtr pScreen)
{ {
shmFuncs[pScreen->myNum] = &fbFuncs; ShmRegisterFuncs(pScreen, &fbFuncs);
} }
static int static int
@ -578,7 +618,6 @@ static int
ProcPanoramiXShmGetImage(ClientPtr client) ProcPanoramiXShmGetImage(ClientPtr client)
{ {
PanoramiXRes *draw; PanoramiXRes *draw;
DrawablePtr drawables[MAXSCREENS];
DrawablePtr pDraw; DrawablePtr pDraw;
xShmGetImageReply xgi; xShmGetImageReply xgi;
ShmDescPtr shmdesc; ShmDescPtr shmdesc;
@ -767,9 +806,11 @@ CreatePmap:
result = (client->noClientException); result = (client->noClientException);
FOR_NSCREENS(j) { FOR_NSCREENS(j) {
ShmScrPrivateRec *screen_priv;
pScreen = screenInfo.screens[j]; pScreen = screenInfo.screens[j];
pMap = (*shmFuncs[j]->CreatePixmap)(pScreen, screen_priv = ShmGetScreenPriv(pScreen);
pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen,
stuff->width, stuff->height, stuff->depth, stuff->width, stuff->height, stuff->depth,
shmdesc->addr + stuff->offset); shmdesc->addr + stuff->offset);
@ -1052,6 +1093,7 @@ ProcShmCreatePixmap(ClientPtr client)
DepthPtr pDepth; DepthPtr pDepth;
int i, rc; int i, rc;
ShmDescPtr shmdesc; ShmDescPtr shmdesc;
ShmScrPrivateRec *screen_priv;
REQUEST(xShmCreatePixmapReq); REQUEST(xShmCreatePixmapReq);
unsigned int width, height, depth; unsigned int width, height, depth;
unsigned long size; unsigned long size;
@ -1100,7 +1142,8 @@ CreatePmap:
return BadAlloc; return BadAlloc;
VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)( screen_priv = ShmGetScreenPriv(pDraw->pScreen);
pMap = (*screen_priv->shmFuncs->CreatePixmap)(
pDraw->pScreen, stuff->width, pDraw->pScreen, stuff->width,
stuff->height, stuff->depth, stuff->height, stuff->depth,
shmdesc->addr + stuff->offset); shmdesc->addr + stuff->offset);