aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/dix/resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/dix/resource.c')
-rw-r--r--xorg-server/dix/resource.c101
1 files changed, 74 insertions, 27 deletions
diff --git a/xorg-server/dix/resource.c b/xorg-server/dix/resource.c
index 00b3368a0..1d33c9aad 100644
--- a/xorg-server/dix/resource.c
+++ b/xorg-server/dix/resource.c
@@ -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);
@@ -221,6 +268,12 @@ CreateNewResourceType(DeleteType deleteFunc, char *name)
return next;
}
+void
+SetResourceTypeErrorValue(RESTYPE type, int errorValue)
+{
+ resourceTypes[type & TypeMask].errorValue = errorValue;
+}
+
RESTYPE
CreateNewResourceClass(void)
{
@@ -251,21 +304,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 +505,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 +600,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 +637,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 +804,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 +858,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 +916,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 +927,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;
}