dix: Refactoring of property code to allow for polyinstantiation.
Introduces dixLookupProperty() API.
This commit is contained in:
parent
c0e1959f28
commit
d5715f7bea
219
dix/property.c
219
dix/property.c
|
@ -63,11 +63,10 @@ SOFTWARE.
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
* Property Stuff
|
* Property Stuff
|
||||||
*
|
*
|
||||||
* ChangeProperty, DeleteProperty, GetProperties,
|
* dixLookupProperty, dixChangeProperty, DeleteProperty
|
||||||
* ListProperties
|
|
||||||
*
|
*
|
||||||
* Properties below to windows. A allocate slots each time
|
* Properties belong to windows. The list of properties should not be
|
||||||
* a property is added. No fancy searching done.
|
* traversed directly. Instead, use the three functions listed above.
|
||||||
*
|
*
|
||||||
*****************************************************************/
|
*****************************************************************/
|
||||||
|
|
||||||
|
@ -91,17 +90,22 @@ PrintPropertys(WindowPtr pWin)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static _X_INLINE PropertyPtr
|
_X_EXPORT int
|
||||||
FindProperty(WindowPtr pWin, Atom propertyName)
|
dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName,
|
||||||
|
ClientPtr client, Mask access_mode)
|
||||||
{
|
{
|
||||||
PropertyPtr pProp = wUserProps(pWin);
|
PropertyPtr pProp;
|
||||||
while (pProp)
|
int rc = BadMatch;
|
||||||
{
|
client->errorValue = propertyName;
|
||||||
|
|
||||||
|
for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
|
||||||
if (pProp->propertyName == propertyName)
|
if (pProp->propertyName == propertyName)
|
||||||
break;
|
break;
|
||||||
pProp = pProp->next;
|
|
||||||
}
|
if (pProp)
|
||||||
return pProp;
|
rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode);
|
||||||
|
*result = pProp;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -125,65 +129,69 @@ ProcRotateProperties(ClientPtr client)
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
Atom * atoms;
|
Atom * atoms;
|
||||||
PropertyPtr * props; /* array of pointer */
|
PropertyPtr * props; /* array of pointer */
|
||||||
PropertyPtr pProp;
|
PropertyPtr pProp, saved;
|
||||||
|
|
||||||
REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
|
REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
|
||||||
UpdateCurrentTime();
|
UpdateCurrentTime();
|
||||||
rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess);
|
rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess);
|
||||||
if (rc != Success)
|
if (rc != Success || stuff->nAtoms <= 0)
|
||||||
return rc;
|
return rc;
|
||||||
if (!stuff->nAtoms)
|
|
||||||
return(Success);
|
|
||||||
atoms = (Atom *) & stuff[1];
|
atoms = (Atom *) & stuff[1];
|
||||||
props = (PropertyPtr *)xalloc(stuff->nAtoms * sizeof(PropertyPtr));
|
props = (PropertyPtr *)xalloc(stuff->nAtoms * sizeof(PropertyPtr));
|
||||||
if (!props)
|
saved = (PropertyPtr)xalloc(stuff->nAtoms * sizeof(PropertyRec));
|
||||||
return(BadAlloc);
|
if (!props || !saved) {
|
||||||
|
rc = BadAlloc;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < stuff->nAtoms; i++)
|
for (i = 0; i < stuff->nAtoms; i++)
|
||||||
{
|
{
|
||||||
if (!ValidAtom(atoms[i])) {
|
if (!ValidAtom(atoms[i])) {
|
||||||
xfree(props);
|
rc = BadAtom;
|
||||||
client->errorValue = atoms[i];
|
client->errorValue = atoms[i];
|
||||||
return BadAtom;
|
goto out;
|
||||||
}
|
}
|
||||||
for (j = i + 1; j < stuff->nAtoms; j++)
|
for (j = i + 1; j < stuff->nAtoms; j++)
|
||||||
if (atoms[j] == atoms[i])
|
if (atoms[j] == atoms[i])
|
||||||
{
|
{
|
||||||
xfree(props);
|
rc = BadMatch;
|
||||||
return BadMatch;
|
goto out;
|
||||||
}
|
}
|
||||||
pProp = FindProperty(pWin, atoms[i]);
|
|
||||||
if (!pProp) {
|
rc = dixLookupProperty(&pProp, pWin, atoms[i], client,
|
||||||
xfree(props);
|
DixReadAccess|DixWriteAccess);
|
||||||
return BadMatch;
|
if (rc != Success)
|
||||||
}
|
goto out;
|
||||||
rc = XaceHookPropertyAccess(client, pWin, pProp,
|
|
||||||
DixReadAccess|DixWriteAccess);
|
|
||||||
if (rc != Success) {
|
|
||||||
xfree(props);
|
|
||||||
client->errorValue = atoms[i];
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
props[i] = pProp;
|
props[i] = pProp;
|
||||||
|
saved[i] = *pProp;
|
||||||
}
|
}
|
||||||
delta = stuff->nPositions;
|
delta = stuff->nPositions;
|
||||||
|
|
||||||
/* If the rotation is a complete 360 degrees, then moving the properties
|
/* If the rotation is a complete 360 degrees, then moving the properties
|
||||||
around and generating PropertyNotify events should be skipped. */
|
around and generating PropertyNotify events should be skipped. */
|
||||||
|
|
||||||
if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 )
|
if (abs(delta) % stuff->nAtoms)
|
||||||
{
|
{
|
||||||
while (delta < 0) /* faster if abs value is small */
|
while (delta < 0) /* faster if abs value is small */
|
||||||
delta += stuff->nAtoms;
|
delta += stuff->nAtoms;
|
||||||
for (i = 0; i < stuff->nAtoms; i++)
|
for (i = 0; i < stuff->nAtoms; i++)
|
||||||
{
|
{
|
||||||
deliverPropertyNotifyEvent(pWin, PropertyNewValue,
|
j = (i + delta) % stuff->nAtoms;
|
||||||
props[i]->propertyName);
|
deliverPropertyNotifyEvent(pWin, PropertyNewValue, atoms[i]);
|
||||||
|
|
||||||
props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
|
/* Preserve name and devPrivates */
|
||||||
|
props[j]->type = saved[i].type;
|
||||||
|
props[j]->format = saved[i].format;
|
||||||
|
props[j]->size = saved[i].size;
|
||||||
|
props[j]->data = saved[i].data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
|
xfree(saved);
|
||||||
xfree(props);
|
xfree(props);
|
||||||
return Success;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -253,9 +261,9 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
|
||||||
totalSize = len * sizeInBytes;
|
totalSize = len * sizeInBytes;
|
||||||
|
|
||||||
/* first see if property already exists */
|
/* first see if property already exists */
|
||||||
pProp = FindProperty(pWin, property);
|
rc = dixLookupProperty(&pProp, pWin, property, pClient, DixWriteAccess);
|
||||||
|
|
||||||
if (!pProp) /* just add to list */
|
if (rc == BadMatch) /* just add to list */
|
||||||
{
|
{
|
||||||
if (!pWin->optional && !MakeWindowOptional (pWin))
|
if (!pWin->optional && !MakeWindowOptional (pWin))
|
||||||
return(BadAlloc);
|
return(BadAlloc);
|
||||||
|
@ -287,13 +295,8 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
|
||||||
pProp->next = pWin->optional->userProps;
|
pProp->next = pWin->optional->userProps;
|
||||||
pWin->optional->userProps = pProp;
|
pWin->optional->userProps = pProp;
|
||||||
}
|
}
|
||||||
else
|
else if (rc == Success)
|
||||||
{
|
{
|
||||||
rc = XaceHookPropertyAccess(pClient, pWin, pProp, DixWriteAccess);
|
|
||||||
if (rc != Success) {
|
|
||||||
pClient->errorValue = property;
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
/* To append or prepend to a property the request format and type
|
/* To append or prepend to a property the request format and type
|
||||||
must match those of the already defined property. The
|
must match those of the already defined property. The
|
||||||
existing format and type are irrelevant when using the mode
|
existing format and type are irrelevant when using the mode
|
||||||
|
@ -347,6 +350,8 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
|
||||||
pProp->size += len;
|
pProp->size += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return rc;
|
||||||
|
|
||||||
if (sendevent)
|
if (sendevent)
|
||||||
deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName);
|
deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName);
|
||||||
|
@ -369,37 +374,29 @@ DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
|
||||||
PropertyPtr pProp, prevProp;
|
PropertyPtr pProp, prevProp;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!(pProp = wUserProps (pWin)))
|
rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess);
|
||||||
return(Success);
|
if (rc == BadMatch)
|
||||||
prevProp = (PropertyPtr)NULL;
|
return Success; /* Succeed if property does not exist */
|
||||||
while (pProp)
|
|
||||||
{
|
|
||||||
if (pProp->propertyName == propName)
|
|
||||||
break;
|
|
||||||
prevProp = pProp;
|
|
||||||
pProp = pProp->next;
|
|
||||||
}
|
|
||||||
if (pProp)
|
|
||||||
{
|
|
||||||
rc = XaceHookPropertyAccess(client, pWin, pProp, DixDestroyAccess);
|
|
||||||
if (rc != Success)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
if (prevProp == (PropertyPtr)NULL) /* takes care of head */
|
if (rc == Success) {
|
||||||
{
|
if (pWin->optional->userProps == pProp) {
|
||||||
|
/* Takes care of head */
|
||||||
if (!(pWin->optional->userProps = pProp->next))
|
if (!(pWin->optional->userProps = pProp->next))
|
||||||
CheckWindowOptionalNeed (pWin);
|
CheckWindowOptionalNeed (pWin);
|
||||||
}
|
} else {
|
||||||
else
|
/* Need to traverse to find the previous element */
|
||||||
{
|
prevProp = pWin->optional->userProps;
|
||||||
prevProp->next = pProp->next;
|
while (prevProp->next != pProp)
|
||||||
}
|
prevProp = prevProp->next;
|
||||||
|
prevProp->next = pProp->next;
|
||||||
|
}
|
||||||
|
|
||||||
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName);
|
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName);
|
||||||
dixFreePrivates(pProp->devPrivates);
|
dixFreePrivates(pProp->devPrivates);
|
||||||
xfree(pProp->data);
|
xfree(pProp->data);
|
||||||
xfree(pProp);
|
xfree(pProp);
|
||||||
}
|
}
|
||||||
return(Success);
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -453,15 +450,16 @@ ProcGetProperty(ClientPtr client)
|
||||||
int rc;
|
int rc;
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
xGetPropertyReply reply;
|
xGetPropertyReply reply;
|
||||||
Mask access_mode = DixGetPropAccess;
|
Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess;
|
||||||
REQUEST(xGetPropertyReq);
|
REQUEST(xGetPropertyReq);
|
||||||
|
|
||||||
REQUEST_SIZE_MATCH(xGetPropertyReq);
|
REQUEST_SIZE_MATCH(xGetPropertyReq);
|
||||||
if (stuff->delete) {
|
if (stuff->delete) {
|
||||||
UpdateCurrentTime();
|
UpdateCurrentTime();
|
||||||
access_mode |= DixSetPropAccess;
|
win_mode |= DixSetPropAccess;
|
||||||
|
prop_mode |= DixDestroyAccess;
|
||||||
}
|
}
|
||||||
rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
|
rc = dixLookupWindow(&pWin, stuff->window, client, win_mode);
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
@ -481,30 +479,14 @@ ProcGetProperty(ClientPtr client)
|
||||||
return(BadAtom);
|
return(BadAtom);
|
||||||
}
|
}
|
||||||
|
|
||||||
pProp = wUserProps (pWin);
|
|
||||||
prevProp = (PropertyPtr)NULL;
|
|
||||||
while (pProp)
|
|
||||||
{
|
|
||||||
if (pProp->propertyName == stuff->property)
|
|
||||||
break;
|
|
||||||
prevProp = pProp;
|
|
||||||
pProp = pProp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
reply.type = X_Reply;
|
reply.type = X_Reply;
|
||||||
reply.sequenceNumber = client->sequence;
|
reply.sequenceNumber = client->sequence;
|
||||||
if (!pProp)
|
|
||||||
|
rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode);
|
||||||
|
if (rc == BadMatch)
|
||||||
return NullPropertyReply(client, None, 0, &reply);
|
return NullPropertyReply(client, None, 0, &reply);
|
||||||
|
else if (rc != Success)
|
||||||
access_mode = DixReadAccess;
|
|
||||||
if (stuff->delete)
|
|
||||||
access_mode |= DixDestroyAccess;
|
|
||||||
|
|
||||||
rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode);
|
|
||||||
if (rc != Success) {
|
|
||||||
client->errorValue = stuff->property;
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
/* If the request type and actual type don't match. Return the
|
/* If the request type and actual type don't match. Return the
|
||||||
property information, but not the data. */
|
property information, but not the data. */
|
||||||
|
@ -560,15 +542,20 @@ ProcGetProperty(ClientPtr client)
|
||||||
(char *)pProp->data + ind);
|
(char *)pProp->data + ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stuff->delete && (reply.bytesAfter == 0))
|
if (stuff->delete && (reply.bytesAfter == 0)) {
|
||||||
{ /* delete the Property */
|
/* Delete the Property */
|
||||||
if (prevProp == (PropertyPtr)NULL) /* takes care of head */
|
if (pWin->optional->userProps == pProp) {
|
||||||
{
|
/* Takes care of head */
|
||||||
if (!(pWin->optional->userProps = pProp->next))
|
if (!(pWin->optional->userProps = pProp->next))
|
||||||
CheckWindowOptionalNeed (pWin);
|
CheckWindowOptionalNeed (pWin);
|
||||||
}
|
} else {
|
||||||
else
|
/* Need to traverse to find the previous element */
|
||||||
|
prevProp = pWin->optional->userProps;
|
||||||
|
while (prevProp->next != pProp)
|
||||||
|
prevProp = prevProp->next;
|
||||||
prevProp->next = pProp->next;
|
prevProp->next = pProp->next;
|
||||||
|
}
|
||||||
|
|
||||||
dixFreePrivates(pProp->devPrivates);
|
dixFreePrivates(pProp->devPrivates);
|
||||||
xfree(pProp->data);
|
xfree(pProp->data);
|
||||||
xfree(pProp);
|
xfree(pProp);
|
||||||
|
@ -583,7 +570,7 @@ ProcListProperties(ClientPtr client)
|
||||||
xListPropertiesReply xlpr;
|
xListPropertiesReply xlpr;
|
||||||
int rc, numProps = 0;
|
int rc, numProps = 0;
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
PropertyPtr pProp;
|
PropertyPtr pProp, realProp;
|
||||||
REQUEST(xResourceReq);
|
REQUEST(xResourceReq);
|
||||||
|
|
||||||
REQUEST_SIZE_MATCH(xResourceReq);
|
REQUEST_SIZE_MATCH(xResourceReq);
|
||||||
|
@ -591,34 +578,34 @@ ProcListProperties(ClientPtr client)
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
pProp = wUserProps (pWin);
|
for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
|
||||||
while (pProp)
|
|
||||||
{
|
|
||||||
pProp = pProp->next;
|
|
||||||
numProps++;
|
numProps++;
|
||||||
|
|
||||||
|
if (numProps && !(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom))))
|
||||||
|
return BadAlloc;
|
||||||
|
|
||||||
|
numProps = 0;
|
||||||
|
temppAtoms = pAtoms;
|
||||||
|
for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) {
|
||||||
|
realProp = pProp;
|
||||||
|
rc = XaceHookPropertyAccess(client, pWin, pProp, DixGetAttrAccess);
|
||||||
|
if (rc == Success && realProp == pProp) {
|
||||||
|
*temppAtoms++ = pProp->propertyName;
|
||||||
|
numProps++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (numProps)
|
|
||||||
if(!(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom))))
|
|
||||||
return(BadAlloc);
|
|
||||||
|
|
||||||
xlpr.type = X_Reply;
|
xlpr.type = X_Reply;
|
||||||
xlpr.nProperties = numProps;
|
xlpr.nProperties = numProps;
|
||||||
xlpr.length = (numProps * sizeof(Atom)) >> 2;
|
xlpr.length = (numProps * sizeof(Atom)) >> 2;
|
||||||
xlpr.sequenceNumber = client->sequence;
|
xlpr.sequenceNumber = client->sequence;
|
||||||
pProp = wUserProps (pWin);
|
|
||||||
temppAtoms = pAtoms;
|
|
||||||
while (pProp)
|
|
||||||
{
|
|
||||||
*temppAtoms++ = pProp->propertyName;
|
|
||||||
pProp = pProp->next;
|
|
||||||
}
|
|
||||||
WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
|
WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
|
||||||
if (numProps)
|
if (numProps)
|
||||||
{
|
{
|
||||||
client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
|
client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
|
||||||
WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
|
WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
|
||||||
xfree(pAtoms);
|
|
||||||
}
|
}
|
||||||
|
xfree(pAtoms);
|
||||||
return(client->noClientException);
|
return(client->noClientException);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,6 +193,7 @@ _X_HIDDEN void *dixLookupTab[] = {
|
||||||
SYMFUNC(XineramaGetCursorScreen)
|
SYMFUNC(XineramaGetCursorScreen)
|
||||||
#endif
|
#endif
|
||||||
/* property.c */
|
/* property.c */
|
||||||
|
SYMFUNC(dixLookupProperty)
|
||||||
SYMFUNC(ChangeWindowProperty)
|
SYMFUNC(ChangeWindowProperty)
|
||||||
SYMFUNC(dixChangeWindowProperty)
|
SYMFUNC(dixChangeWindowProperty)
|
||||||
/* extension.c */
|
/* extension.c */
|
||||||
|
|
|
@ -52,6 +52,13 @@ SOFTWARE.
|
||||||
|
|
||||||
typedef struct _Property *PropertyPtr;
|
typedef struct _Property *PropertyPtr;
|
||||||
|
|
||||||
|
extern int dixLookupProperty(
|
||||||
|
PropertyPtr * /*result*/,
|
||||||
|
WindowPtr /*pWin*/,
|
||||||
|
Atom /*proprty*/,
|
||||||
|
ClientPtr /*pClient*/,
|
||||||
|
Mask /*access_mode*/);
|
||||||
|
|
||||||
extern int dixChangeWindowProperty(
|
extern int dixChangeWindowProperty(
|
||||||
ClientPtr /*pClient*/,
|
ClientPtr /*pClient*/,
|
||||||
WindowPtr /*pWin*/,
|
WindowPtr /*pWin*/,
|
||||||
|
|
Loading…
Reference in New Issue