⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resource.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 2 页
字号:
    resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));    if (!resources)    {	DEALLOCATE_LOCAL(tails);	return;    }    for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)    {	*rptr = NullResource;	*tptr = rptr;    }    clientTable[client].hashsize++;    for (j = clientTable[client].buckets,	 rptr = clientTable[client].resources;	 --j >= 0;	 rptr++)    {	for (res = *rptr; res; res = next)	{	    next = res->next;	    res->next = NullResource;	    tptr = &tails[Hash(client, res->id)];	    **tptr = res;	    *tptr = &res->next;	}    }    DEALLOCATE_LOCAL(tails);    clientTable[client].buckets *= 2;    xfree(clientTable[client].resources);    clientTable[client].resources = resources;}voidFreeResource(id, skipDeleteFuncType)    XID id;    RESTYPE skipDeleteFuncType;{    int		cid;    register    ResourcePtr res;    register	ResourcePtr *prev, *head;    register	int *eltptr;    int		elements;    Bool	gotOne = FALSE;    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)    {	head = &clientTable[cid].resources[Hash(cid, id)];	eltptr = &clientTable[cid].elements;	prev = head;	while ( (res = *prev) )	{	    if (res->id == id)	    {		RESTYPE rtype = res->type;		*prev = res->next;		elements = --*eltptr;		if (rtype & RC_CACHED)		    FlushClientCaches(res->id);		if (rtype != skipDeleteFuncType)		    (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);		xfree(res);		if (*eltptr != elements)		    prev = head; /* prev may no longer be valid */		gotOne = TRUE;	    }	    else		prev = &res->next;        }	if(clients[cid] && (id == clients[cid]->lastDrawableID))	{	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;	}    }    if (!gotOne)	FatalError("Freeing resource id=%X which isn't there", id);}voidFreeResourceByType(id, type, skipFree)    XID id;    RESTYPE type;    Bool    skipFree;{    int		cid;    register    ResourcePtr res;    register	ResourcePtr *prev, *head;    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)    {	head = &clientTable[cid].resources[Hash(cid, id)];	prev = head;	while ( (res = *prev) )	{	    if (res->id == id && res->type == type)	    {		*prev = res->next;		if (type & RC_CACHED)		    FlushClientCaches(res->id);		if (!skipFree)		    (*DeleteFuncs[type & TypeMask])(res->value, res->id);		xfree(res);		break;	    }	    else		prev = &res->next;        }	if(clients[cid] && (id == clients[cid]->lastDrawableID))	{	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;	}    }}/* * Change the value associated with a resource id.  Caller * is responsible for "doing the right thing" with the old * data */BoolChangeResourceValue (id, rtype, value)    XID	id;    RESTYPE rtype;    pointer value;{    int    cid;    register    ResourcePtr res;    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)    {	res = clientTable[cid].resources[Hash(cid, id)];	for (; res; res = res->next)	    if ((res->id == id) && (res->type == rtype))	    {		if (rtype & RC_CACHED)		    FlushClientCaches(res->id);		res->value = value;		return TRUE;	    }    }    return FALSE;}/* Note: if func adds or deletes resources, then func can get called * more than once for some resources.  If func adds new resources, * func might or might not get called for them.  func cannot both * add and delete an equal number of resources! */voidFindClientResourcesByType(client, type, func, cdata)    ClientPtr client;    RESTYPE type;    FindResType func;    pointer cdata;{    register ResourcePtr *resources;    register ResourcePtr this, next;    int i, elements;    register int *eltptr;    if (!client)	client = serverClient;    resources = clientTable[client->index].resources;    eltptr = &clientTable[client->index].elements;    for (i = 0; i < clientTable[client->index].buckets; i++)     {        for (this = resources[i]; this; this = next)	{	    next = this->next;	    if (!type || this->type == type) {		elements = *eltptr;		(*func)(this->value, this->id, cdata);		if (*eltptr != elements)		    next = resources[i]; /* start over */	    }	}    }}voidFreeClientNeverRetainResources(client)    ClientPtr client;{    ResourcePtr *resources;    ResourcePtr this;    ResourcePtr *prev;    int j;    if (!client)	return;    resources = clientTable[client->index].resources;    for (j=0; j < clientTable[client->index].buckets; j++)     {	prev = &resources[j];        while ( (this = *prev) )	{	    RESTYPE rtype = this->type;	    if (rtype & RC_NEVERRETAIN)	    {		*prev = this->next;		if (rtype & RC_CACHED)		    FlushClientCaches(this->id);		(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);		xfree(this);	    	    }	    else		prev = &this->next;	}    }}voidFreeClientResources(client)    ClientPtr client;{    register ResourcePtr *resources;    register ResourcePtr this;    int j;    /* This routine shouldn't be called with a null client, but just in	case ... */    if (!client)	return;    HandleSaveSet(client);    resources = clientTable[client->index].resources;    for (j=0; j < clientTable[client->index].buckets; j++)     {        /* It may seem silly to update the head of this resource list as	we delete the members, since the entire list will be deleted any way, 	but there are some resource deletion functions "FreeClientPixels" for 	one which do a LookupID on another resource id (a Colormap id in this	case), so the resource list must be kept valid up to the point that	it is deleted, so every time we delete a resource, we must update the	head, just like in FreeResource. I hope that this doesn't slow down	mass deletion appreciably. PRH */	ResourcePtr *head;	head = &resources[j];        for (this = *head; this; this = *head)	{	    RESTYPE rtype = this->type;	    *head = this->next;	    if (rtype & RC_CACHED)		FlushClientCaches(this->id);	    (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);	    xfree(this);	    	}    }    xfree(clientTable[client->index].resources);    clientTable[client->index].buckets = 0;}voidFreeAllResources(){    int	i;    for (i = currentMaxClients; --i >= 0; )     {        if (clientTable[i].buckets) 	    FreeClientResources(clients[i]);    }}BoolLegalNewID(id, client)    XID id;    register ClientPtr client;{    return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&	    ((clientTable[client->index].expectID <= id) ||	     !LookupIDByClass(id, RC_ANY)));}#ifdef XCSECURITY/* SecurityLookupIDByType and SecurityLookupIDByClass: * These are the heart of the resource ID security system.  They take * two additional arguments compared to the old LookupID functions: * the client doing the lookup, and the access mode (see resource.h). * The resource is returned if it exists and the client is allowed access, * else NULL is returned. */pointerSecurityLookupIDByType(client, id, rtype, mode)    ClientPtr client;    XID id;    RESTYPE rtype;    Mask mode;{    int    cid;    register    ResourcePtr res;    pointer retval = NULL;    assert(client == NullClient ||     (client->index <= currentMaxClients && clients[client->index] == client));    assert( (rtype & TypeMask) <= lastResourceType);    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&	clientTable[cid].buckets)    {	res = clientTable[cid].resources[Hash(cid, id)];	for (; res; res = res->next)	    if ((res->id == id) && (res->type == rtype))	    {		retval = res->value;		break;	    }    }    if (retval && client && client->CheckAccess)	retval = (* client->CheckAccess)(client, id, rtype, mode, retval);    return retval;}pointerSecurityLookupIDByClass(client, id, classes, mode)    ClientPtr client;    XID id;    RESTYPE classes;    Mask mode;{    int    cid;    register    ResourcePtr res;    pointer retval = NULL;    assert(client == NullClient ||     (client->index <= currentMaxClients && clients[client->index] == client));    assert (classes >= lastResourceClass);    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&	clientTable[cid].buckets)    {	res = clientTable[cid].resources[Hash(cid, id)];	for (; res; res = res->next)	    if ((res->id == id) && (res->type & classes))	    {		retval = res->value;		break;	    }    }    if (retval && client && client->CheckAccess)	retval = (* client->CheckAccess)(client, id, classes, mode, retval);    return retval;}/* We can't replace the LookupIDByType and LookupIDByClass functions with * macros because of compatibility with loadable servers. */pointerLookupIDByType(id, rtype)    XID id;    RESTYPE rtype;{    return SecurityLookupIDByType(NullClient, id, rtype,				  SecurityUnknownAccess);}pointerLookupIDByClass(id, classes)    XID id;    RESTYPE classes;{    return SecurityLookupIDByClass(NullClient, id, classes,				   SecurityUnknownAccess);}#else /* not XCSECURITY *//* *  LookupIDByType returns the object with the given id and type, else NULL. */ pointerLookupIDByType(id, rtype)    XID id;    RESTYPE rtype;{    int    cid;    register    ResourcePtr res;    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&	clientTable[cid].buckets)    {	res = clientTable[cid].resources[Hash(cid, id)];	for (; res; res = res->next)	    if ((res->id == id) && (res->type == rtype))		return res->value;    }    return (pointer)NULL;}/* *  LookupIDByClass returns the object with the given id and any one of the *  given classes, else NULL. */ pointerLookupIDByClass(id, classes)    XID id;    RESTYPE classes;{    int    cid;    register    ResourcePtr res;    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&	clientTable[cid].buckets)    {	res = clientTable[cid].resources[Hash(cid, id)];	for (; res; res = res->next)	    if ((res->id == id) && (res->type & classes))		return res->value;    }    return (pointer)NULL;}#endif /* XCSECURITY */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -