From d5715f7beaad6816db27b01b67d7a3c69164d106 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Fri, 29 Feb 2008 16:16:12 -0500 Subject: dix: Refactoring of property code to allow for polyinstantiation. Introduces dixLookupProperty() API. --- dix/property.c | 221 +++++++++++++++++++++++++++------------------------------ 1 file changed, 104 insertions(+), 117 deletions(-) (limited to 'dix/property.c') diff --git a/dix/property.c b/dix/property.c index ce6116992..e74becfa2 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); } -- cgit v1.2.3