property.c revision 9ace9065
105b261ecSmrg/*********************************************************** 205b261ecSmrg 305b261ecSmrgCopyright 1987, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg 2505b261ecSmrg 2605b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 2705b261ecSmrg 2805b261ecSmrg All Rights Reserved 2905b261ecSmrg 3005b261ecSmrgPermission to use, copy, modify, and distribute this software and its 3105b261ecSmrgdocumentation for any purpose and without fee is hereby granted, 3205b261ecSmrgprovided that the above copyright notice appear in all copies and that 3305b261ecSmrgboth that copyright notice and this permission notice appear in 3405b261ecSmrgsupporting documentation, and that the name of Digital not be 3505b261ecSmrgused in advertising or publicity pertaining to distribution of the 3605b261ecSmrgsoftware without specific, written prior permission. 3705b261ecSmrg 3805b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3905b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 4005b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4105b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4205b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4305b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4405b261ecSmrgSOFTWARE. 4505b261ecSmrg 4605b261ecSmrg******************************************************************/ 4705b261ecSmrg 4805b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 4905b261ecSmrg#include <dix-config.h> 5005b261ecSmrg#endif 5105b261ecSmrg 5205b261ecSmrg#include <X11/X.h> 5305b261ecSmrg#include <X11/Xproto.h> 5405b261ecSmrg#include "windowstr.h" 5505b261ecSmrg#include "propertyst.h" 5605b261ecSmrg#include "dixstruct.h" 5705b261ecSmrg#include "dispatch.h" 5805b261ecSmrg#include "swaprep.h" 5905b261ecSmrg#include "xace.h" 6005b261ecSmrg 6105b261ecSmrg/***************************************************************** 6205b261ecSmrg * Property Stuff 6305b261ecSmrg * 644642e01fSmrg * dixLookupProperty, dixChangeProperty, DeleteProperty 6505b261ecSmrg * 664642e01fSmrg * Properties belong to windows. The list of properties should not be 674642e01fSmrg * traversed directly. Instead, use the three functions listed above. 6805b261ecSmrg * 6905b261ecSmrg *****************************************************************/ 7005b261ecSmrg 7105b261ecSmrg#ifdef notdef 7205b261ecSmrgstatic void 7305b261ecSmrgPrintPropertys(WindowPtr pWin) 7405b261ecSmrg{ 7505b261ecSmrg PropertyPtr pProp; 7605b261ecSmrg int j; 7705b261ecSmrg 7805b261ecSmrg pProp = pWin->userProps; 7905b261ecSmrg while (pProp) 8005b261ecSmrg { 814642e01fSmrg ErrorF("[dix] %x %x\n", pProp->propertyName, pProp->type); 824642e01fSmrg ErrorF("[dix] property format: %d\n", pProp->format); 834642e01fSmrg ErrorF("[dix] property data: \n"); 8405b261ecSmrg for (j=0; j<(pProp->format/8)*pProp->size; j++) 854642e01fSmrg ErrorF("[dix] %c\n", pProp->data[j]); 8605b261ecSmrg pProp = pProp->next; 8705b261ecSmrg } 8805b261ecSmrg} 8905b261ecSmrg#endif 9005b261ecSmrg 916747b715Smrgint 924642e01fSmrgdixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName, 934642e01fSmrg ClientPtr client, Mask access_mode) 944642e01fSmrg{ 954642e01fSmrg PropertyPtr pProp; 964642e01fSmrg int rc = BadMatch; 974642e01fSmrg client->errorValue = propertyName; 984642e01fSmrg 994642e01fSmrg for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) 1004642e01fSmrg if (pProp->propertyName == propertyName) 1014642e01fSmrg break; 1024642e01fSmrg 1034642e01fSmrg if (pProp) 1044642e01fSmrg rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode); 1054642e01fSmrg *result = pProp; 1064642e01fSmrg return rc; 1074642e01fSmrg} 1084642e01fSmrg 10905b261ecSmrgstatic void 11005b261ecSmrgdeliverPropertyNotifyEvent(WindowPtr pWin, int state, Atom atom) 11105b261ecSmrg{ 11205b261ecSmrg xEvent event; 11305b261ecSmrg 1146747b715Smrg memset(&event, 0, sizeof(xEvent)); 11505b261ecSmrg event.u.u.type = PropertyNotify; 11605b261ecSmrg event.u.property.window = pWin->drawable.id; 11705b261ecSmrg event.u.property.state = state; 11805b261ecSmrg event.u.property.atom = atom; 11905b261ecSmrg event.u.property.time = currentTime.milliseconds; 12005b261ecSmrg DeliverEvents(pWin, &event, 1, (WindowPtr)NULL); 12105b261ecSmrg} 12205b261ecSmrg 12305b261ecSmrgint 12405b261ecSmrgProcRotateProperties(ClientPtr client) 12505b261ecSmrg{ 12605b261ecSmrg int i, j, delta, rc; 12705b261ecSmrg REQUEST(xRotatePropertiesReq); 12805b261ecSmrg WindowPtr pWin; 12905b261ecSmrg Atom * atoms; 13005b261ecSmrg PropertyPtr * props; /* array of pointer */ 1314642e01fSmrg PropertyPtr pProp, saved; 13205b261ecSmrg 13305b261ecSmrg REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2); 13405b261ecSmrg UpdateCurrentTime(); 1354642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); 1364642e01fSmrg if (rc != Success || stuff->nAtoms <= 0) 13705b261ecSmrg return rc; 1384642e01fSmrg 13905b261ecSmrg atoms = (Atom *) & stuff[1]; 1406747b715Smrg props = malloc(stuff->nAtoms * sizeof(PropertyPtr)); 1416747b715Smrg saved = malloc(stuff->nAtoms * sizeof(PropertyRec)); 1424642e01fSmrg if (!props || !saved) { 1434642e01fSmrg rc = BadAlloc; 1444642e01fSmrg goto out; 1454642e01fSmrg } 1464642e01fSmrg 14705b261ecSmrg for (i = 0; i < stuff->nAtoms; i++) 14805b261ecSmrg { 1494642e01fSmrg if (!ValidAtom(atoms[i])) { 1504642e01fSmrg rc = BadAtom; 15105b261ecSmrg client->errorValue = atoms[i]; 1524642e01fSmrg goto out; 15305b261ecSmrg } 15405b261ecSmrg for (j = i + 1; j < stuff->nAtoms; j++) 15505b261ecSmrg if (atoms[j] == atoms[i]) 15605b261ecSmrg { 1574642e01fSmrg rc = BadMatch; 1584642e01fSmrg goto out; 15905b261ecSmrg } 1604642e01fSmrg 1614642e01fSmrg rc = dixLookupProperty(&pProp, pWin, atoms[i], client, 1624642e01fSmrg DixReadAccess|DixWriteAccess); 1634642e01fSmrg if (rc != Success) 1644642e01fSmrg goto out; 1654642e01fSmrg 16605b261ecSmrg props[i] = pProp; 1674642e01fSmrg saved[i] = *pProp; 16805b261ecSmrg } 16905b261ecSmrg delta = stuff->nPositions; 17005b261ecSmrg 17105b261ecSmrg /* If the rotation is a complete 360 degrees, then moving the properties 17205b261ecSmrg around and generating PropertyNotify events should be skipped. */ 17305b261ecSmrg 1744642e01fSmrg if (abs(delta) % stuff->nAtoms) 17505b261ecSmrg { 17605b261ecSmrg while (delta < 0) /* faster if abs value is small */ 17705b261ecSmrg delta += stuff->nAtoms; 17805b261ecSmrg for (i = 0; i < stuff->nAtoms; i++) 17905b261ecSmrg { 1804642e01fSmrg j = (i + delta) % stuff->nAtoms; 1814642e01fSmrg deliverPropertyNotifyEvent(pWin, PropertyNewValue, atoms[i]); 1824642e01fSmrg 1834642e01fSmrg /* Preserve name and devPrivates */ 1844642e01fSmrg props[j]->type = saved[i].type; 1854642e01fSmrg props[j]->format = saved[i].format; 1864642e01fSmrg props[j]->size = saved[i].size; 1874642e01fSmrg props[j]->data = saved[i].data; 18805b261ecSmrg } 18905b261ecSmrg } 1904642e01fSmrgout: 1916747b715Smrg free(saved); 1926747b715Smrg free(props); 1934642e01fSmrg return rc; 19405b261ecSmrg} 19505b261ecSmrg 19605b261ecSmrgint 19705b261ecSmrgProcChangeProperty(ClientPtr client) 19805b261ecSmrg{ 19905b261ecSmrg WindowPtr pWin; 20005b261ecSmrg char format, mode; 20105b261ecSmrg unsigned long len; 20205b261ecSmrg int sizeInBytes, totalSize, err; 20305b261ecSmrg REQUEST(xChangePropertyReq); 20405b261ecSmrg 20505b261ecSmrg REQUEST_AT_LEAST_SIZE(xChangePropertyReq); 20605b261ecSmrg UpdateCurrentTime(); 20705b261ecSmrg format = stuff->format; 20805b261ecSmrg mode = stuff->mode; 20905b261ecSmrg if ((mode != PropModeReplace) && (mode != PropModeAppend) && 21005b261ecSmrg (mode != PropModePrepend)) 21105b261ecSmrg { 21205b261ecSmrg client->errorValue = mode; 21305b261ecSmrg return BadValue; 21405b261ecSmrg } 21505b261ecSmrg if ((format != 8) && (format != 16) && (format != 32)) 21605b261ecSmrg { 21705b261ecSmrg client->errorValue = format; 21805b261ecSmrg return BadValue; 21905b261ecSmrg } 22005b261ecSmrg len = stuff->nUnits; 2216747b715Smrg if (len > bytes_to_int32(0xffffffff - sizeof(xChangePropertyReq))) 22205b261ecSmrg return BadLength; 22305b261ecSmrg sizeInBytes = format>>3; 22405b261ecSmrg totalSize = len * sizeInBytes; 22505b261ecSmrg REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize); 22605b261ecSmrg 2274642e01fSmrg err = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); 22805b261ecSmrg if (err != Success) 22905b261ecSmrg return err; 23005b261ecSmrg if (!ValidAtom(stuff->property)) 23105b261ecSmrg { 23205b261ecSmrg client->errorValue = stuff->property; 2336747b715Smrg return BadAtom; 23405b261ecSmrg } 23505b261ecSmrg if (!ValidAtom(stuff->type)) 23605b261ecSmrg { 23705b261ecSmrg client->errorValue = stuff->type; 2386747b715Smrg return BadAtom; 23905b261ecSmrg } 24005b261ecSmrg 2414642e01fSmrg err = dixChangeWindowProperty(client, pWin, stuff->property, stuff->type, 2424642e01fSmrg (int)format, (int)mode, len, &stuff[1], 2434642e01fSmrg TRUE); 24405b261ecSmrg if (err != Success) 24505b261ecSmrg return err; 24605b261ecSmrg else 2476747b715Smrg return Success; 24805b261ecSmrg} 24905b261ecSmrg 2506747b715Smrgint 2514642e01fSmrgdixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, 2524642e01fSmrg Atom type, int format, int mode, unsigned long len, 2534642e01fSmrg pointer value, Bool sendevent) 25405b261ecSmrg{ 25505b261ecSmrg PropertyPtr pProp; 2566747b715Smrg PropertyRec savedProp; 2574642e01fSmrg int sizeInBytes, totalSize, rc; 2586747b715Smrg unsigned char *data; 2594642e01fSmrg Mask access_mode; 26005b261ecSmrg 26105b261ecSmrg sizeInBytes = format>>3; 26205b261ecSmrg totalSize = len * sizeInBytes; 2634642e01fSmrg access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess; 26405b261ecSmrg 26505b261ecSmrg /* first see if property already exists */ 2664642e01fSmrg rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode); 26705b261ecSmrg 2684642e01fSmrg if (rc == BadMatch) /* just add to list */ 26905b261ecSmrg { 27005b261ecSmrg if (!pWin->optional && !MakeWindowOptional (pWin)) 2716747b715Smrg return BadAlloc; 2726747b715Smrg pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY); 27305b261ecSmrg if (!pProp) 2746747b715Smrg return BadAlloc; 2756747b715Smrg data = malloc(totalSize); 27605b261ecSmrg if (!data && len) 27705b261ecSmrg { 2786747b715Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 2796747b715Smrg return BadAlloc; 28005b261ecSmrg } 2816747b715Smrg memcpy(data, value, totalSize); 28205b261ecSmrg pProp->propertyName = property; 28305b261ecSmrg pProp->type = type; 28405b261ecSmrg pProp->format = format; 28505b261ecSmrg pProp->data = data; 28605b261ecSmrg pProp->size = len; 2874642e01fSmrg rc = XaceHookPropertyAccess(pClient, pWin, &pProp, 2884642e01fSmrg DixCreateAccess|DixWriteAccess); 2894642e01fSmrg if (rc != Success) { 2906747b715Smrg free(data); 2916747b715Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 2924642e01fSmrg pClient->errorValue = property; 2934642e01fSmrg return rc; 2944642e01fSmrg } 29505b261ecSmrg pProp->next = pWin->optional->userProps; 29605b261ecSmrg pWin->optional->userProps = pProp; 29705b261ecSmrg } 2984642e01fSmrg else if (rc == Success) 29905b261ecSmrg { 30005b261ecSmrg /* To append or prepend to a property the request format and type 30105b261ecSmrg must match those of the already defined property. The 30205b261ecSmrg existing format and type are irrelevant when using the mode 30305b261ecSmrg "PropModeReplace" since they will be written over. */ 30405b261ecSmrg 30505b261ecSmrg if ((format != pProp->format) && (mode != PropModeReplace)) 3066747b715Smrg return BadMatch; 30705b261ecSmrg if ((pProp->type != type) && (mode != PropModeReplace)) 3086747b715Smrg return BadMatch; 3096747b715Smrg 3106747b715Smrg /* save the old values for later */ 3116747b715Smrg savedProp = *pProp; 3126747b715Smrg 31305b261ecSmrg if (mode == PropModeReplace) 31405b261ecSmrg { 3156747b715Smrg data = malloc(totalSize); 3166747b715Smrg if (!data && len) 3176747b715Smrg return BadAlloc; 3186747b715Smrg memcpy(data, value, totalSize); 3196747b715Smrg pProp->data = data; 32005b261ecSmrg pProp->size = len; 32105b261ecSmrg pProp->type = type; 32205b261ecSmrg pProp->format = format; 32305b261ecSmrg } 32405b261ecSmrg else if (len == 0) 32505b261ecSmrg { 32605b261ecSmrg /* do nothing */ 32705b261ecSmrg } 32805b261ecSmrg else if (mode == PropModeAppend) 32905b261ecSmrg { 3306747b715Smrg data = malloc((pProp->size + len) * sizeInBytes); 33105b261ecSmrg if (!data) 3326747b715Smrg return BadAlloc; 3336747b715Smrg memcpy(data, pProp->data, pProp->size * sizeInBytes); 3346747b715Smrg memcpy(data + pProp->size * sizeInBytes, value, totalSize); 33505b261ecSmrg pProp->data = data; 33605b261ecSmrg pProp->size += len; 33705b261ecSmrg } 33805b261ecSmrg else if (mode == PropModePrepend) 33905b261ecSmrg { 3406747b715Smrg data = malloc(sizeInBytes * (len + pProp->size)); 34105b261ecSmrg if (!data) 3426747b715Smrg return BadAlloc; 3436747b715Smrg memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes); 3446747b715Smrg memcpy(data, value, totalSize); 34505b261ecSmrg pProp->data = data; 34605b261ecSmrg pProp->size += len; 34705b261ecSmrg } 3486747b715Smrg 3496747b715Smrg /* Allow security modules to check the new content */ 3506747b715Smrg access_mode |= DixPostAccess; 3516747b715Smrg rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode); 3526747b715Smrg if (rc == Success) 3536747b715Smrg { 3546747b715Smrg if (savedProp.data != pProp->data) 3556747b715Smrg free(savedProp.data); 3566747b715Smrg } 3576747b715Smrg else 3586747b715Smrg { 3596747b715Smrg if (savedProp.data != pProp->data) 3606747b715Smrg free(pProp->data); 3616747b715Smrg *pProp = savedProp; 3626747b715Smrg return rc; 3636747b715Smrg } 36405b261ecSmrg } 3654642e01fSmrg else 3664642e01fSmrg return rc; 36705b261ecSmrg 36805b261ecSmrg if (sendevent) 36905b261ecSmrg deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName); 37005b261ecSmrg 3716747b715Smrg return Success; 37205b261ecSmrg} 37305b261ecSmrg 3746747b715Smrgint 3754642e01fSmrgChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format, 3764642e01fSmrg int mode, unsigned long len, pointer value, 3774642e01fSmrg Bool sendevent) 3784642e01fSmrg{ 3794642e01fSmrg return dixChangeWindowProperty(serverClient, pWin, property, type, format, 3804642e01fSmrg mode, len, value, sendevent); 3814642e01fSmrg} 3824642e01fSmrg 38305b261ecSmrgint 3844642e01fSmrgDeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName) 38505b261ecSmrg{ 38605b261ecSmrg PropertyPtr pProp, prevProp; 3874642e01fSmrg int rc; 38805b261ecSmrg 3894642e01fSmrg rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess); 3904642e01fSmrg if (rc == BadMatch) 3914642e01fSmrg return Success; /* Succeed if property does not exist */ 3924642e01fSmrg 3934642e01fSmrg if (rc == Success) { 3944642e01fSmrg if (pWin->optional->userProps == pProp) { 3954642e01fSmrg /* Takes care of head */ 39605b261ecSmrg if (!(pWin->optional->userProps = pProp->next)) 39705b261ecSmrg CheckWindowOptionalNeed (pWin); 3984642e01fSmrg } else { 3994642e01fSmrg /* Need to traverse to find the previous element */ 4004642e01fSmrg prevProp = pWin->optional->userProps; 4014642e01fSmrg while (prevProp->next != pProp) 4024642e01fSmrg prevProp = prevProp->next; 4034642e01fSmrg prevProp->next = pProp->next; 4044642e01fSmrg } 4054642e01fSmrg 40605b261ecSmrg deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); 4076747b715Smrg free(pProp->data); 4086747b715Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 40905b261ecSmrg } 4104642e01fSmrg return rc; 41105b261ecSmrg} 41205b261ecSmrg 41305b261ecSmrgvoid 41405b261ecSmrgDeleteAllWindowProperties(WindowPtr pWin) 41505b261ecSmrg{ 41605b261ecSmrg PropertyPtr pProp, pNextProp; 41705b261ecSmrg 41805b261ecSmrg pProp = wUserProps (pWin); 41905b261ecSmrg while (pProp) 42005b261ecSmrg { 42105b261ecSmrg deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); 42205b261ecSmrg pNextProp = pProp->next; 4236747b715Smrg free(pProp->data); 4246747b715Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 42505b261ecSmrg pProp = pNextProp; 42605b261ecSmrg } 4279ace9065Smrg 4289ace9065Smrg if (pWin->optional) 4299ace9065Smrg pWin->optional->userProps = NULL; 43005b261ecSmrg} 43105b261ecSmrg 43205b261ecSmrgstatic int 43305b261ecSmrgNullPropertyReply( 43405b261ecSmrg ClientPtr client, 43505b261ecSmrg ATOM propertyType, 43605b261ecSmrg int format, 43705b261ecSmrg xGetPropertyReply *reply) 43805b261ecSmrg{ 43905b261ecSmrg reply->nItems = 0; 44005b261ecSmrg reply->length = 0; 44105b261ecSmrg reply->bytesAfter = 0; 44205b261ecSmrg reply->propertyType = propertyType; 44305b261ecSmrg reply->format = format; 44405b261ecSmrg WriteReplyToClient(client, sizeof(xGenericReply), reply); 4456747b715Smrg return Success; 44605b261ecSmrg} 44705b261ecSmrg 44805b261ecSmrg/***************** 44905b261ecSmrg * GetProperty 45005b261ecSmrg * If type Any is specified, returns the property from the specified 45105b261ecSmrg * window regardless of its type. If a type is specified, returns the 45205b261ecSmrg * property only if its type equals the specified type. 45305b261ecSmrg * If delete is True and a property is returned, the property is also 45405b261ecSmrg * deleted from the window and a PropertyNotify event is generated on the 45505b261ecSmrg * window. 45605b261ecSmrg *****************/ 45705b261ecSmrg 45805b261ecSmrgint 45905b261ecSmrgProcGetProperty(ClientPtr client) 46005b261ecSmrg{ 46105b261ecSmrg PropertyPtr pProp, prevProp; 4624642e01fSmrg unsigned long n, len, ind; 4634642e01fSmrg int rc; 46405b261ecSmrg WindowPtr pWin; 46505b261ecSmrg xGetPropertyReply reply; 4664642e01fSmrg Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess; 46705b261ecSmrg REQUEST(xGetPropertyReq); 46805b261ecSmrg 46905b261ecSmrg REQUEST_SIZE_MATCH(xGetPropertyReq); 4704642e01fSmrg if (stuff->delete) { 47105b261ecSmrg UpdateCurrentTime(); 4724642e01fSmrg win_mode |= DixSetPropAccess; 4734642e01fSmrg prop_mode |= DixDestroyAccess; 4744642e01fSmrg } 4754642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, win_mode); 47605b261ecSmrg if (rc != Success) 4776747b715Smrg return (rc == BadMatch) ? BadWindow : rc; 47805b261ecSmrg 47905b261ecSmrg if (!ValidAtom(stuff->property)) 48005b261ecSmrg { 48105b261ecSmrg client->errorValue = stuff->property; 4826747b715Smrg return BadAtom; 48305b261ecSmrg } 48405b261ecSmrg if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) 48505b261ecSmrg { 48605b261ecSmrg client->errorValue = stuff->delete; 4876747b715Smrg return BadValue; 48805b261ecSmrg } 48905b261ecSmrg if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) 49005b261ecSmrg { 49105b261ecSmrg client->errorValue = stuff->type; 4926747b715Smrg return BadAtom; 49305b261ecSmrg } 49405b261ecSmrg 4956747b715Smrg memset(&reply, 0, sizeof(xGetPropertyReply)); 49605b261ecSmrg reply.type = X_Reply; 49705b261ecSmrg reply.sequenceNumber = client->sequence; 49805b261ecSmrg 4994642e01fSmrg rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode); 5004642e01fSmrg if (rc == BadMatch) 5014642e01fSmrg return NullPropertyReply(client, None, 0, &reply); 5024642e01fSmrg else if (rc != Success) 5034642e01fSmrg return rc; 50405b261ecSmrg 50505b261ecSmrg /* If the request type and actual type don't match. Return the 50605b261ecSmrg property information, but not the data. */ 50705b261ecSmrg 50805b261ecSmrg if (((stuff->type != pProp->type) && 50905b261ecSmrg (stuff->type != AnyPropertyType)) 51005b261ecSmrg ) 51105b261ecSmrg { 51205b261ecSmrg reply.bytesAfter = pProp->size; 51305b261ecSmrg reply.format = pProp->format; 51405b261ecSmrg reply.length = 0; 51505b261ecSmrg reply.nItems = 0; 51605b261ecSmrg reply.propertyType = pProp->type; 51705b261ecSmrg WriteReplyToClient(client, sizeof(xGenericReply), &reply); 5186747b715Smrg return Success; 51905b261ecSmrg } 52005b261ecSmrg 52105b261ecSmrg/* 52205b261ecSmrg * Return type, format, value to client 52305b261ecSmrg */ 52405b261ecSmrg n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */ 52505b261ecSmrg ind = stuff->longOffset << 2; 52605b261ecSmrg 52705b261ecSmrg /* If longOffset is invalid such that it causes "len" to 52805b261ecSmrg be negative, it's a value error. */ 52905b261ecSmrg 53005b261ecSmrg if (n < ind) 53105b261ecSmrg { 53205b261ecSmrg client->errorValue = stuff->longOffset; 53305b261ecSmrg return BadValue; 53405b261ecSmrg } 53505b261ecSmrg 53605b261ecSmrg len = min(n - ind, 4 * stuff->longLength); 53705b261ecSmrg 53805b261ecSmrg reply.bytesAfter = n - (ind + len); 53905b261ecSmrg reply.format = pProp->format; 5406747b715Smrg reply.length = bytes_to_int32(len); 54105b261ecSmrg reply.nItems = len / (pProp->format / 8 ); 54205b261ecSmrg reply.propertyType = pProp->type; 54305b261ecSmrg 54405b261ecSmrg if (stuff->delete && (reply.bytesAfter == 0)) 54505b261ecSmrg deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); 54605b261ecSmrg 54705b261ecSmrg WriteReplyToClient(client, sizeof(xGenericReply), &reply); 54805b261ecSmrg if (len) 54905b261ecSmrg { 55005b261ecSmrg switch (reply.format) { 55105b261ecSmrg case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break; 55205b261ecSmrg case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break; 55305b261ecSmrg default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break; 55405b261ecSmrg } 55505b261ecSmrg WriteSwappedDataToClient(client, len, 55605b261ecSmrg (char *)pProp->data + ind); 55705b261ecSmrg } 55805b261ecSmrg 5594642e01fSmrg if (stuff->delete && (reply.bytesAfter == 0)) { 5604642e01fSmrg /* Delete the Property */ 5614642e01fSmrg if (pWin->optional->userProps == pProp) { 5624642e01fSmrg /* Takes care of head */ 5634642e01fSmrg if (!(pWin->optional->userProps = pProp->next)) 56405b261ecSmrg CheckWindowOptionalNeed (pWin); 5654642e01fSmrg } else { 5664642e01fSmrg /* Need to traverse to find the previous element */ 5674642e01fSmrg prevProp = pWin->optional->userProps; 5684642e01fSmrg while (prevProp->next != pProp) 5694642e01fSmrg prevProp = prevProp->next; 57005b261ecSmrg prevProp->next = pProp->next; 5714642e01fSmrg } 5724642e01fSmrg 5736747b715Smrg free(pProp->data); 5746747b715Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 57505b261ecSmrg } 5766747b715Smrg return Success; 57705b261ecSmrg} 57805b261ecSmrg 57905b261ecSmrgint 58005b261ecSmrgProcListProperties(ClientPtr client) 58105b261ecSmrg{ 58205b261ecSmrg Atom *pAtoms = NULL, *temppAtoms; 58305b261ecSmrg xListPropertiesReply xlpr; 58405b261ecSmrg int rc, numProps = 0; 58505b261ecSmrg WindowPtr pWin; 5864642e01fSmrg PropertyPtr pProp, realProp; 58705b261ecSmrg REQUEST(xResourceReq); 58805b261ecSmrg 58905b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 5904642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess); 59105b261ecSmrg if (rc != Success) 59205b261ecSmrg return rc; 59305b261ecSmrg 5944642e01fSmrg for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) 59505b261ecSmrg numProps++; 5964642e01fSmrg 5976747b715Smrg if (numProps && !(pAtoms = malloc(numProps * sizeof(Atom)))) 5984642e01fSmrg return BadAlloc; 5994642e01fSmrg 6004642e01fSmrg numProps = 0; 6014642e01fSmrg temppAtoms = pAtoms; 6024642e01fSmrg for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { 6034642e01fSmrg realProp = pProp; 6044642e01fSmrg rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess); 6054642e01fSmrg if (rc == Success && realProp == pProp) { 6064642e01fSmrg *temppAtoms++ = pProp->propertyName; 6074642e01fSmrg numProps++; 6084642e01fSmrg } 60905b261ecSmrg } 61005b261ecSmrg 61105b261ecSmrg xlpr.type = X_Reply; 61205b261ecSmrg xlpr.nProperties = numProps; 6136747b715Smrg xlpr.length = bytes_to_int32(numProps * sizeof(Atom)); 61405b261ecSmrg xlpr.sequenceNumber = client->sequence; 61505b261ecSmrg WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); 61605b261ecSmrg if (numProps) 61705b261ecSmrg { 61805b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; 61905b261ecSmrg WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); 62005b261ecSmrg } 6216747b715Smrg free(pAtoms); 6226747b715Smrg return Success; 62305b261ecSmrg} 62405b261ecSmrg 62505b261ecSmrgint 62605b261ecSmrgProcDeleteProperty(ClientPtr client) 62705b261ecSmrg{ 62805b261ecSmrg WindowPtr pWin; 62905b261ecSmrg REQUEST(xDeletePropertyReq); 63005b261ecSmrg int result; 63105b261ecSmrg 63205b261ecSmrg REQUEST_SIZE_MATCH(xDeletePropertyReq); 63305b261ecSmrg UpdateCurrentTime(); 6344642e01fSmrg result = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); 63505b261ecSmrg if (result != Success) 63605b261ecSmrg return result; 63705b261ecSmrg if (!ValidAtom(stuff->property)) 63805b261ecSmrg { 63905b261ecSmrg client->errorValue = stuff->property; 6406747b715Smrg return BadAtom; 64105b261ecSmrg } 64205b261ecSmrg 6436747b715Smrg return DeleteProperty(client, pWin, stuff->property); 64405b261ecSmrg} 645