diff options
Diffstat (limited to 'xorg-server/dix/resource.c')
-rw-r--r-- | xorg-server/dix/resource.c | 102 |
1 files changed, 75 insertions, 27 deletions
diff --git a/xorg-server/dix/resource.c b/xorg-server/dix/resource.c index 00b3368a0..5364dcc3b 100644 --- a/xorg-server/dix/resource.c +++ b/xorg-server/dix/resource.c @@ -183,7 +183,55 @@ 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 +248,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 +269,12 @@ CreateNewResourceType(DeleteType deleteFunc, char *name) return next;
}
+void
+SetResourceTypeErrorValue(RESTYPE type, int errorValue)
+{
+ resourceTypes[type & TypeMask].errorValue = errorValue;
+}
+
RESTYPE
CreateNewResourceClass(void)
{
@@ -251,21 +305,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 +506,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 +601,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 +638,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 +805,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 +859,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 +917,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 +928,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;
}
|