xfree86: use screen privates for exclusive DGA clients.

Most DGA requests allow at most one client to be using DGA on each
screen. Instead of keeping track of the current client in a
MAXSCREEN-sized array, track it in a per-screen private.

Signed-off-by: Jamey Sharp <jamey@minilop.net>
Acked-by: Tiago Vignatti <tiago.vignatti@nokia.com>
Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
This commit is contained in:
Jamey Sharp 2010-04-21 18:05:45 -07:00
parent f9e3a2955d
commit a1c2acfe79

View File

@ -57,12 +57,12 @@ static void XDGAResetProc(ExtensionEntry *extEntry);
static void DGAClientStateChange (CallbackListPtr*, pointer, pointer); static void DGAClientStateChange (CallbackListPtr*, pointer, pointer);
static ClientPtr DGAClients[MAXSCREENS];
unsigned char DGAReqCode = 0; unsigned char DGAReqCode = 0;
int DGAErrorBase; int DGAErrorBase;
int DGAEventBase; int DGAEventBase;
static int DGAScreenPrivateKeyIndex;
static DevPrivateKey DGAScreenPrivateKey = &DGAScreenPrivateKeyIndex;
static int DGAClientPrivateKeyIndex; static int DGAClientPrivateKeyIndex;
static DevPrivateKey DGAClientPrivateKey = &DGAClientPrivateKeyIndex; static DevPrivateKey DGAClientPrivateKey = &DGAClientPrivateKeyIndex;
static int DGACallbackRefCount = 0; static int DGACallbackRefCount = 0;
@ -73,6 +73,11 @@ typedef struct {
int minor; int minor;
} DGAPrivRec, *DGAPrivPtr; } DGAPrivRec, *DGAPrivPtr;
#define DGA_GETCLIENT(idx) ((ClientPtr) \
dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey))
#define DGA_SETCLIENT(idx,p) \
dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p)
#define DGA_GETPRIV(c) ((DGAPrivPtr) \ #define DGA_GETPRIV(c) ((DGAPrivPtr) \
dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey)) dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
#define DGA_SETPRIV(c,p) \ #define DGA_SETPRIV(c,p) \
@ -93,9 +98,6 @@ XFree86DGAExtensionInit(INITARGS)
StandardMinorOpcode))) { StandardMinorOpcode))) {
int i; int i;
for(i = 0; i < MAXSCREENS; i++)
DGAClients[i] = NULL;
DGAReqCode = (unsigned char)extEntry->base; DGAReqCode = (unsigned char)extEntry->base;
DGAErrorBase = extEntry->errorBase; DGAErrorBase = extEntry->errorBase;
DGAEventBase = extEntry->eventBase; DGAEventBase = extEntry->eventBase;
@ -282,7 +284,7 @@ DGAClientStateChange (
int i; int i;
for(i = 0; i < screenInfo.numScreens; i++) { for(i = 0; i < screenInfo.numScreens; i++) {
if(DGAClients[i] == pci->client) { if(DGA_GETCLIENT(i) == pci->client) {
client = pci->client; client = pci->client;
break; break;
} }
@ -294,7 +296,7 @@ DGAClientStateChange (
XDGAModeRec mode; XDGAModeRec mode;
PixmapPtr pPix; PixmapPtr pPix;
DGAClients[i] = NULL; DGA_SETCLIENT(i, NULL);
DGASelectInput(i, NULL, 0); DGASelectInput(i, NULL, 0);
DGASetMode(i, 0, &mode, &pPix); DGASetMode(i, 0, &mode, &pPix);
@ -311,10 +313,12 @@ ProcXDGASetMode(ClientPtr client)
XDGAModeRec mode; XDGAModeRec mode;
xXDGAModeInfo info; xXDGAModeInfo info;
PixmapPtr pPix; PixmapPtr pPix;
ClientPtr owner;
int size; int size;
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
owner = DGA_GETCLIENT(stuff->screen);
REQUEST_SIZE_MATCH(xXDGASetModeReq); REQUEST_SIZE_MATCH(xXDGASetModeReq);
rep.type = X_Reply; rep.type = X_Reply;
@ -326,16 +330,15 @@ ProcXDGASetMode(ClientPtr client)
if (!DGAAvailable(stuff->screen)) if (!DGAAvailable(stuff->screen))
return DGAErrorBase + XF86DGANoDirectVideoMode; return DGAErrorBase + XF86DGANoDirectVideoMode;
if(DGAClients[stuff->screen] && if(owner && owner != client)
(DGAClients[stuff->screen] != client))
return DGAErrorBase + XF86DGANoDirectVideoMode; return DGAErrorBase + XF86DGANoDirectVideoMode;
if(!stuff->mode) { if(!stuff->mode) {
if(DGAClients[stuff->screen]) { if(owner) {
if(--DGACallbackRefCount == 0) if(--DGACallbackRefCount == 0)
DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL); DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
} }
DGAClients[stuff->screen] = NULL; DGA_SETCLIENT(stuff->screen, NULL);
DGASelectInput(stuff->screen, NULL, 0); DGASelectInput(stuff->screen, NULL, 0);
DGASetMode(stuff->screen, 0, &mode, &pPix); DGASetMode(stuff->screen, 0, &mode, &pPix);
WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep); WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
@ -345,12 +348,12 @@ ProcXDGASetMode(ClientPtr client)
if(Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix)) if(Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
return BadValue; return BadValue;
if(!DGAClients[stuff->screen]) { if(!owner) {
if(DGACallbackRefCount++ == 0) if(DGACallbackRefCount++ == 0)
AddCallback (&ClientStateCallback, DGAClientStateChange, NULL); AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
} }
DGAClients[stuff->screen] = client; DGA_SETCLIENT(stuff->screen, client);
if(pPix) { if(pPix) {
if(AddResource(stuff->pid, RT_PIXMAP, (pointer)(pPix))) { if(AddResource(stuff->pid, RT_PIXMAP, (pointer)(pPix))) {
@ -405,7 +408,7 @@ ProcXDGASetViewport(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if(DGAClients[stuff->screen] != client) if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGASetViewportReq); REQUEST_SIZE_MATCH(xXDGASetViewportReq);
@ -425,7 +428,7 @@ ProcXDGAInstallColormap(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if(DGAClients[stuff->screen] != client) if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGAInstallColormapReq); REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
@ -451,12 +454,12 @@ ProcXDGASelectInput(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if(DGAClients[stuff->screen] != client) if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGASelectInputReq); REQUEST_SIZE_MATCH(xXDGASelectInputReq);
if(DGAClients[stuff->screen] == client) if(DGA_GETCLIENT(stuff->screen) == client)
DGASelectInput(stuff->screen, client, stuff->mask); DGASelectInput(stuff->screen, client, stuff->mask);
return (client->noClientException); return (client->noClientException);
@ -471,7 +474,7 @@ ProcXDGAFillRectangle(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if(DGAClients[stuff->screen] != client) if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGAFillRectangleReq); REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
@ -491,7 +494,7 @@ ProcXDGACopyArea(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if(DGAClients[stuff->screen] != client) if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGACopyAreaReq); REQUEST_SIZE_MATCH(xXDGACopyAreaReq);
@ -512,7 +515,7 @@ ProcXDGACopyTransparentArea(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if(DGAClients[stuff->screen] != client) if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq); REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq);
@ -534,7 +537,7 @@ ProcXDGAGetViewportStatus(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if(DGAClients[stuff->screen] != client) if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq); REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq);
@ -557,7 +560,7 @@ ProcXDGASync(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if(DGAClients[stuff->screen] != client) if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGASyncReq); REQUEST_SIZE_MATCH(xXDGASyncReq);
@ -602,7 +605,7 @@ ProcXDGAChangePixmapMode(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if(DGAClients[stuff->screen] != client) if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq); REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
@ -633,7 +636,7 @@ ProcXDGACreateColormap(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if(DGAClients[stuff->screen] != client) if(DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXDGACreateColormapReq); REQUEST_SIZE_MATCH(xXDGACreateColormapReq);
@ -713,18 +716,19 @@ ProcXF86DGADirectVideo(ClientPtr client)
int num; int num;
PixmapPtr pix; PixmapPtr pix;
XDGAModeRec mode; XDGAModeRec mode;
ClientPtr owner;
REQUEST(xXF86DGADirectVideoReq); REQUEST(xXF86DGADirectVideoReq);
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
owner = DGA_GETCLIENT(stuff->screen);
REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq); REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
if (!DGAAvailable(stuff->screen)) if (!DGAAvailable(stuff->screen))
return DGAErrorBase + XF86DGANoDirectVideoMode; return DGAErrorBase + XF86DGANoDirectVideoMode;
if (DGAClients[stuff->screen] && if (owner && owner != client)
(DGAClients[stuff->screen] != client))
return DGAErrorBase + XF86DGANoDirectVideoMode; return DGAErrorBase + XF86DGANoDirectVideoMode;
if (stuff->enable & XF86DGADirectGraphics) { if (stuff->enable & XF86DGADirectGraphics) {
@ -743,19 +747,19 @@ ProcXF86DGADirectVideo(ClientPtr client)
/* We need to track the client and attach the teardown callback */ /* We need to track the client and attach the teardown callback */
if (stuff->enable & if (stuff->enable &
(XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) { (XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) {
if (!DGAClients[stuff->screen]) { if (!owner) {
if (DGACallbackRefCount++ == 0) if (DGACallbackRefCount++ == 0)
AddCallback (&ClientStateCallback, DGAClientStateChange, NULL); AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
} }
DGAClients[stuff->screen] = client; DGA_SETCLIENT(stuff->screen, client);
} else { } else {
if (DGAClients[stuff->screen]) { if (owner) {
if (--DGACallbackRefCount == 0) if (--DGACallbackRefCount == 0)
DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL); DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
} }
DGAClients[stuff->screen] = NULL; DGA_SETCLIENT(stuff->screen, NULL);
} }
return (client->noClientException); return (client->noClientException);
@ -800,7 +804,7 @@ ProcXF86DGASetViewPort(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if (DGAClients[stuff->screen] != client) if (DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq); REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
@ -864,7 +868,7 @@ ProcXF86DGAInstallColormap(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if (DGAClients[stuff->screen] != client) if (DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq); REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq);
@ -913,7 +917,7 @@ ProcXF86DGAViewPortChanged(ClientPtr client)
if (stuff->screen > screenInfo.numScreens) if (stuff->screen > screenInfo.numScreens)
return BadValue; return BadValue;
if (DGAClients[stuff->screen] != client) if (DGA_GETCLIENT(stuff->screen) != client)
return DGAErrorBase + XF86DGADirectNotActivated; return DGAErrorBase + XF86DGADirectNotActivated;
REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq); REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq);