Return an appropriately-typed error from dixLookupResourceByType.

Rather than always returning BadValue, associate an error status like
BadWindow with a resource type like RT_WINDOW, and return the
appropriate one for the requested type.

This patch only touches the core protocol resource types. Others still
return BadValue and need to be mapped appropriately.

dixLookupResourceByType can now return BadImplementation, if the caller
asked for a resource type that has not been allocated in the server.

Signed-off-by: Jamey Sharp <jamey@minilop.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
Jamey Sharp 2010-04-24 23:26:40 -07:00
parent 90e612dcbe
commit e291c56182
21 changed files with 124 additions and 93 deletions

View File

@ -457,7 +457,7 @@ int PanoramiXConfigureWindow(ClientPtr client)
result = dixLookupResourceByType((pointer *)&pWin, stuff->window,
RT_WINDOW, client, DixWriteAccess);
if (result != Success)
return (result == BadValue) ? BadWindow : result;
return result;
result = dixLookupResourceByType((pointer *)&win, stuff->window,
XRT_WINDOW, client, DixWriteAccess);

View File

@ -1043,7 +1043,6 @@ ScreenSaverSetAttributes (ClientPtr client)
}
else
{
ret = (ret == BadValue) ? BadPixmap : ret;
client->errorValue = pixID;
goto PatchUp;
}
@ -1081,7 +1080,6 @@ ScreenSaverSetAttributes (ClientPtr client)
}
else
{
ret = (ret == BadValue) ? BadPixmap : ret;
client->errorValue = pixID;
goto PatchUp;
}
@ -1163,7 +1161,6 @@ ScreenSaverSetAttributes (ClientPtr client)
client, DixUseAccess);
if (ret != Success)
{
ret = (ret == BadValue) ? BadColor : ret;
client->errorValue = cmap;
goto PatchUp;
}
@ -1187,7 +1184,6 @@ ScreenSaverSetAttributes (ClientPtr client)
RT_CURSOR, client, DixUseAccess);
if (ret != Success)
{
ret = (ret == BadValue) ? BadCursor : ret;
client->errorValue = cursorID;
goto PatchUp;
}

View File

@ -415,7 +415,7 @@ ProcShapeMask (ClientPtr client)
rc = dixLookupResourceByType((pointer *)&pPixmap, stuff->src, RT_PIXMAP,
client, DixReadAccess);
if (rc != Success)
return (rc == BadValue) ? BadPixmap : rc;
return rc;
if (pPixmap->drawable.pScreen != pScreen ||
pPixmap->drawable.depth != 1)
return BadMatch;

View File

@ -153,7 +153,7 @@ ProcXTestCompareCursor(ClientPtr client)
if (rc != Success)
{
client->errorValue = stuff->cursor;
return (rc == BadValue) ? BadCursor : rc;
return rc;
}
}
rep.type = X_Reply;

View File

@ -1445,7 +1445,7 @@ GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
if (rc != Success)
{
client->errorValue = param->cursor;
return (rc == BadValue) ? BadCursor : rc;
return rc;
}
access_mode |= DixForceAccess;
}
@ -1543,7 +1543,7 @@ GrabWindow(ClientPtr client, DeviceIntPtr dev, int type,
if (rc != Success)
{
client->errorValue = param->cursor;
return (rc == BadValue) ? BadCursor : rc;
return rc;
}
access_mode |= DixForceAccess;
}

View File

@ -103,7 +103,7 @@ int ProcXIChangeCursor(ClientPtr client)
rc = dixLookupResourceByType((pointer *)&pCursor, stuff->cursor,
RT_CURSOR, client, DixUseAccess);
if (rc != Success)
return (rc == BadValue) ? BadCursor : rc;
return rc;
}
ChangeWindowDeviceCursor(pWin, pDev, pCursor);

View File

@ -147,7 +147,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
if (status != Success)
{
client->errorValue = stuff->cursor;
return (status == BadValue) ? BadCursor : status;
return status;
}
}

View File

@ -140,10 +140,7 @@ ProcCompositeQueryVersion (ClientPtr client)
int err; \
err = dixLookupResourceByType((pointer *) &pWindow, wid, \
RT_WINDOW, client, mode); \
if (err == BadValue) { \
client->errorValue = wid; \
return BadWindow; \
} else if (err != Success) { \
if (err != Success) { \
client->errorValue = wid; \
return err; \
} \

View File

@ -316,14 +316,14 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
if (rc != Success)
{
client->errorValue = source;
return (rc == BadValue) ? BadFont : rc;
return rc;
}
rc = dixLookupResourceByType((pointer *)&maskfont, mask, RT_FONT, client,
DixUseAccess);
if (rc != Success && mask != None)
{
client->errorValue = mask;
return (rc == BadValue) ? BadFont : rc;
return rc;
}
if (sourcefont != maskfont)
pShare = (GlyphSharePtr)NULL;

View File

@ -1240,7 +1240,7 @@ ProcCloseFont(ClientPtr client)
else
{
client->errorValue = stuff->id;
return (rc == BadValue) ? BadFont : rc;
return rc;
}
}
@ -1453,7 +1453,7 @@ ProcFreePixmap(ClientPtr client)
else
{
client->errorValue = stuff->id;
return (rc == BadValue) ? BadPixmap : rc;
return rc;
}
}
@ -2407,7 +2407,7 @@ ProcFreeColormap(ClientPtr client)
else
{
client->errorValue = stuff->id;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}
@ -2428,7 +2428,7 @@ ProcCopyColormapAndFree(ClientPtr client)
if (rc == Success)
return CopyColormapAndFree(mid, pSrcMap, client->index);
client->errorValue = stuff->srcCmap;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
int
@ -2445,15 +2445,18 @@ ProcInstallColormap(ClientPtr client)
goto out;
rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
if (rc != Success)
if (rc != Success) {
if (rc == BadValue)
rc = BadColor;
goto out;
}
(*(pcmp->pScreen->InstallColormap)) (pcmp);
return Success;
out:
client->errorValue = stuff->id;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
int
@ -2470,8 +2473,11 @@ ProcUninstallColormap(ClientPtr client)
goto out;
rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
if (rc != Success)
if (rc != Success) {
if (rc == BadValue)
rc = BadColor;
goto out;
}
if(pcmp->mid != pcmp->pScreen->defColormap)
(*(pcmp->pScreen->UninstallColormap)) (pcmp);
@ -2479,7 +2485,7 @@ ProcUninstallColormap(ClientPtr client)
out:
client->errorValue = stuff->id;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
int
@ -2552,7 +2558,7 @@ ProcAllocColor (ClientPtr client)
else
{
client->errorValue = stuff->cmap;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}
@ -2598,7 +2604,7 @@ ProcAllocNamedColor (ClientPtr client)
else
{
client->errorValue = stuff->cmap;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}
@ -2662,7 +2668,7 @@ ProcAllocColorCells (ClientPtr client)
else
{
client->errorValue = stuff->cmap;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}
@ -2724,7 +2730,7 @@ ProcAllocColorPlanes(ClientPtr client)
else
{
client->errorValue = stuff->cmap;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}
@ -2751,7 +2757,7 @@ ProcFreeColors(ClientPtr client)
else
{
client->errorValue = stuff->cmap;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}
@ -2778,7 +2784,7 @@ ProcStoreColors (ClientPtr client)
else
{
client->errorValue = stuff->cmap;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}
@ -2808,7 +2814,7 @@ ProcStoreNamedColor (ClientPtr client)
else
{
client->errorValue = stuff->cmap;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}
@ -2855,7 +2861,7 @@ ProcQueryColors(ClientPtr client)
else
{
client->errorValue = stuff->cmap;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}
@ -2894,7 +2900,7 @@ ProcLookupColor(ClientPtr client)
else
{
client->errorValue = stuff->cmap;
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}
@ -2920,7 +2926,7 @@ ProcCreateCursor (ClientPtr client)
DixReadAccess);
if (rc != Success) {
client->errorValue = stuff->source;
return (rc == BadValue) ? BadPixmap : rc;
return rc;
}
rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client,
@ -2930,7 +2936,7 @@ ProcCreateCursor (ClientPtr client)
if (stuff->mask != None)
{
client->errorValue = stuff->mask;
return (rc == BadValue) ? BadPixmap : rc;
return rc;
}
}
else if ( src->drawable.width != msk->drawable.width
@ -3031,7 +3037,7 @@ ProcFreeCursor (ClientPtr client)
else
{
client->errorValue = stuff->id;
return (rc == BadValue) ? BadCursor : rc;
return rc;
}
}

