[PATCH 1/4] dix: Refactoring of property code to allow for polyinstantiation.
Eamon Walsh
ewalsh at tycho.nsa.gov
Wed Feb 27 20:41:45 PST 2008
Signed-off-by: Eamon Walsh <ewalsh at moss-charon.epoch.ncsc.mil>
---
dix/property.c | 221 +++++++++++++++++++++-----------------------
hw/xfree86/loader/dixsym.c | 1 +
include/property.h | 7 ++
3 files changed, 112 insertions(+), 117 deletions(-)
diff --git a/dix/property.c b/dix/property.c
index ce61169..e74becf 100644
--- a/dix/property.c
+++ b/dix/property.c
@@ -63,11 +63,10 @@ SOFTWARE.
/*****************************************************************
* Property Stuff
*
- * ChangeProperty, DeleteProperty, GetProperties,
- * ListProperties
+ * dixLookupProperty, dixChangeProperty, DeleteProperty
*
- * Properties below to windows. A allocate slots each time
- * a property is added. No fancy searching done.
+ * Properties belong to windows. The list of properties should not be
+ * traversed directly. Instead, use the three functions listed above.
*
*****************************************************************/
@@ -91,17 +90,22 @@ PrintPropertys(WindowPtr pWin)
}
#endif
-static _X_INLINE PropertyPtr
-FindProperty(WindowPtr pWin, Atom propertyName)
+_X_EXPORT int
+dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName,
+ ClientPtr client, Mask access_mode)
{
- PropertyPtr pProp = wUserProps(pWin);
- while (pProp)
- {
+ PropertyPtr pProp;
+ int rc = BadMatch;
+ client->errorValue = propertyName;
+
+ for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
if (pProp->propertyName == propertyName)
break;
- pProp = pProp->next;
- }
- return pProp;
+
+ if (pProp)
+ rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode);
+ *result = pProp;
+ return rc;
}
static void
@@ -125,65 +129,69 @@ ProcRotateProperties(ClientPtr client)
WindowPtr pWin;
Atom * atoms;
PropertyPtr * props; /* array of pointer */
- PropertyPtr pProp;
+ PropertyPtr pProp, saved;
REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
UpdateCurrentTime();
rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess);
- if (rc != Success)
+ if (rc != Success || stuff->nAtoms <= 0)
return rc;
- if (!stuff->nAtoms)
- return(Success);
+
atoms = (Atom *) & stuff[1];
props = (PropertyPtr *)xalloc(stuff->nAtoms * sizeof(PropertyPtr));
- if (!props)
- return(BadAlloc);
+ saved = (PropertyPtr)xalloc(stuff->nAtoms * sizeof(PropertyRec));
+ if (!props || !saved) {
+ rc = BadAlloc;
+ goto out;
+ }
+
for (i = 0; i < stuff->nAtoms; i++)
{
if (!ValidAtom(atoms[i])) {
- xfree(props);
+ rc = BadAtom;
client->errorValue = atoms[i];
- return BadAtom;
+ goto out;
}
for (j = i + 1; j < stuff->nAtoms; j++)
if (atoms[j] == atoms[i])
{
- xfree(props);
- return BadMatch;
+ rc = BadMatch;
+ goto out;
}
- pProp = FindProperty(pWin, atoms[i]);
- if (!pProp) {
- xfree(props);
- return BadMatch;
- }
- rc = XaceHookPropertyAccess(client, pWin, pProp,
- DixReadAccess|DixWriteAccess);
- if (rc != Success) {
- xfree(props);
- client->errorValue = atoms[i];
- return rc;
- }
+
+ rc = dixLookupProperty(&pProp, pWin, atoms[i], client,
+ DixReadAccess|DixWriteAccess);
+ if (rc != Success)
+ goto out;
+
props[i] = pProp;
+ saved[i] = *pProp;
}
delta = stuff->nPositions;
/* If the rotation is a complete 360 degrees, then moving the properties
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 */
delta += stuff->nAtoms;
for (i = 0; i < stuff->nAtoms; i++)
{
- deliverPropertyNotifyEvent(pWin, PropertyNewValue,
- props[i]->propertyName);
-
- props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+ j = (i + delta) % stuff->nAtoms;
+ deliverPropertyNotifyEvent(pWin, PropertyNewValue, atoms[i]);
+
+ /* 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);
- return Success;
+ return rc;
}
int
@@ -253,9 +261,9 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
totalSize = len * sizeInBytes;
/* 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))
return(BadAlloc);
@@ -287,13 +295,8 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
pProp->next = pWin->optional->userProps;
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
must match those of the already defined property. The
existing format and type are irrelevant when using the mode
@@ -347,6 +350,8 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
pProp->size += len;
}
}
+ else
+ return rc;
if (sendevent)
deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName);
@@ -369,37 +374,29 @@ DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
PropertyPtr pProp, prevProp;
int rc;
- if (!(pProp = wUserProps (pWin)))
- return(Success);
- prevProp = (PropertyPtr)NULL;
- 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;
+ rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess);
+ if (rc == BadMatch)
+ return Success; /* Succeed if property does not exist */
- 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))
CheckWindowOptionalNeed (pWin);
- }
- else
- {
- prevProp->next = pProp->next;
- }
+ } else {
+ /* Need to traverse to find the previous element */
+ prevProp = pWin->optional->userProps;
+ while (prevProp->next != pProp)
+ prevProp = prevProp->next;
+ prevProp->next = pProp->next;
+ }
+
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName);
dixFreePrivates(pProp->devPrivates);
xfree(pProp->data);
xfree(pProp);
}
- return(Success);
+ return rc;
}
void
@@ -453,15 +450,16 @@ ProcGetProperty(ClientPtr client)
int rc;
WindowPtr pWin;
xGetPropertyReply reply;
- Mask access_mode = DixGetPropAccess;
+ Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess;
REQUEST(xGetPropertyReq);
REQUEST_SIZE_MATCH(xGetPropertyReq);
if (stuff->delete) {
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)
return rc;
@@ -481,30 +479,14 @@ ProcGetProperty(ClientPtr client)
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.sequenceNumber = client->sequence;
- if (!pProp)
- return NullPropertyReply(client, None, 0, &reply);
- access_mode = DixReadAccess;
- if (stuff->delete)
- access_mode |= DixDestroyAccess;
-
- rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode);
- if (rc != Success) {
- client->errorValue = stuff->property;
+ rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode);
+ if (rc == BadMatch)
+ return NullPropertyReply(client, None, 0, &reply);
+ else if (rc != Success)
return rc;
- }
/* If the request type and actual type don't match. Return the
property information, but not the data. */
@@ -560,15 +542,20 @@ ProcGetProperty(ClientPtr client)
(char *)pProp->data + ind);
}
- if (stuff->delete && (reply.bytesAfter == 0))
- { /* delete the Property */
- if (prevProp == (PropertyPtr)NULL) /* takes care of head */
- {
- if (!(pWin->optional->userProps = pProp->next))
+ if (stuff->delete && (reply.bytesAfter == 0)) {
+ /* Delete the Property */
+ if (pWin->optional->userProps == pProp) {
+ /* Takes care of head */
+ if (!(pWin->optional->userProps = pProp->next))
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;
+ }
+
dixFreePrivates(pProp->devPrivates);
xfree(pProp->data);
xfree(pProp);
@@ -583,7 +570,7 @@ ProcListProperties(ClientPtr client)
xListPropertiesReply xlpr;
int rc, numProps = 0;
WindowPtr pWin;
- PropertyPtr pProp;
+ PropertyPtr pProp, realProp;
REQUEST(xResourceReq);
REQUEST_SIZE_MATCH(xResourceReq);
@@ -591,34 +578,34 @@ ProcListProperties(ClientPtr client)
if (rc != Success)
return rc;
- pProp = wUserProps (pWin);
- while (pProp)
- {
- pProp = pProp->next;
+ for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
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.nProperties = numProps;
xlpr.length = (numProps * sizeof(Atom)) >> 2;
xlpr.sequenceNumber = client->sequence;
- pProp = wUserProps (pWin);
- temppAtoms = pAtoms;
- while (pProp)
- {
- *temppAtoms++ = pProp->propertyName;
- pProp = pProp->next;
- }
WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
if (numProps)
{
client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
- xfree(pAtoms);
}
+ xfree(pAtoms);
return(client->noClientException);
}
diff --git a/hw/xfree86/loader/dixsym.c b/hw/xfree86/loader/dixsym.c
index 49c7d27..e6c37fe 100644
--- a/hw/xfree86/loader/dixsym.c
+++ b/hw/xfree86/loader/dixsym.c
@@ -193,6 +193,7 @@ _X_HIDDEN void *dixLookupTab[] = {
SYMFUNC(XineramaGetCursorScreen)
#endif
/* property.c */
+ SYMFUNC(dixLookupProperty)
SYMFUNC(ChangeWindowProperty)
SYMFUNC(dixChangeWindowProperty)
/* extension.c */
diff --git a/include/property.h b/include/property.h
index ba7d226..1207e81 100644
--- a/include/property.h
+++ b/include/property.h
@@ -52,6 +52,13 @@ SOFTWARE.
typedef struct _Property *PropertyPtr;
+extern int dixLookupProperty(
+ PropertyPtr * /*result*/,
+ WindowPtr /*pWin*/,
+ Atom /*proprty*/,
+ ClientPtr /*pClient*/,
+ Mask /*access_mode*/);
+
extern int dixChangeWindowProperty(
ClientPtr /*pClient*/,
WindowPtr /*pWin*/,
--
1.5.4.3
More information about the xorg
mailing list