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; 202c8c3bf63Smrg int sizeInBytes, err; 203c8c3bf63Smrg uint64_t totalSize; 204706f2543Smrg REQUEST(xChangePropertyReq); 205706f2543Smrg 206706f2543Smrg REQUEST_AT_LEAST_SIZE(xChangePropertyReq); 207706f2543Smrg UpdateCurrentTime(); 208706f2543Smrg format = stuff->format; 209706f2543Smrg mode = stuff->mode; 210706f2543Smrg if ((mode != PropModeReplace) && (mode != PropModeAppend) && 211706f2543Smrg (mode != PropModePrepend)) 212706f2543Smrg { 213706f2543Smrg client->errorValue = mode; 214706f2543Smrg return BadValue; 215706f2543Smrg } 216706f2543Smrg if ((format != 8) && (format != 16) && (format != 32)) 217706f2543Smrg { 218706f2543Smrg client->errorValue = format; 219706f2543Smrg return BadValue; 220706f2543Smrg } 221706f2543Smrg len = stuff->nUnits; 222706f2543Smrg if (len > bytes_to_int32(0xffffffff - sizeof(xChangePropertyReq))) 223706f2543Smrg return BadLength; 224706f2543Smrg sizeInBytes = format>>3; 225706f2543Smrg totalSize = len * sizeInBytes; 226706f2543Smrg REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize); 227706f2543Smrg 228706f2543Smrg err = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); 229706f2543Smrg if (err != Success) 230706f2543Smrg return err; 231706f2543Smrg if (!ValidAtom(stuff->property)) 232706f2543Smrg { 233706f2543Smrg client->errorValue = stuff->property; 234706f2543Smrg return BadAtom; 235706f2543Smrg } 236706f2543Smrg if (!ValidAtom(stuff->type)) 237706f2543Smrg { 238706f2543Smrg client->errorValue = stuff->type; 239706f2543Smrg return BadAtom; 240706f2543Smrg } 241706f2543Smrg 242706f2543Smrg err = dixChangeWindowProperty(client, pWin, stuff->property, stuff->type, 243706f2543Smrg (int)format, (int)mode, len, &stuff[1], 244706f2543Smrg TRUE); 245706f2543Smrg if (err != Success) 246706f2543Smrg return err; 247706f2543Smrg else 248706f2543Smrg return Success; 249706f2543Smrg} 250706f2543Smrg 251706f2543Smrgint 252706f2543SmrgdixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, 253706f2543Smrg Atom type, int format, int mode, unsigned long len, 254706f2543Smrg pointer value, Bool sendevent) 255706f2543Smrg{ 256706f2543Smrg PropertyPtr pProp; 257706f2543Smrg PropertyRec savedProp; 258706f2543Smrg int sizeInBytes, totalSize, rc; 259706f2543Smrg unsigned char *data; 260706f2543Smrg Mask access_mode; 261706f2543Smrg 262706f2543Smrg sizeInBytes = format>>3; 263706f2543Smrg totalSize = len * sizeInBytes; 264706f2543Smrg access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess; 265706f2543Smrg 266706f2543Smrg /* first see if property already exists */ 267706f2543Smrg rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode); 268706f2543Smrg 269706f2543Smrg if (rc == BadMatch) /* just add to list */ 270706f2543Smrg { 271706f2543Smrg if (!pWin->optional && !MakeWindowOptional (pWin)) 272706f2543Smrg return BadAlloc; 273706f2543Smrg pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY); 274706f2543Smrg if (!pProp) 275706f2543Smrg return BadAlloc; 276706f2543Smrg data = malloc(totalSize); 277706f2543Smrg if (!data && len) 278706f2543Smrg { 279706f2543Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 280706f2543Smrg return BadAlloc; 281706f2543Smrg } 282706f2543Smrg memcpy(data, value, totalSize); 283706f2543Smrg pProp->propertyName = property; 284706f2543Smrg pProp->type = type; 285706f2543Smrg pProp->format = format; 286706f2543Smrg pProp->data = data; 287706f2543Smrg pProp->size = len; 288706f2543Smrg rc = XaceHookPropertyAccess(pClient, pWin, &pProp, 289706f2543Smrg DixCreateAccess|DixWriteAccess); 290706f2543Smrg if (rc != Success) { 291706f2543Smrg free(data); 292706f2543Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 293706f2543Smrg pClient->errorValue = property; 294706f2543Smrg return rc; 295706f2543Smrg } 296706f2543Smrg pProp->next = pWin->optional->userProps; 297706f2543Smrg pWin->optional->userProps = pProp; 298706f2543Smrg } 299706f2543Smrg else if (rc == Success) 300706f2543Smrg { 301706f2543Smrg /* To append or prepend to a property the request format and type 302706f2543Smrg must match those of the already defined property. The 303706f2543Smrg existing format and type are irrelevant when using the mode 304706f2543Smrg "PropModeReplace" since they will be written over. */ 305706f2543Smrg 306706f2543Smrg if ((format != pProp->format) && (mode != PropModeReplace)) 307706f2543Smrg return BadMatch; 308706f2543Smrg if ((pProp->type != type) && (mode != PropModeReplace)) 309706f2543Smrg return BadMatch; 310706f2543Smrg 311706f2543Smrg /* save the old values for later */ 312706f2543Smrg savedProp = *pProp; 313706f2543Smrg 314706f2543Smrg if (mode == PropModeReplace) 315706f2543Smrg { 316706f2543Smrg data = malloc(totalSize); 317706f2543Smrg if (!data && len) 318706f2543Smrg return BadAlloc; 319706f2543Smrg memcpy(data, value, totalSize); 320706f2543Smrg pProp->data = data; 321706f2543Smrg pProp->size = len; 322706f2543Smrg pProp->type = type; 323706f2543Smrg pProp->format = format; 324706f2543Smrg } 325706f2543Smrg else if (len == 0) 326706f2543Smrg { 327706f2543Smrg /* do nothing */ 328706f2543Smrg } 329706f2543Smrg else if (mode == PropModeAppend) 330706f2543Smrg { 331706f2543Smrg data = malloc((pProp->size + len) * sizeInBytes); 332706f2543Smrg if (!data) 333706f2543Smrg return BadAlloc; 334706f2543Smrg memcpy(data, pProp->data, pProp->size * sizeInBytes); 335706f2543Smrg memcpy(data + pProp->size * sizeInBytes, value, totalSize); 336706f2543Smrg pProp->data = data; 337706f2543Smrg pProp->size += len; 338706f2543Smrg } 339706f2543Smrg else if (mode == PropModePrepend) 340706f2543Smrg { 341706f2543Smrg data = malloc(sizeInBytes * (len + pProp->size)); 342706f2543Smrg if (!data) 343706f2543Smrg return BadAlloc; 344706f2543Smrg memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes); 345706f2543Smrg memcpy(data, value, totalSize); 346706f2543Smrg pProp->data = data; 347706f2543Smrg pProp->size += len; 348706f2543Smrg } 349706f2543Smrg 350706f2543Smrg /* Allow security modules to check the new content */ 351706f2543Smrg access_mode |= DixPostAccess; 352706f2543Smrg rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode); 353706f2543Smrg if (rc == Success) 354706f2543Smrg { 355706f2543Smrg if (savedProp.data != pProp->data) 356706f2543Smrg free(savedProp.data); 357706f2543Smrg } 358706f2543Smrg else 359706f2543Smrg { 360706f2543Smrg if (savedProp.data != pProp->data) 361706f2543Smrg free(pProp->data); 362706f2543Smrg *pProp = savedProp; 363706f2543Smrg return rc; 364706f2543Smrg } 365706f2543Smrg } 366706f2543Smrg else 367706f2543Smrg return rc; 368706f2543Smrg 369706f2543Smrg if (sendevent) 370706f2543Smrg deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName); 371706f2543Smrg 372706f2543Smrg return Success; 373706f2543Smrg} 374706f2543Smrg 375706f2543Smrgint 376706f2543SmrgChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format, 377706f2543Smrg int mode, unsigned long len, pointer value, 378706f2543Smrg Bool sendevent) 379706f2543Smrg{ 380706f2543Smrg return dixChangeWindowProperty(serverClient, pWin, property, type, format, 381706f2543Smrg mode, len, value, sendevent); 382706f2543Smrg} 383706f2543Smrg 384706f2543Smrgint 385706f2543SmrgDeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName) 386706f2543Smrg{ 387706f2543Smrg PropertyPtr pProp, prevProp; 388706f2543Smrg int rc; 389706f2543Smrg 390706f2543Smrg rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess); 391706f2543Smrg if (rc == BadMatch) 392706f2543Smrg return Success; /* Succeed if property does not exist */ 393706f2543Smrg 394706f2543Smrg if (rc == Success) { 395706f2543Smrg if (pWin->optional->userProps == pProp) { 396706f2543Smrg /* Takes care of head */ 397706f2543Smrg if (!(pWin->optional->userProps = pProp->next)) 398706f2543Smrg CheckWindowOptionalNeed (pWin); 399706f2543Smrg } else { 400706f2543Smrg /* Need to traverse to find the previous element */ 401706f2543Smrg prevProp = pWin->optional->userProps; 402706f2543Smrg while (prevProp->next != pProp) 403706f2543Smrg prevProp = prevProp->next; 404706f2543Smrg prevProp->next = pProp->next; 405706f2543Smrg } 406706f2543Smrg 407706f2543Smrg deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); 408706f2543Smrg free(pProp->data); 409706f2543Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 410706f2543Smrg } 411706f2543Smrg return rc; 412706f2543Smrg} 413706f2543Smrg 414706f2543Smrgvoid 415706f2543SmrgDeleteAllWindowProperties(WindowPtr pWin) 416706f2543Smrg{ 417706f2543Smrg PropertyPtr pProp, pNextProp; 418706f2543Smrg 419706f2543Smrg pProp = wUserProps (pWin); 420706f2543Smrg while (pProp) 421706f2543Smrg { 422706f2543Smrg deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); 423706f2543Smrg pNextProp = pProp->next; 424706f2543Smrg free(pProp->data); 425706f2543Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 426706f2543Smrg pProp = pNextProp; 427706f2543Smrg } 428706f2543Smrg 429706f2543Smrg if (pWin->optional) 430706f2543Smrg pWin->optional->userProps = NULL; 431706f2543Smrg} 432706f2543Smrg 433706f2543Smrgstatic int 434706f2543SmrgNullPropertyReply( 435706f2543Smrg ClientPtr client, 436706f2543Smrg ATOM propertyType, 437706f2543Smrg int format, 438706f2543Smrg xGetPropertyReply *reply) 439706f2543Smrg{ 440706f2543Smrg reply->nItems = 0; 441706f2543Smrg reply->length = 0; 442706f2543Smrg reply->bytesAfter = 0; 443706f2543Smrg reply->propertyType = propertyType; 444706f2543Smrg reply->format = format; 445706f2543Smrg WriteReplyToClient(client, sizeof(xGenericReply), reply); 446706f2543Smrg return Success; 447706f2543Smrg} 448706f2543Smrg 449706f2543Smrg/***************** 450706f2543Smrg * GetProperty 451706f2543Smrg * If type Any is specified, returns the property from the specified 452706f2543Smrg * window regardless of its type. If a type is specified, returns the 453706f2543Smrg * property only if its type equals the specified type. 454706f2543Smrg * If delete is True and a property is returned, the property is also 455706f2543Smrg * deleted from the window and a PropertyNotify event is generated on the 456706f2543Smrg * window. 457706f2543Smrg *****************/ 458706f2543Smrg 459706f2543Smrgint 460706f2543SmrgProcGetProperty(ClientPtr client) 461706f2543Smrg{ 462706f2543Smrg PropertyPtr pProp, prevProp; 463706f2543Smrg unsigned long n, len, ind; 464706f2543Smrg int rc; 465706f2543Smrg WindowPtr pWin; 466706f2543Smrg xGetPropertyReply reply; 467706f2543Smrg Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess; 468706f2543Smrg REQUEST(xGetPropertyReq); 469706f2543Smrg 470706f2543Smrg REQUEST_SIZE_MATCH(xGetPropertyReq); 471706f2543Smrg if (stuff->delete) { 472706f2543Smrg UpdateCurrentTime(); 473706f2543Smrg win_mode |= DixSetPropAccess; 474706f2543Smrg prop_mode |= DixDestroyAccess; 475706f2543Smrg } 476706f2543Smrg rc = dixLookupWindow(&pWin, stuff->window, client, win_mode); 477706f2543Smrg if (rc != Success) 478706f2543Smrg return (rc == BadMatch) ? BadWindow : rc; 479706f2543Smrg 480706f2543Smrg if (!ValidAtom(stuff->property)) 481706f2543Smrg { 482706f2543Smrg client->errorValue = stuff->property; 483706f2543Smrg return BadAtom; 484706f2543Smrg } 485706f2543Smrg if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) 486706f2543Smrg { 487706f2543Smrg client->errorValue = stuff->delete; 488706f2543Smrg return BadValue; 489706f2543Smrg } 490706f2543Smrg if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) 491706f2543Smrg { 492706f2543Smrg client->errorValue = stuff->type; 493706f2543Smrg return BadAtom; 494706f2543Smrg } 495706f2543Smrg 496706f2543Smrg memset(&reply, 0, sizeof(xGetPropertyReply)); 497706f2543Smrg reply.type = X_Reply; 498706f2543Smrg reply.sequenceNumber = client->sequence; 499706f2543Smrg 500706f2543Smrg rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode); 501706f2543Smrg if (rc == BadMatch) 502706f2543Smrg return NullPropertyReply(client, None, 0, &reply); 503706f2543Smrg else if (rc != Success) 504706f2543Smrg return rc; 505706f2543Smrg 506706f2543Smrg /* If the request type and actual type don't match. Return the 507706f2543Smrg property information, but not the data. */ 508706f2543Smrg 509706f2543Smrg if (((stuff->type != pProp->type) && 510706f2543Smrg (stuff->type != AnyPropertyType)) 511706f2543Smrg ) 512706f2543Smrg { 513706f2543Smrg reply.bytesAfter = pProp->size; 514706f2543Smrg reply.format = pProp->format; 515706f2543Smrg reply.length = 0; 516706f2543Smrg reply.nItems = 0; 517706f2543Smrg reply.propertyType = pProp->type; 518706f2543Smrg WriteReplyToClient(client, sizeof(xGenericReply), &reply); 519706f2543Smrg return Success; 520706f2543Smrg } 521706f2543Smrg 522706f2543Smrg/* 523706f2543Smrg * Return type, format, value to client 524706f2543Smrg */ 525706f2543Smrg n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */ 526706f2543Smrg ind = stuff->longOffset << 2; 527706f2543Smrg 528706f2543Smrg /* If longOffset is invalid such that it causes "len" to 529706f2543Smrg be negative, it's a value error. */ 530706f2543Smrg 531706f2543Smrg if (n < ind) 532706f2543Smrg { 533706f2543Smrg client->errorValue = stuff->longOffset; 534706f2543Smrg return BadValue; 535706f2543Smrg } 536706f2543Smrg 537706f2543Smrg len = min(n - ind, 4 * stuff->longLength); 538706f2543Smrg 539706f2543Smrg reply.bytesAfter = n - (ind + len); 540706f2543Smrg reply.format = pProp->format; 541706f2543Smrg reply.length = bytes_to_int32(len); 542706f2543Smrg reply.nItems = len / (pProp->format / 8 ); 543706f2543Smrg reply.propertyType = pProp->type; 544706f2543Smrg 545706f2543Smrg if (stuff->delete && (reply.bytesAfter == 0)) 546706f2543Smrg deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); 547706f2543Smrg 548706f2543Smrg WriteReplyToClient(client, sizeof(xGenericReply), &reply); 549706f2543Smrg if (len) 550706f2543Smrg { 551706f2543Smrg switch (reply.format) { 552706f2543Smrg case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break; 553706f2543Smrg case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break; 554706f2543Smrg default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break; 555706f2543Smrg } 556706f2543Smrg WriteSwappedDataToClient(client, len, 557706f2543Smrg (char *)pProp->data + ind); 558706f2543Smrg } 559706f2543Smrg 560706f2543Smrg if (stuff->delete && (reply.bytesAfter == 0)) { 561706f2543Smrg /* Delete the Property */ 562706f2543Smrg if (pWin->optional->userProps == pProp) { 563706f2543Smrg /* Takes care of head */ 564706f2543Smrg if (!(pWin->optional->userProps = pProp->next)) 565706f2543Smrg CheckWindowOptionalNeed (pWin); 566706f2543Smrg } else { 567706f2543Smrg /* Need to traverse to find the previous element */ 568706f2543Smrg prevProp = pWin->optional->userProps; 569706f2543Smrg while (prevProp->next != pProp) 570706f2543Smrg prevProp = prevProp->next; 571706f2543Smrg prevProp->next = pProp->next; 572706f2543Smrg } 573706f2543Smrg 574706f2543Smrg free(pProp->data); 575706f2543Smrg dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); 576706f2543Smrg } 577706f2543Smrg return Success; 578706f2543Smrg} 579706f2543Smrg 580706f2543Smrgint 581706f2543SmrgProcListProperties(ClientPtr client) 582706f2543Smrg{ 583706f2543Smrg Atom *pAtoms = NULL, *temppAtoms; 584706f2543Smrg xListPropertiesReply xlpr; 585706f2543Smrg int rc, numProps = 0; 586706f2543Smrg WindowPtr pWin; 587706f2543Smrg PropertyPtr pProp, realProp; 588706f2543Smrg REQUEST(xResourceReq); 589706f2543Smrg 590706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 591706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess); 592706f2543Smrg if (rc != Success) 593706f2543Smrg return rc; 594706f2543Smrg 595706f2543Smrg for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) 596706f2543Smrg numProps++; 597706f2543Smrg 598706f2543Smrg if (numProps && !(pAtoms = malloc(numProps * sizeof(Atom)))) 599706f2543Smrg return BadAlloc; 600706f2543Smrg 601706f2543Smrg numProps = 0; 602706f2543Smrg temppAtoms = pAtoms; 603706f2543Smrg for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { 604706f2543Smrg realProp = pProp; 605706f2543Smrg rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess); 606706f2543Smrg if (rc == Success && realProp == pProp) { 607706f2543Smrg *temppAtoms++ = pProp->propertyName; 608706f2543Smrg numProps++; 609706f2543Smrg } 610706f2543Smrg } 611706f2543Smrg 612706f2543Smrg xlpr.type = X_Reply; 613706f2543Smrg xlpr.nProperties = numProps; 614706f2543Smrg xlpr.length = bytes_to_int32(numProps * sizeof(Atom)); 615706f2543Smrg xlpr.sequenceNumber = client->sequence; 616706f2543Smrg WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); 617706f2543Smrg if (numProps) 618706f2543Smrg { 619706f2543Smrg client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; 620706f2543Smrg WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); 621706f2543Smrg } 622706f2543Smrg free(pAtoms); 623706f2543Smrg return Success; 624706f2543Smrg} 625706f2543Smrg 626706f2543Smrgint 627706f2543SmrgProcDeleteProperty(ClientPtr client) 628706f2543Smrg{ 629706f2543Smrg WindowPtr pWin; 630706f2543Smrg REQUEST(xDeletePropertyReq); 631706f2543Smrg int result; 632706f2543Smrg 633706f2543Smrg REQUEST_SIZE_MATCH(xDeletePropertyReq); 634706f2543Smrg UpdateCurrentTime(); 635706f2543Smrg result = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); 636706f2543Smrg if (result != Success) 637706f2543Smrg return result; 638706f2543Smrg if (!ValidAtom(stuff->property)) 639706f2543Smrg { 640706f2543Smrg client->errorValue = stuff->property; 641706f2543Smrg return BadAtom; 642706f2543Smrg } 643706f2543Smrg 644706f2543Smrg return DeleteProperty(client, pWin, stuff->property); 645706f2543Smrg} 646