View File

@ -1238,7 +1238,6 @@ doPolyText(ClientPtr client, PTclosurePtr c)
client, DixUseAccess);
if (err != Success)
{
err = (err == BadValue) ? BadFont : err;
/* restore pFont and fid for step 4 (described below) */
pFont = oldpFont;
fid = oldfid;

View File

@ -231,9 +231,7 @@ dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access)
int
dixLookupGC(GCPtr *pGC, XID id, ClientPtr client, Mask access)
{
int rc;
rc = dixLookupResourceByType((pointer *)pGC, id, RT_GC, client, access);
return (rc == BadValue) ? BadGC : rc;
return dixLookupResourceByType((pointer *)pGC, id, RT_GC, client, access);
}
int
@ -243,10 +241,10 @@ dixLookupFontable(FontPtr *pFont, XID id, ClientPtr client, Mask access)
GC *pGC;
client->errorValue = id; /* EITHER font or gc */
rc = dixLookupResourceByType((pointer *) pFont, id, RT_FONT, client, access);
if (rc != BadValue)
if (rc != BadFont)
return rc;
rc = dixLookupResourceByType((pointer *) &pGC, id, RT_GC, client, access);
if (rc == BadValue)
if (rc == BadGC)
return BadFont;
if (rc == Success)
*pFont = pGC->font;

View File

@ -4697,7 +4697,7 @@ ProcChangeActivePointerGrab(ClientPtr client)
if (rc != Success)
{
client->errorValue = stuff->cursor;
return (rc == BadValue) ? BadCursor : rc;
return rc;
}
}
@ -4820,7 +4820,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
if (rc != Success)
{
client->errorValue = curs;
return (rc == BadValue) ? BadCursor : rc;
return rc;
}
access_mode |= DixForceAccess;
}
@ -5345,7 +5345,7 @@ ProcGrabButton(ClientPtr client)
if (rc != Success)
{
client->errorValue = stuff->cursor;
return (rc == BadValue) ? BadCursor : rc;
return rc;
}
access_mode |= DixForceAccess;
}
@ -5608,7 +5608,7 @@ ProcRecolorCursor(ClientPtr client)
if (rc != Success)
{
client->errorValue = stuff->cursor;
return (rc == BadValue) ? BadCursor : rc;
return rc;
}
pCursor->foreRed = stuff->foreRed;

View File

@ -458,8 +458,6 @@ ChangeGCXIDs(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32)
if (rc != Success)
{
client->errorValue = vals[offset].val;
if (rc == BadValue)
rc = (xidfields[i].type == RT_PIXMAP) ? BadPixmap : BadFont;
return rc;
}
}

View File

