Commit ab6bb890 authored by Mike Gabriel's avatar Mike Gabriel

hw/nxagent/NXresource.c: Shrink file, drop duplicate code that can identically…

hw/nxagent/NXresource.c: Shrink file, drop duplicate code that can identically be found in dix/resource.c.
parent 1384776f
......@@ -16,10 +16,12 @@ FFS_OBJ = ffs.o
#if (!(defined(NXAgentServer) && NXAgentServer))
NXAGENT_SKIP_SRCS = \
extension.c \
resource.c \
window.c \
$(NULL)
NXAGENT_SKIP_OBJS = \
extension.o \
resource.o \
window.o \
$(NULL)
#endif
......@@ -40,7 +42,6 @@ SRCS = \
main.c \
property.c \
region.c \
resource.c \
swaprep.c \
swapreq.c \
tables.c \
......@@ -67,7 +68,6 @@ OBJS = \
main.o \
property.o \
region.o \
resource.o \
swaprep.o \
swapreq.o \
tables.o \
......
......@@ -422,6 +422,7 @@ FakeClientID(register int client)
return id;
}
#ifndef NXAGENT_SERVER
Bool
AddResource(XID id, RESTYPE type, void * value)
{
......@@ -457,6 +458,7 @@ AddResource(XID id, RESTYPE type, void * value)
rrec->expectID = id + 1;
return TRUE;
}
#endif /* NXAGENT_SERVER */
static void
RebuildTable(int client)
......@@ -507,6 +509,7 @@ RebuildTable(int client)
clientTable[client].resources = resources;
}
#ifndef NXAGENT_SERVER
void
FreeResource(XID id, RESTYPE skipDeleteFuncType)
{
......@@ -573,6 +576,7 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
}
}
}
#endif /* NXAGENT_SERVER */
/*
* Change the value associated with a resource id. Caller
......@@ -606,6 +610,7 @@ ChangeResourceValue (XID id, RESTYPE rtype, void * value)
* add and delete an equal number of resources!
*/
#ifndef NXAGENT_SERVER
void
FindClientResourcesByType(
ClientPtr client,
......@@ -693,6 +698,7 @@ LookupClientResourceComplex(
}
return NULL;
}
#endif /* NXAGENT_SERVER */
void
......
......@@ -118,31 +118,7 @@ Equipment Corporation.
*/
/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.13 2003/09/24 02:43:13 dawes Exp $ */
#define NEED_EVENTS
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <nx-X11/X.h>
#include "misc.h"
#include "os.h"
#include "resource.h"
#include "dixstruct.h"
#include "opaque.h"
#include "windowstr.h"
#include "dixfont.h"
#include "colormap.h"
#include "inputstr.h"
#include "dixevents.h"
#include "dixgrabs.h"
#include "cursor.h"
#ifdef PANORAMIX
#include "panoramiX.h"
#include "panoramiXsrv.h"
#endif
#include <assert.h>
#ifdef NXAGENT_SERVER
#include "../../dix/resource.c"
#include "Agent.h"
#include "Font.h"
......@@ -154,311 +130,11 @@ Equipment Corporation.
#undef TEST
#undef DEBUG
#endif
static void RebuildTable(
int /*client*/
);
#define SERVER_MINID 32
#define INITBUCKETS 64
#define INITHASHSIZE 6
#define MAXHASHSIZE 11
typedef struct _Resource {
struct _Resource *next;
XID id;
RESTYPE type;
void * value;
} ResourceRec, *ResourcePtr;
#define NullResource ((ResourcePtr)NULL)
typedef struct _ClientResource {
ResourcePtr *resources;
int elements;
int buckets;
int hashsize; /* log(2)(buckets) */
XID fakeID;
XID endFakeID;
XID expectID;
} ClientResourceRec;
RESTYPE lastResourceType;
static RESTYPE lastResourceClass;
RESTYPE TypeMask;
static DeleteType *DeleteFuncs = (DeleteType *)NULL;
#ifdef XResExtension
Atom * ResourceNames = NULL;
void RegisterResourceName (RESTYPE type, char *name)
{
ResourceNames[type & TypeMask] = MakeAtom(name, strlen(name), TRUE);
}
#endif
#ifdef NXAGENT_SERVER
static int nxagentResChangedFlag = 0;
#endif
RESTYPE
CreateNewResourceType(DeleteType deleteFunc)
{
RESTYPE next = lastResourceType + 1;
DeleteType *funcs;
if (next & lastResourceClass)
return 0;
funcs = (DeleteType *)xrealloc(DeleteFuncs,
(next + 1) * sizeof(DeleteType));
if (!funcs)
return 0;
#ifdef XResExtension
{
Atom *newnames;
newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
if(!newnames)
return 0;
ResourceNames = newnames;
ResourceNames[next] = 0;
}
#endif
lastResourceType = next;
DeleteFuncs = funcs;
DeleteFuncs[next] = deleteFunc;
return next;
}
RESTYPE
CreateNewResourceClass()
{
RESTYPE next = lastResourceClass >> 1;
if (next & lastResourceType)
return 0;
lastResourceClass = next;
TypeMask = next - 1;
return next;
}
ClientResourceRec clientTable[MAXCLIENTS];
/*****************
* InitClientResources
* When a new client is created, call this to allocate space
* in resource table
*****************/
Bool
InitClientResources(ClientPtr client)
{
register int i, j;
if (client == serverClient)
{
lastResourceType = RT_LASTPREDEF;
lastResourceClass = RC_LASTPREDEF;
TypeMask = RC_LASTPREDEF - 1;
if (DeleteFuncs)
xfree(DeleteFuncs);
DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
sizeof(DeleteType));
if (!DeleteFuncs)
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;
#ifdef XResExtension
if(ResourceNames)
xfree(ResourceNames);
ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
if(!ResourceNames)
return FALSE;
#endif
}
clientTable[i = client->index].resources =
(ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
if (!clientTable[i].resources)
return FALSE;
clientTable[i].buckets = INITBUCKETS;
clientTable[i].elements = 0;
clientTable[i].hashsize = INITHASHSIZE;
/* Many IDs allocated from the server client are visible to clients,
* so we don't use the SERVER_BIT for them, but we have to start
* past the magic value constants used in the protocol. For normal
* clients, we can start from zero, with SERVER_BIT set.
*/
clientTable[i].fakeID = client->clientAsMask |
(client->index ? SERVER_BIT : SERVER_MINID);
clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
clientTable[i].expectID = client->clientAsMask;
for (j=0; j<INITBUCKETS; j++)
{
clientTable[i].resources[j] = NullResource;
}
return TRUE;
}
static int
Hash(int client, register XID id)
{
id &= RESOURCE_ID_MASK;
switch (clientTable[client].hashsize)
{
case 6:
return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
case 7:
return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
case 8:
return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
case 9:
return ((int)(0x1FF & (id ^ (id>>9))));
case 10:
return ((int)(0x3FF & (id ^ (id>>10))));
case 11:
return ((int)(0x7FF & (id ^ (id>>11))));
}
return -1;
}
static XID
AvailableID(
register int client,
register XID id,
register XID maxid,
register XID goodid)
{
register ResourcePtr res;
if ((goodid >= id) && (goodid <= maxid))
return goodid;
for (; id <= maxid; id++)
{
res = clientTable[client].resources[Hash(client, id)];
while (res && (res->id != id))
res = res->next;
if (!res)
return id;
}
return 0;
}
void
GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
{
register XID id, maxid;
register ResourcePtr *resp;
register ResourcePtr res;
register int i;
XID goodid;
id = (Mask)client << CLIENTOFFSET;
if (server)
id |= client ? SERVER_BIT : SERVER_MINID;
maxid = id | RESOURCE_ID_MASK;
goodid = 0;
for (resp = clientTable[client].resources, i = clientTable[client].buckets;
--i >= 0;)
{
for (res = *resp++; res; res = res->next)
{
if ((res->id < id) || (res->id > maxid))
continue;
if (((res->id - id) >= (maxid - res->id)) ?
(goodid = AvailableID(client, id, res->id - 1, goodid)) :
!(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
maxid = res->id - 1;
else
id = res->id + 1;
}
}
if (id > maxid)
id = maxid = 0;
*minp = id;
*maxp = maxid;
}
/**
* GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
* This function tries to find count unused XIDs for the given client. It
* puts the IDs in the array pids and returns the number found, which should
* almost always be the number requested.
*
* The circumstances that lead to a call to this function are very rare.
* Xlib must run out of IDs while trying to generate a request that wants
* multiple ID's, like the Multi-buffering CreateImageBuffers request.
*
* No rocket science in the implementation; just iterate over all
* possible IDs for the given client and pick the first count IDs
* that aren't in use. A more efficient algorithm could probably be
* invented, but this will be used so rarely that this should suffice.
*/
unsigned int
GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
{
unsigned int found = 0;
XID id = pClient->clientAsMask;
XID maxid;
maxid = id | RESOURCE_ID_MASK;
while ( (found < count) && (id <= maxid) )
{
if (!LookupIDByClass(id, RC_ANY))
{
pids[found++] = id;
}
id++;
}
return found;
}
/*
* Return the next usable fake client ID.
*
* Normally this is just the next one in line, but if we've used the last
* in the range, we need to find a new range of safe IDs to avoid
* over-running another client.
*/
XID
FakeClientID(register int client)
{
XID id, maxid;
id = clientTable[client].fakeID++;
if (id != clientTable[client].endFakeID)
return id;
GetXIDRange(client, TRUE, &id, &maxid);
if (!id) {
if (!client)
FatalError("FakeClientID: server internal ids exhausted\n");
MarkClientException(clients[client]);
id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
maxid = id | RESOURCE_ID_MASK;
}
clientTable[client].fakeID = id + 1;
clientTable[client].endFakeID = maxid + 1;
return id;
}
#ifdef NXAGENT_SERVER
int nxagentFindClientResource(int client, RESTYPE type, void * value)
{
ResourcePtr pResource;
......@@ -548,8 +224,7 @@ int nxagentSwitchResourceType(int client, RESTYPE type, void * value)
return 0;
}
#endif
#endif /* NXAGENT_SERVER */
Bool
AddResource(XID id, RESTYPE type, void * value)
......@@ -602,55 +277,6 @@ AddResource(XID id, RESTYPE type, void * value)
return TRUE;
}
static void
RebuildTable(int client)
{
register int j;
register ResourcePtr res, next;
ResourcePtr **tails, *resources;
register ResourcePtr **tptr, *rptr;
/*
* For now, preserve insertion order, since some ddx layers depend
* on resources being free in the opposite order they are added.
*/
j = 2 * clientTable[client].buckets;
tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
if (!tails)
return;
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;
}
void
FreeResource(XID id, RESTYPE skipDeleteFuncType)
{
......@@ -732,32 +358,6 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
}
}
/*
* Change the value associated with a resource id. Caller
* is responsible for "doing the right thing" with the old
* data
*/
Bool
ChangeResourceValue (XID id, RESTYPE rtype, void * 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))
{
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
......@@ -988,243 +588,3 @@ RestartLoop:
}
return NULL;
}
void
FreeClientNeverRetainResources(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;
(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
xfree(this);
}
else
prev = &this->next;
}
}
}
void
FreeClientResources(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;
(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
xfree(this);
}
}
xfree(clientTable[client->index].resources);
clientTable[client->index].resources = NULL;
clientTable[client->index].buckets = 0;
}
void
FreeAllResources()
{
int i;
for (i = currentMaxClients; --i >= 0; )
{
if (clientTable[i].buckets)
FreeClientResources(clients[i]);
}
}
Bool
LegalNewID(XID id, register ClientPtr client)
{
#ifdef PANORAMIX
XID minid, maxid;
if (!noPanoramiXExtension) {
minid = client->clientAsMask | (client->index ?
SERVER_BIT : SERVER_MINID);
maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
if ((id >= minid) && (id <= maxid))
return TRUE;
}
#endif /* PANORAMIX */
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.
*/
void *
SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
{
int cid;
register ResourcePtr res;
void * 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;
}
void *
SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
{
int cid;
register ResourcePtr res = NULL;
void * 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, res->type, mode, retval);
return retval;
}
/* We can't replace the LookupIDByType and LookupIDByClass functions with
* macros because of compatibility with loadable servers.
*/
void *
LookupIDByType(XID id, RESTYPE rtype)
{
return SecurityLookupIDByType(NullClient, id, rtype,
SecurityUnknownAccess);
}
void *
LookupIDByClass(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.
*/
void *
LookupIDByType(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 (void *)NULL;
}
/*
* LookupIDByClass returns the object with the given id and any one of the
* given classes, else NULL.
*/
void *
LookupIDByClass(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 (void *)NULL;
}
#endif /* XCSECURITY */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment