property.c revision 706f2543
1706f2543Smrg/*********************************************************** 2706f2543Smrg 3706f2543SmrgCopyright 1987, 1998 The Open Group 4706f2543Smrg 5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its 6706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that 7706f2543Smrgthe above copyright notice appear in all copies and that both that 8706f2543Smrgcopyright notice and this permission notice appear in supporting 9706f2543Smrgdocumentation. 10706f2543Smrg 11706f2543SmrgThe above copyright notice and this permission notice shall be included in 12706f2543Smrgall copies or substantial portions of the Software. 13706f2543Smrg 14706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20706f2543Smrg 21706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be 22706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings 23706f2543Smrgin this Software without prior written authorization from The Open Group. 24706f2543Smrg 25706f2543Smrg 26706f2543SmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 27706f2543Smrg 28706f2543Smrg All Rights Reserved 29706f2543Smrg 30706f2543SmrgPermission to use, copy, modify, and distribute this software and its 31706f2543Smrgdocumentation for any purpose and without fee is hereby granted, 32706f2543Smrgprovided that the above copyright notice appear in all copies and that 33706f2543Smrgboth that copyright notice and this permission notice appear in 34706f2543Smrgsupporting documentation, and that the name of Digital not be 35706f2543Smrgused in advertising or publicity pertaining to distribution of the 36706f2543Smrgsoftware without specific, written prior permission. 37706f2543Smrg 38706f2543SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 39706f2543SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 40706f2543SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 41706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 42706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 43706f2543SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 44706f2543SmrgSOFTWARE. 45706f2543Smrg 46706f2543Smrg******************************************************************/ 47706f2543Smrg 48706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 49706f2543Smrg#include <dix-config.h> 50706f2543Smrg#endif 51706f2543Smrg 52706f2543Smrg#include <X11/X.h> 53706f2543Smrg#include <X11/Xproto.h> 54706f2543Smrg#include "windowstr.h" 55706f2543Smrg#include "propertyst.h" 56706f2543Smrg#include "dixstruct.h" 57706f2543Smrg#include "dispatch.h" 58706f2543Smrg#include "swaprep.h" 59706f2543Smrg#include "xace.h" 60706f2543Smrg 61706f2543Smrg/***************************************************************** 62706f2543Smrg * Property Stuff 63706f2543Smrg * 64706f2543Smrg * dixLookupProperty, dixChangeProperty, DeleteProperty 65706f2543Smrg * 66706f2543Smrg * Properties belong to windows. The list of properties should not be 67706f2543Smrg * traversed directly. Instead, use the three functions listed above. 68706f2543Smrg * 69706f2543Smrg *****************************************************************/ 70706f2543Smrg 71706f2543Smrg#ifdef notdef 72706f2543Smrgstatic void 73706f2543SmrgPrintPropertys(WindowPtr pWin) 74706f2543Smrg{ 75706f2543Smrg PropertyPtr pProp; 76706f2543Smrg int j; 77706f2543Smrg 78706f2543Smrg pProp = pWin->userProps; 79706f2543Smrg while (pProp) 80706f2543Smrg { 81706f2543Smrg ErrorF("[dix] %x %x\n", pProp->propertyName, pProp->type); 82706f2543Smrg ErrorF("[dix] property format: %d\n", pProp->format); 83706f2543Smrg ErrorF("[dix] property data: \n"); 84706f2543Smrg for (j=0; j<(pProp->format/8)*pProp->size; j++) 85706f2543Smrg ErrorF("[dix] %c\n", pProp->data[j]); 86706f2543Smrg pProp = pProp->next; 87706f2543Smrg } 88706f2543Smrg} 89706f2543Smrg#endif 90706f2543Smrg 91706f2543Smrgint 92706f2543SmrgdixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName, 93706f2543Smrg ClientPtr client, Mask access_mode) 94706f2543Smrg{ 95706f2543Smrg PropertyPtr pProp; 96706f2543Smrg int rc = BadMatch; 97706f2543Smrg client->errorValue = propertyName; 98706f2543Smrg 99706f2543Smrg for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) 100706f2543Smrg if (pProp->propertyName == propertyName) 101706f2543Smrg break; 102706f2543Smrg 103706f2543Smrg if (pProp) 104706f2543Smrg rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode); 105706f2543Smrg *result = pProp; 106706f2543Smrg return rc; 107706f2543Smrg} 108706f2543Smrg 109706f2543Smrgstatic void 110706f2543SmrgdeliverPropertyNotifyEvent(WindowPtr pWin, int state, Atom atom) 111706f2543Smrg{ 112706f2543Smrg xEvent event; 113706f2543Smrg 114706f2543Smrg memset(&event, 0, sizeof(xEvent)); 115706f2543Smrg event.u.u.type = PropertyNotify; 116706f2543Smrg event.u.property.window = pWin->drawable.id; 117706f2543Smrg event.u.property.state = state; 118706f2543Smrg event.u.property.atom = atom; 119706f2543Smrg event.u.property.time = currentTime.milliseconds; 120706f2543Smrg DeliverEvents(pWin, &event, 1, (WindowPtr)NULL); 121706f2543Smrg} 122706f2543Smrg 123706f2543Smrgint 124706f2543SmrgProcRotateProperties(ClientPtr client) 125706f2543Smrg{ 126706f2543Smrg int i, j, delta, rc; 127706f2543Smrg REQUEST(xRotatePropertiesReq); 128706f2543Smrg WindowPtr pWin; 129706f2543Smrg Atom * atoms; 130706f2543Smrg PropertyPtr * props; /* array of pointer */ 131706f2543Smrg PropertyPtr pProp, saved; 132706f2543Smrg 133706f2543Smrg REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2); 134706f2543Smrg UpdateCurrentTime(); 135706f2543Smrg rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); 136706f2543Smrg if (rc != Success || stuff->nAtoms <= 0) 137706f2543Smrg return rc; 138706f2543Smrg 139706f2543Smrg atoms = (Atom *) & stuff[1]; 140706f2543Smrg props = malloc(stuff->nAtoms * sizeof(PropertyPtr)); 141706f2543Smrg saved = malloc(stuff->nAtoms * sizeof(PropertyRec)); 142706f2543Smrg if (!props || !saved) { 143706f2543Smrg rc = BadAlloc; 144706f2543Smrg goto out; 145706f2543Smrg } 146706f2543Smrg 147706f2543Smrg for (i = 0; i < stuff->nAtoms; i++) 148706f2543Smrg { 149706f2543Smrg if (!ValidAtom(atoms[i])) { 150706f2543Smrg rc = BadAtom; 151706f2543Smrg client->errorValue = atoms[i]; 152706f2543Smrg goto out; 153706f2543Smrg } 154706f2543Smrg for (j = i + 1; j < stuff->nAtoms; j++) 155706f2543Smrg if (atoms[j] == atoms[i]) 156706f2543Smrg { 157706f2543Smrg rc = BadMatch; 158706f2543Smrg goto out; 159706f2543Smrg } 160706f2543Smrg 161706f2543Smrg rc = dixLookupProperty(&pProp, pWin, atoms[i], client, 162706f2543Smrg DixReadAccess|DixWriteAccess); 163706f2543Smrg if (rc != Success) 164706f2543Smrg goto out; 165706f2543Smrg 166706f2543Smrg props[i] = pProp; 167706f2543Smrg saved[i] = *pProp; 168706f2543Smrg } 169706f2543Smrg delta = stuff->nPositions; 170706f2543Smrg 171706f2543Smrg /* If the rotation is a complete 360 degrees, then moving the properties 172706f2543Smrg around and generating PropertyNotify events should be skipped. */ 173706f2543Smrg 174706f2543Smrg if (abs(delta) % stuff->nAtoms) 175706f2543Smrg { 176706f2543Smrg while (delta < 0) /* faster if abs value is small */ 177706f2543Smrg delta += stuff->nAtoms; 178706f2543Smrg for (i = 0; i < stuff->nAtoms; i++) 179706f2543Smrg { 180706f2543Smrg j = (i + delta) % stuff->nAtoms; 181706f2543Smrg deliverPropertyNotifyEvent(pWin, PropertyNewValue, atoms[i]); 182706f2543Smrg 183706f2543Smrg /* Preserve name and devPrivates */ 184706f2543Smrg props[j]->type = saved[i].type; 185706f2543Smrg props[j]->format = saved[i].format; 186706f2543Smrg props[j]->size = saved[i].size; 187706f2543Smrg props[j]->data = saved[i].data; 188706f2543Smrg } 189706f2543Smrg } 190706f2543Smrgout: 191706f2543Smrg free(saved); 192706f2543Smrg free(props); 193706f2543Smrg return rc; 194706f2543Smrg} 195706f2543Smrg 196706f2543Smrgint 197706f2543SmrgProcChangeProperty(ClientPtr client) 198706f2543Smrg{ 199706f2543Smrg WindowPtr pWin; 200706f2543Smrg char format, mode; 201706f2543Smrg unsigned long len; 202706f2543Smrg int sizeInBytes, totalSize, err; 203706f2543Smrg REQUEST(xChangePropertyReq); 204706f2543Smrg 205706f2543Smrg REQUEST_AT_LEAST_SIZE(xChangePropertyReq); 206706f2543Smrg UpdateCurrentTime(); 207706f2543Smrg format = stuff->format; 208706f2543Smrg mode = stuff->mode; 209706f2543Smrg if ((mode != PropModeReplace) && (mode != PropModeAppend) && 210706f2543Smrg (mode != PropModePrepend)) 211706f2543Smrg { 212706f2543Smrg client->errorValue = mode; 213706f2543Smrg return BadValue; 214706f2543Smrg } 215706f2543Smrg if ((format != 8) && (format != 16) && (format != 32)) 216706f2543Smrg { 217706f2543Smrg client->errorValue = format; 218706f2543Smrg return BadValue; 219706f2543Smrg } 220706f2543Smrg len = stuff->nUnits; 221706f2543Smrg if (len > bytes_to_int32(0xffffffff - sizeof(xChangePropertyReq))) 222706f2543Smrg return BadLength; 223706f2543Smrg sizeInBytes = format>>3; 224706f2543Smrg totalSize = len * sizeInBytes; 225706f2543Smrg REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize); 226706f2543Smrg 227706f2543Smrg err = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); 228706f2543Smrg if (err != Success) 229706f2543Smrg return err; 230706f2543Smrg if (!ValidAtom(stuff->property)) 231706f2543Smrg { 232706f2543Smrg client->errorValue = stuff->property; 233706f2543Smrg return BadAtom; 234706f2543Smrg } 235706f2543Smrg if (!ValidAtom(stuff->type)) 236706f2543Smrg { 237706f2543Smrg client->errorValue = stuff->type; 238706f2543Smrg return BadAtom; 239706f2543Smrg } 240706f2543Smrg 241706f2543Smrg err = dixChangeWindowProperty(client, pWin, stuff->property, stuff->type, 242706f2543Smrg (int)format, (int)mode, len, &stuff[1], 243706f2543Smrg TRUE); 244706f2543Smrg if (err != Success) 245706f2543Smrg return err; 246706f2543Smrg else 247706f2543Smrg return Success; 248706f2543Smrg} 249706f2543Smrg 250706f2543Smrgint 251706f2543SmrgdixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, 252706f2543Smrg Atom type, int format, int mode, unsigned long len, 253706f2543Smrg pointer value, Bool sendevent) 254706f2543Smrg{ 255706f2543Smrg PropertyPtr pProp; 256706f2543Smrg PropertyRec savedProp; 257706f2543Smrg int sizeInBytes, totalSize, rc; 258706f2543Smrg unsigned char *data; 259706f2543Smrg Mask access_mode; 260706f2543Smrg 261706f2543Smrg sizeInBytes = format>>3; 262706f2543Smrg totalSize = len * sizeInBytes; 263706f2543Smrg access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess; 264706f2543Smrg 265706f2543Smrg /* first see if property already exists */ 266706f2543Smrg rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode); 267706f2543Smrg 268706f2543Smrg if (rc == BadMatch) /* just add to list */ 269706f2543Smrg { 270706f2543Smrg if (!pWin->optional && !MakeWindowOptional (pWin)) 271706f2543Smrg return BadAlloc; 272706f2543Smrg pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY); 273706f2543Smrg if (!pProp) 274706f2543Smrg return BadAlloc; 275706f2543Smrg data = malloc(totalSize); 276706f2543Smrg if (!data && len) 277706f2543Smrg { 278706f2543Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 279706f2543Smrg return BadAlloc; 280706f2543Smrg } 281706f2543Smrg memcpy(data, value, totalSize); 282706f2543Smrg pProp->propertyName = property; 283706f2543Smrg pProp->type = type; 284706f2543Smrg pProp->format = format; 285706f2543Smrg pProp->data = data; 286706f2543Smrg pProp->size = len; 287706f2543Smrg rc = XaceHookPropertyAccess(pClient, pWin, &pProp, 288706f2543Smrg DixCreateAccess|DixWriteAccess); 289706f2543Smrg if (rc != Success) { 290706f2543Smrg free(data); 291706f2543Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 292706f2543Smrg pClient->errorValue = property; 293706f2543Smrg return rc; 294706f2543Smrg } 295706f2543Smrg pProp->next = pWin->optional->userProps; 296706f2543Smrg pWin->optional->userProps = pProp; 297706f2543Smrg } 298706f2543Smrg else if (rc == Success) 299706f2543Smrg { 300706f2543Smrg /* To append or prepend to a property the request format and type 301706f2543Smrg must match those of the already defined property. The 302706f2543Smrg existing format and type are irrelevant when using the mode 303706f2543Smrg "PropModeReplace" since they will be written over. */ 304706f2543Smrg 305706f2543Smrg if ((format != pProp->format) && (mode != PropModeReplace)) 306706f2543Smrg return BadMatch; 307706f2543Smrg if ((pProp->type != type) && (mode != PropModeReplace)) 308706f2543Smrg return BadMatch; 309706f2543Smrg 310706f2543Smrg /* save the old values for later */ 311706f2543Smrg savedProp = *pProp; 312706f2543Smrg 313706f2543Smrg if (mode == PropModeReplace) 314706f2543Smrg { 315706f2543Smrg data = malloc(totalSize); 316706f2543Smrg if (!data && len) 317706f2543Smrg return BadAlloc; 318706f2543Smrg memcpy(data, value, totalSize); 319706f2543Smrg pProp->data = data; 320706f2543Smrg pProp->size = len; 321706f2543Smrg pProp->type = type; 322706f2543Smrg pProp->format = format; 323706f2543Smrg } 324706f2543Smrg else if (len == 0) 325706f2543Smrg { 326706f2543Smrg /* do nothing */ 327706f2543Smrg } 328706f2543Smrg else if (mode == PropModeAppend) 329706f2543Smrg { 330706f2543Smrg data = malloc((pProp->size + len) * sizeInBytes); 331706f2543Smrg if (!data) 332706f2543Smrg return BadAlloc; 333706f2543Smrg memcpy(data, pProp->data, pProp->size * sizeInBytes); 334706f2543Smrg memcpy(data + pProp->size * sizeInBytes, value, totalSize); 335706f2543Smrg pProp->data = data; 336706f2543Smrg pProp->size += len; 337706f2543Smrg } 338706f2543Smrg else if (mode == PropModePrepend) 339706f2543Smrg { 340706f2543Smrg data = malloc(sizeInBytes * (len + pProp->size)); 341706f2543Smrg if (!data) 342706f2543Smrg return BadAlloc; 343706f2543Smrg memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes); 344706f2543Smrg memcpy(data, value, totalSize); 345706f2543Smrg pProp->data = data; 346706f2543Smrg pProp->size += len; 347706f2543Smrg } 348706f2543Smrg 349706f2543Smrg /* Allow security modules to check the new content */ 350706f2543Smrg access_mode |= DixPostAccess; 351706f2543Smrg rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode); 352706f2543Smrg if (rc == Success) 353706f2543Smrg { 354706f2543Smrg if (savedProp.data != pProp->data) 355706f2543Smrg free(savedProp.data); 356706f2543Smrg } 357706f2543Smrg else 358706f2543Smrg { 359706f2543Smrg if (savedProp.data != pProp->data) 360706f2543Smrg free(pProp->data); 361706f2543Smrg *pProp = savedProp; 362706f2543Smrg return rc; 363706f2543Smrg } 364706f2543Smrg } 365706f2543Smrg else 366706f2543Smrg return rc; 367706f2543Smrg 368706f2543Smrg if (sendevent) 369706f2543Smrg deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName); 370706f2543Smrg 371706f2543Smrg return Success; 372706f2543Smrg} 373706f2543Smrg 374706f2543Smrgint 375706f2543SmrgChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format, 376706f2543Smrg int mode, unsigned long len, pointer value, 377706f2543Smrg Bool sendevent) 378706f2543Smrg{ 379706f2543Smrg return dixChangeWindowProperty(serverClient, pWin, property, type, format, 380706f2543Smrg mode, len, value, sendevent); 381706f2543Smrg} 382706f2543Smrg 383706f2543Smrgint 384706f2543SmrgDeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName) 385706f2543Smrg{ 386706f2543Smrg PropertyPtr pProp, prevProp; 387706f2543Smrg int rc; 388706f2543Smrg 389706f2543Smrg rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess); 390706f2543Smrg if (rc == BadMatch) 391706f2543Smrg return Success; /* Succeed if property does not exist */ 392706f2543Smrg 393706f2543Smrg if (rc == Success) { 394706f2543Smrg if (pWin->optional->userProps == pProp) { 395706f2543Smrg /* Takes care of head */ 396706f2543Smrg if (!(pWin->optional->userProps = pProp->next)) 397706f2543Smrg CheckWindowOptionalNeed (pWin); 398706f2543Smrg } else { 399706f2543Smrg /* Need to traverse to find the previous element */ 400706f2543Smrg prevProp = pWin->optional->userProps; 401706f2543Smrg while (prevProp->next != pProp) 402706f2543Smrg prevProp = prevProp->next; 403706f2543Smrg prevProp->next = pProp->next; 404706f2543Smrg } 405706f2543Smrg 406706f2543Smrg deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); 407706f2543Smrg free(pProp->data); 408706f2543Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 409706f2543Smrg } 410706f2543Smrg return rc; 411706f2543Smrg} 412706f2543Smrg 413706f2543Smrgvoid 414706f2543SmrgDeleteAllWindowProperties(WindowPtr pWin) 415706f2543Smrg{ 416706f2543Smrg PropertyPtr pProp, pNextProp; 417706f2543Smrg 418706f2543Smrg pProp = wUserProps (pWin); 419706f2543Smrg while (pProp) 420706f2543Smrg { 421706f2543Smrg deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); 422706f2543Smrg pNextProp = pProp->next; 423706f2543Smrg free(pProp->data); 424706f2543Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 425706f2543Smrg pProp = pNextProp; 426706f2543Smrg } 427706f2543Smrg 428706f2543Smrg if (pWin->optional) 429706f2543Smrg pWin->optional->userProps = NULL; 430706f2543Smrg} 431706f2543Smrg 432706f2543Smrgstatic int 433706f2543SmrgNullPropertyReply( 434706f2543Smrg ClientPtr client, 435706f2543Smrg ATOM propertyType, 436706f2543Smrg int format, 437706f2543Smrg xGetPropertyReply *reply) 438706f2543Smrg{ 439706f2543Smrg reply->nItems = 0; 440706f2543Smrg reply->length = 0; 441706f2543Smrg reply->bytesAfter = 0; 442706f2543Smrg reply->propertyType = propertyType; 443706f2543Smrg reply->format = format; 444706f2543Smrg WriteReplyToClient(client, sizeof(xGenericReply), reply); 445706f2543Smrg return Success; 446706f2543Smrg} 447706f2543Smrg 448706f2543Smrg/***************** 449706f2543Smrg * GetProperty 450706f2543Smrg * If type Any is specified, returns the property from the specified 451706f2543Smrg * window regardless of its type. If a type is specified, returns the 452706f2543Smrg * property only if its type equals the specified type. 453706f2543Smrg * If delete is True and a property is returned, the property is also 454706f2543Smrg * deleted from the window and a PropertyNotify event is generated on the 455706f2543Smrg * window. 456706f2543Smrg *****************/ 457706f2543Smrg 458706f2543Smrgint 459706f2543SmrgProcGetProperty(ClientPtr client) 460706f2543Smrg{ 461706f2543Smrg PropertyPtr pProp, prevProp; 462706f2543Smrg unsigned long n, len, ind; 463706f2543Smrg int rc; 464706f2543Smrg WindowPtr pWin; 465706f2543Smrg xGetPropertyReply reply; 466706f2543Smrg Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess; 467706f2543Smrg REQUEST(xGetPropertyReq); 468706f2543Smrg 469706f2543Smrg REQUEST_SIZE_MATCH(xGetPropertyReq); 470706f2543Smrg if (stuff->delete) { 471706f2543Smrg UpdateCurrentTime(); 472706f2543Smrg win_mode |= DixSetPropAccess; 473706f2543Smrg prop_mode |= DixDestroyAccess; 474706f2543Smrg } 475706f2543Smrg rc = dixLookupWindow(&pWin, stuff->window, client, win_mode); 476706f2543Smrg if (rc != Success) 477706f2543Smrg return (rc == BadMatch) ? BadWindow : rc; 478706f2543Smrg 479706f2543Smrg if (!ValidAtom(stuff->property)) 480706f2543Smrg { 481706f2543Smrg client->errorValue = stuff->property; 482706f2543Smrg return BadAtom; 483706f2543Smrg } 484706f2543Smrg if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) 485706f2543Smrg { 486706f2543Smrg client->errorValue = stuff->delete; 487706f2543Smrg return BadValue; 488706f2543Smrg } 489706f2543Smrg if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) 490706f2543Smrg { 491706f2543Smrg client->errorValue = stuff->type; 492706f2543Smrg return BadAtom; 493706f2543Smrg } 494706f2543Smrg 495706f2543Smrg memset(&reply, 0, sizeof(xGetPropertyReply)); 496706f2543Smrg reply.type = X_Reply; 497706f2543Smrg reply.sequenceNumber = client->sequence; 498706f2543Smrg 499706f2543Smrg rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode); 500706f2543Smrg if (rc == BadMatch) 501706f2543Smrg return NullPropertyReply(client, None, 0, &reply); 502706f2543Smrg else if (rc != Success) 503706f2543Smrg return rc; 504706f2543Smrg 505706f2543Smrg /* If the request type and actual type don't match. Return the 506706f2543Smrg property information, but not the data. */ 507706f2543Smrg 508706f2543Smrg if (((stuff->type != pProp->type) && 509706f2543Smrg (stuff->type != AnyPropertyType)) 510706f2543Smrg ) 511706f2543Smrg { 512706f2543Smrg reply.bytesAfter = pProp->size; 513706f2543Smrg reply.format = pProp->format; 514706f2543Smrg reply.length = 0; 515706f2543Smrg reply.nItems = 0; 516706f2543Smrg reply.propertyType = pProp->type; 517706f2543Smrg WriteReplyToClient(client, sizeof(xGenericReply), &reply); 518706f2543Smrg return Success; 519706f2543Smrg } 520706f2543Smrg 521706f2543Smrg/* 522706f2543Smrg * Return type, format, value to client 523706f2543Smrg */ 524706f2543Smrg n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */ 525706f2543Smrg ind = stuff->longOffset << 2; 526706f2543Smrg 527706f2543Smrg /* If longOffset is invalid such that it causes "len" to 528706f2543Smrg be negative, it's a value error. */ 529706f2543Smrg 530706f2543Smrg if (n < ind) 531706f2543Smrg { 532706f2543Smrg client->errorValue = stuff->longOffset; 533706f2543Smrg return BadValue; 534706f2543Smrg } 535706f2543Smrg 536706f2543Smrg len = min(n - ind, 4 * stuff->longLength); 537706f2543Smrg 538706f2543Smrg reply.bytesAfter = n - (ind + len); 539706f2543Smrg reply.format = pProp->format; 540706f2543Smrg reply.length = bytes_to_int32(len); 541706f2543Smrg reply.nItems = len / (pProp->format / 8 ); 542706f2543Smrg reply.propertyType = pProp->type; 543706f2543Smrg 544706f2543Smrg if (stuff->delete && (reply.bytesAfter == 0)) 545706f2543Smrg deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); 546706f2543Smrg 547706f2543Smrg WriteReplyToClient(client, sizeof(xGenericReply), &reply); 548706f2543Smrg if (len) 549706f2543Smrg { 550706f2543Smrg switch (reply.format) { 551706f2543Smrg case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break; 552706f2543Smrg case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break; 553706f2543Smrg default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break; 554706f2543Smrg } 555706f2543Smrg WriteSwappedDataToClient(client, len, 556706f2543Smrg (char *)pProp->data + ind); 557706f2543Smrg } 558706f2543Smrg 559706f2543Smrg if (stuff->delete && (reply.bytesAfter == 0)) { 560706f2543Smrg /* Delete the Property */ 561706f2543Smrg if (pWin->optional->userProps == pProp) { 562706f2543Smrg /* Takes care of head */ 563706f2543Smrg if (!(pWin->optional->userProps = pProp->next)) 564706f2543Smrg CheckWindowOptionalNeed (pWin); 565706f2543Smrg } else { 566706f2543Smrg /* Need to traverse to find the previous element */ 567706f2543Smrg prevProp = pWin->optional->userProps; 568706f2543Smrg while (prevProp->next != pProp) 569706f2543Smrg prevProp = prevProp->next; 570706f2543Smrg prevProp->next = pProp->next; 571706f2543Smrg } 572706f2543Smrg 573706f2543Smrg free(pProp->data); 574706f2543Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 575706f2543Smrg } 576706f2543Smrg return Success; 577706f2543Smrg} 578706f2543Smrg 579706f2543Smrgint 580706f2543SmrgProcListProperties(ClientPtr client) 581706f2543Smrg{ 582706f2543Smrg Atom *pAtoms = NULL, *temppAtoms; 583706f2543Smrg xListPropertiesReply xlpr; 584706f2543Smrg int rc, numProps = 0; 585706f2543Smrg WindowPtr pWin; 586706f2543Smrg PropertyPtr pProp, realProp; 587706f2543Smrg REQUEST(xResourceReq); 588706f2543Smrg 589706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 590706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess); 591706f2543Smrg if (rc != Success) 592706f2543Smrg return rc; 593706f2543Smrg 594706f2543Smrg for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) 595706f2543Smrg numProps++; 596706f2543Smrg 597706f2543Smrg if (numProps && !(pAtoms = malloc(numProps * sizeof(Atom)))) 598706f2543Smrg return BadAlloc; 599706f2543Smrg 600706f2543Smrg numProps = 0; 601706f2543Smrg temppAtoms = pAtoms; 602706f2543Smrg for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { 603706f2543Smrg realProp = pProp; 604706f2543Smrg rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess); 605706f2543Smrg if (rc == Success && realProp == pProp) { 606706f2543Smrg *temppAtoms++ = pProp->propertyName; 607706f2543Smrg numProps++; 608706f2543Smrg } 609706f2543Smrg } 610706f2543Smrg 611706f2543Smrg xlpr.type = X_Reply; 612706f2543Smrg xlpr.nProperties = numProps; 613706f2543Smrg xlpr.length = bytes_to_int32(numProps * sizeof(Atom)); 614706f2543Smrg xlpr.sequenceNumber = client->sequence; 615706f2543Smrg WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); 616706f2543Smrg if (numProps) 617706f2543Smrg { 618706f2543Smrg client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; 619706f2543Smrg WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); 620706f2543Smrg } 621706f2543Smrg free(pAtoms); 622706f2543Smrg return Success; 623706f2543Smrg} 624706f2543Smrg 625706f2543Smrgint 626706f2543SmrgProcDeleteProperty(ClientPtr client) 627706f2543Smrg{ 628706f2543Smrg WindowPtr pWin; 629706f2543Smrg REQUEST(xDeletePropertyReq); 630706f2543Smrg int result; 631706f2543Smrg 632706f2543Smrg REQUEST_SIZE_MATCH(xDeletePropertyReq); 633706f2543Smrg UpdateCurrentTime(); 634706f2543Smrg result = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); 635706f2543Smrg if (result != Success) 636706f2543Smrg return result; 637706f2543Smrg if (!ValidAtom(stuff->property)) 638706f2543Smrg { 639706f2543Smrg client->errorValue = stuff->property; 640706f2543Smrg return BadAtom; 641706f2543Smrg } 642706f2543Smrg 643706f2543Smrg return DeleteProperty(client, pWin, stuff->property); 644706f2543Smrg} 645