@ -183,7 +183,54 @@ RESTYPE lastResourceType;
static RESTYPE lastResourceClass;
RESTYPE TypeMask;
static DeleteType *DeleteFuncs = (DeleteType *)NULL;
struct ResourceType {
DeleteType deleteFunc;
int errorValue;
};
static struct ResourceType *resourceTypes;
static const struct ResourceType predefTypes[] = {
[RT_NONE & (RC_LASTPREDEF - 1)] = {
.deleteFunc = (DeleteType)NoopDDA,
.errorValue = BadValue,
},
[RT_WINDOW & (RC_LASTPREDEF - 1)] = {
.deleteFunc = DeleteWindow,
.errorValue = BadWindow,
},
[RT_PIXMAP & (RC_LASTPREDEF - 1)] = {
.deleteFunc = dixDestroyPixmap,
.errorValue = BadPixmap,
},
[RT_GC & (RC_LASTPREDEF - 1)] = {
.deleteFunc = FreeGC,
.errorValue = BadGC,
},
[RT_FONT & (RC_LASTPREDEF - 1)] = {
.deleteFunc = CloseFont,
.errorValue = BadFont,
},
[RT_CURSOR & (RC_LASTPREDEF - 1)] = {
.deleteFunc = FreeCursor,
.errorValue = BadCursor,
},
[RT_COLORMAP & (RC_LASTPREDEF - 1)] = {
.deleteFunc = FreeColormap,
.errorValue = BadColor,
},
[RT_CMAPENTRY & (RC_LASTPREDEF - 1)] = {
.deleteFunc = FreeClientPixels,
.errorValue = BadColor,
},
[RT_OTHERCLIENT & (RC_LASTPREDEF - 1)] = {
.deleteFunc = OtherClientGone,
.errorValue = BadValue,
},
[RT_PASSIVEGRAB & (RC_LASTPREDEF - 1)] = {
.deleteFunc = DeletePassiveGrab,
.errorValue = BadValue,
},
};
CallbackListPtr ResourceStateCallback;
@ -200,20 +247,20 @@ RESTYPE
CreateNewResourceType(DeleteType deleteFunc, char *name)
{
RESTYPE next = lastResourceType + 1;
DeleteType *funcs;
struct ResourceType *types;
if (next & lastResourceClass)
return 0;
funcs = (DeleteType *)realloc(DeleteFuncs,
(next + 1) * sizeof(DeleteType));
if (!funcs)
types = realloc(resourceTypes, (next + 1) * sizeof(*resourceTypes));
if (!types)
return 0;
if (!dixRegisterPrivateOffset(next, -1))
return 0;
lastResourceType = next;
DeleteFuncs = funcs;
DeleteFuncs[next] = deleteFunc;
resourceTypes = types;
resourceTypes[next].deleteFunc = deleteFunc;
resourceTypes[next].errorValue = BadValue;
/* Called even if name is NULL, to remove any previous entry */
RegisterResourceName(next, name);
@ -251,21 +298,11 @@ InitClientResources(ClientPtr client)
lastResourceType = RT_LASTPREDEF;
lastResourceClass = RC_LASTPREDEF;
TypeMask = RC_LASTPREDEF - 1;
if (DeleteFuncs)
free(DeleteFuncs);
DeleteFuncs = malloc((lastResourceType + 1) * sizeof(DeleteType));
if (!DeleteFuncs)
free(resourceTypes);
resourceTypes = malloc(sizeof(predefTypes));
if (!resourceTypes)
return FALSE;
DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
DeleteFuncs[RT_GC & TypeMask] = FreeGC;
DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
memcpy(resourceTypes, predefTypes, sizeof(predefTypes));
}
clientTable[i = client->index].resources =
malloc(INITBUCKETS*sizeof(ResourcePtr));
@ -462,7 +499,7 @@ AddResource(XID id, RESTYPE type, pointer value)
res = malloc(sizeof(ResourceRec));
if (!res)
{
(*DeleteFuncs[type & TypeMask])(value, id);
(*resourceTypes[type & TypeMask].deleteFunc)(value, id);
return FALSE;
}
res->next = *head;
@ -557,7 +594,7 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType)
CallResourceStateCallback(ResourceStateFreeing, res);
if (rtype != skipDeleteFuncType)
(*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
(*resourceTypes[rtype & TypeMask].deleteFunc)(res->value, res->id);
free(res);
if (*eltptr != elements)
prev = head; /* prev may no longer be valid */
@ -594,7 +631,7 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
CallResourceStateCallback(ResourceStateFreeing, res);
if (!skipFree)
(*DeleteFuncs[type & TypeMask])(res->value, res->id);
(*resourceTypes[type & TypeMask].deleteFunc)(res->value, res->id);
free(res);
break;
}
@ -761,7 +798,7 @@ FreeClientNeverRetainResources(ClientPtr client)
CallResourceStateCallback(ResourceStateFreeing, this);
elements = *eltptr;
(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
(*resourceTypes[rtype & TypeMask].deleteFunc)(this->value, this->id);
free(this);
if (*eltptr != elements)
prev = &resources[j]; /* prev may no longer be valid */
@ -815,7 +852,7 @@ FreeClientResources(ClientPtr client)
CallResourceStateCallback(ResourceStateFreeing, this);
(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
(*resourceTypes[rtype & TypeMask].deleteFunc)(this->value, this->id);
free(this);
}
}
@ -873,6 +910,8 @@ dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype,
ResourcePtr res = NULL;
*result = NULL;
if ((rtype & TypeMask) > lastResourceType)
return BadImplementation;
if ((cid < MAXCLIENTS) && clientTable[cid].buckets) {
res = clientTable[cid].resources[Hash(cid, id)];
@ -882,12 +921,14 @@ dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype,
break;
}
if (!res)
return BadValue;
return resourceTypes[rtype & TypeMask].errorValue;
if (client) {
client->errorValue = id;
cid = XaceHook(XACE_RESOURCE_ACCESS, client, id, res->type,
res->value, RT_NONE, NULL, mode);
if (cid == BadValue)
return resourceTypes[rtype & TypeMask].errorValue;
if (cid != Success)
return cid;
}

