diff --git a/dix/resource.c b/dix/resource.c index 2cad7c01b..edf32ff34 100644 --- a/dix/resource.c +++ b/dix/resource.c @@ -193,6 +193,17 @@ _X_EXPORT RESTYPE TypeMask; static DeleteType *DeleteFuncs = (DeleteType *)NULL; +_X_EXPORT CallbackListPtr ResourceStateCallback; + +static _X_INLINE void +CallResourceStateCallback(ResourceState state, ResourceRec *res) +{ + if (ResourceStateCallback) { + ResourceStateInfoRec rsi = { state, res->id, res->type, res->value }; + CallCallbacks(&ResourceStateCallback, &rsi); + } +} + #ifdef XResExtension _X_EXPORT Atom * ResourceNames = NULL; @@ -492,6 +503,7 @@ AddResource(XID id, RESTYPE type, pointer value) rrec->elements++; if (!(id & SERVER_BIT) && (id >= rrec->expectID)) rrec->expectID = id + 1; + CallResourceStateCallback(ResourceStateAdding, res); return TRUE; } @@ -572,6 +584,9 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType) #endif *prev = res->next; elements = --*eltptr; + + CallResourceStateCallback(ResourceStateFreeing, res); + if (rtype & RC_CACHED) FlushClientCaches(res->id); if (rtype != skipDeleteFuncType) @@ -616,6 +631,9 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree) res->value, TypeNameString(res->type)); #endif *prev = res->next; + + CallResourceStateCallback(ResourceStateFreeing, res); + if (type & RC_CACHED) FlushClientCaches(res->id); if (!skipFree) @@ -782,6 +800,9 @@ FreeClientNeverRetainResources(ClientPtr client) this->value, TypeNameString(this->type)); #endif *prev = this->next; + + CallResourceStateCallback(ResourceStateFreeing, this); + if (rtype & RC_CACHED) FlushClientCaches(this->id); (*DeleteFuncs[rtype & TypeMask])(this->value, this->id); @@ -832,6 +853,9 @@ FreeClientResources(ClientPtr client) this->value, TypeNameString(this->type)); #endif *head = this->next; + + CallResourceStateCallback(ResourceStateFreeing, this); + if (rtype & RC_CACHED) FlushClientCaches(this->id); (*DeleteFuncs[rtype & TypeMask])(this->value, this->id); diff --git a/hw/xfree86/loader/dixsym.c b/hw/xfree86/loader/dixsym.c index e6c2baac3..1732d1fe4 100644 --- a/hw/xfree86/loader/dixsym.c +++ b/hw/xfree86/loader/dixsym.c @@ -300,6 +300,7 @@ _X_HIDDEN void *dixLookupTab[] = { SYMFUNC(FindAllClientResources) SYMVAR(lastResourceType) SYMVAR(TypeMask) + SYMVAR(ResourceStateCallback) #ifdef RES SYMFUNC(RegisterResourceName) SYMVAR(ResourceNames) diff --git a/include/resource.h b/include/resource.h index 3231e8cd9..9949dd2fc 100644 --- a/include/resource.h +++ b/include/resource.h @@ -120,6 +120,19 @@ typedef unsigned long RESTYPE; #define BAD_RESOURCE 0xe0000000 +/* Resource state callback */ +extern CallbackListPtr ResourceStateCallback; + +typedef enum {ResourceStateAdding, + ResourceStateFreeing} ResourceState; + +typedef struct { + ResourceState state; + XID id; + RESTYPE type; + pointer value; +} ResourceStateInfoRec; + typedef int (*DeleteType)( pointer /*value*/, XID /*id*/);