View File

@ -1056,7 +1056,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
}
else
{
error = (rc == BadValue) ? BadPixmap : rc;
error = rc;
client->errorValue = pixID;
goto PatchUp;
}
@ -1116,7 +1116,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
}
else
{
error = (rc == BadValue) ? BadPixmap : rc;
error = rc;
client->errorValue = pixID;
goto PatchUp;
}
@ -1264,7 +1264,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
client, DixUseAccess);
if (rc != Success)
{
error = (rc == BadValue) ? BadColor : rc;
error = rc;
client->errorValue = cmap;
goto PatchUp;
}
@ -1340,7 +1340,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
RT_CURSOR, client, DixUseAccess);
if (rc != Success)
{
error = (rc == BadValue) ? BadCursor : rc;
error = rc;
client->errorValue = cursorID;
goto PatchUp;
}

View File

@ -436,7 +436,7 @@ ProcXDGAInstallColormap(ClientPtr client)
rc = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, RT_COLORMAP,
client, DixInstallAccess);
if (rc != Success)
return (rc == BadValue) ? BadColor : rc;
return rc;
DGAInstallCmap(cmap);
return Success;
}
@ -878,7 +878,7 @@ ProcXF86DGAInstallColormap(ClientPtr client)
DGAInstallCmap(pcmp);
return Success;
} else {
return (rc == BadValue) ? BadColor : rc;
return rc;
}
}

View File

@ -1176,7 +1176,6 @@ ChangePicture (PicturePtr pPicture,
if (error != Success)
{
client->errorValue = pid;
error = (error == BadValue) ? BadPixmap : error;
break;
}
}

View File

@ -1856,7 +1856,7 @@ ProcRenderCreateAnimCursor (ClientPtr client)
if (ret != Success)
{
free(cursors);
return (ret == BadValue) ? BadCursor : ret;
return ret;
}
deltas[i] = elt->delay;
elt++;

View File

@ -70,10 +70,7 @@ static void deleteCursorHideCountsForScreen (ScreenPtr pScreen);
int err; \
err = dixLookupResourceByType((pointer *) &pCursor, cursor, \
RT_CURSOR, client, access); \
if (err == BadValue) { \
client->errorValue = cursor; \
return BadCursor; \
} else if (err != Success) { \
if (err != Success) { \
client->errorValue = cursor; \
return err; \
} \
@ -882,7 +879,7 @@ ProcXFixesHideCursor (ClientPtr client)
client, DixGetAttrAccess);
if (ret != Success) {
client->errorValue = stuff->window;
return (ret == BadValue) ? BadWindow : ret;
return ret;
}
/*
@ -945,7 +942,7 @@ ProcXFixesShowCursor (ClientPtr client)
client, DixGetAttrAccess);
if (rc != Success) {
client->errorValue = stuff->window;
return (rc == BadValue) ? BadWindow : rc;
return rc;
}
/*

View File

@ -119,7 +119,7 @@ ProcXFixesCreateRegionFromBitmap (ClientPtr client)
if (rc != Success)
{
client->errorValue = stuff->bitmap;
return (rc == BadValue) ? BadPixmap : rc;
return rc;
}
if (pPixmap->drawable.depth != 1)
return BadMatch;
@ -164,7 +164,7 @@ ProcXFixesCreateRegionFromWindow (ClientPtr client)
if (rc != Success)
{
client->errorValue = stuff->window;
return (rc == BadValue) ? BadWindow : rc;
return rc;
}
switch (stuff->kind) {
case WindowRegionBounding:
@ -675,7 +675,7 @@ ProcXFixesSetWindowShapeRegion (ClientPtr client)
if (rc != Success)
{
client->errorValue = stuff->dest;
return (rc == BadValue) ? BadWindow : rc;
return rc;
}
VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess);
pScreen = pWin->drawable.pScreen;