|
|
1.1 ! root 1: /*********************************************************** ! 2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 4: ! 5: All Rights Reserved ! 6: ! 7: Permission to use, copy, modify, and distribute this software and its ! 8: documentation for any purpose and without fee is hereby granted, ! 9: provided that the above copyright notice appear in all copies and that ! 10: both that copyright notice and this permission notice appear in ! 11: supporting documentation, and that the names of Digital or MIT not be ! 12: used in advertising or publicity pertaining to distribution of the ! 13: software without specific, written prior permission. ! 14: ! 15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 21: SOFTWARE. ! 22: ! 23: ******************************************************************/ ! 24: /* $Header: property.c,v 1.55 87/09/03 03:04:04 newman Exp $ */ ! 25: ! 26: #include "X.h" ! 27: #define NEED_REPLIES ! 28: #define NEED_EVENTS ! 29: #include "Xproto.h" ! 30: #include "windowstr.h" ! 31: #include "propertyst.h" ! 32: #include "dixstruct.h" ! 33: ! 34: extern void (*ReplySwapVector[]) (); ! 35: extern void CopySwap16Write(), CopySwap32Write(), Swap32Write(), WriteToClient(); ! 36: ! 37: /***************************************************************** ! 38: * Property Stuff ! 39: * ! 40: * ChangeProperty, DeleteProperty, GetProperties, ! 41: * ListProperties ! 42: * ! 43: * Properties below to windows. A allocate slots each time ! 44: * a property is added. No fancy searching done. ! 45: * ! 46: *****************************************************************/ ! 47: ! 48: static void ! 49: PrintPropertys(pWin) ! 50: WindowPtr pWin; ! 51: { ! 52: PropertyPtr pProp; ! 53: register int j; ! 54: ! 55: pProp = pWin->userProps; ! 56: while (pProp) ! 57: { ! 58: ErrorF( "%x %x\n", pProp->propertyName, pProp->type); ! 59: ErrorF("property format: %d\n", pProp->format); ! 60: ErrorF("property data: \n"); ! 61: for (j=0; j<(pProp->format/8)*pProp->size; j++) ! 62: ErrorF("%c\n", pProp->data[j]); ! 63: pProp = pProp->next; ! 64: } ! 65: } ! 66: ! 67: ! 68: int ! 69: ProcRotateProperties(client) ! 70: ClientPtr client; ! 71: { ! 72: int i, j, delta; ! 73: REQUEST(xRotatePropertiesReq); ! 74: WindowPtr pWin; ! 75: register Atom * atoms; ! 76: PropertyPtr * props; /* array of pointer */ ! 77: PropertyPtr pProp; ! 78: xEvent event; ! 79: ! 80: REQUEST_AT_LEAST_SIZE(xRotatePropertiesReq); ! 81: if (stuff->length != ((sizeof(xRotatePropertiesReq) >> 2) + stuff->nAtoms)) ! 82: return BadLength; ! 83: pWin = (WindowPtr) LookupWindow(stuff->window, client); ! 84: if (!pWin) ! 85: return(BadWindow); ! 86: atoms = (Atom *) & stuff[1]; ! 87: props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr)); ! 88: for (i = 0; i < stuff->nAtoms; i++) ! 89: { ! 90: if (!ValidAtom(atoms[i])) ! 91: { ! 92: DEALLOCATE_LOCAL(props); ! 93: return BadAtom; ! 94: } ! 95: for (j = i + 1; j < stuff->nAtoms; j++) ! 96: if (atoms[j] == atoms[i]) ! 97: { ! 98: DEALLOCATE_LOCAL(props); ! 99: return BadMatch; ! 100: } ! 101: pProp = pWin->userProps; ! 102: while (pProp) ! 103: { ! 104: if (pProp->propertyName == atoms[i]) ! 105: goto found; ! 106: pProp = pProp->next; ! 107: } ! 108: DEALLOCATE_LOCAL(props); ! 109: return BadMatch; ! 110: found: ! 111: props[i] = pProp; ! 112: } ! 113: delta = stuff->nPositions; ! 114: ! 115: /* If the rotation is a complete 360 degrees, then moving the properties ! 116: around and generating PropertyNotify events should be skipped. */ ! 117: ! 118: if ( (stuff->nAtoms > 0) && (abs(delta) % stuff->nAtoms) != 0 ) ! 119: { ! 120: while (delta < 0) /* faster if abs value is small */ ! 121: delta += stuff->nAtoms; ! 122: for (i = 0; i < stuff->nAtoms; i++) ! 123: { ! 124: /* Generate a PropertyNotify event for each property whose value ! 125: is changed in the order in which they appear in the request. */ ! 126: ! 127: event.u.u.type = PropertyNotify; ! 128: event.u.property.window = pWin->wid; ! 129: event.u.property.state = PropertyNewValue; ! 130: event.u.property.atom = props[i]->propertyName; ! 131: event.u.property.time = currentTime.milliseconds; ! 132: DeliverEvents(pWin, &event, 1); ! 133: ! 134: props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms]; ! 135: } ! 136: } ! 137: DEALLOCATE_LOCAL(props); ! 138: return Success; ! 139: } ! 140: ! 141: int ! 142: ProcChangeProperty(client) ! 143: ClientPtr client; ! 144: { ! 145: WindowPtr pWin; ! 146: char format, mode; ! 147: int len; ! 148: PropertyPtr pProp; ! 149: xEvent event; ! 150: int sizeInBytes; ! 151: REQUEST(xChangePropertyReq); ! 152: ! 153: REQUEST_AT_LEAST_SIZE(xChangePropertyReq); ! 154: format = stuff->format; ! 155: mode = stuff->mode; ! 156: if (((mode != PropModeReplace) && (mode != PropModeAppend) && ! 157: (mode != PropModePrepend)) ! 158: || ((format != 8) && (format != 16) && (format != 32))) ! 159: return BadValue; ! 160: ! 161: pWin = (WindowPtr)LookupWindow(stuff->window, client); ! 162: if (!pWin) ! 163: return(BadWindow); ! 164: if (!(ValidAtom(stuff->property) && ValidAtom(stuff->type))) ! 165: return(BadAtom); ! 166: ! 167: /* first see if property already exists */ ! 168: ! 169: len = stuff->nUnits; ! 170: sizeInBytes = format/8; ! 171: pProp = pWin->userProps; ! 172: while (pProp) ! 173: { ! 174: if (pProp->propertyName ==stuff->property) ! 175: break; ! 176: pProp = pProp->next; ! 177: } ! 178: if (!pProp) /* just add to list */ ! 179: { ! 180: pProp = (PropertyPtr)Xalloc(sizeof(PropertyRec)); ! 181: pProp->propertyName = stuff->property; ! 182: pProp->type = stuff->type; ! 183: pProp->format = format; ! 184: pProp->data = (pointer)Xalloc(sizeInBytes * len); ! 185: bcopy(&stuff[1], pProp->data, len * sizeInBytes); ! 186: pProp->size = len; ! 187: pProp->next = pWin->userProps; ! 188: pWin->userProps = pProp; ! 189: } ! 190: else ! 191: { ! 192: ! 193: /* To append or prepend to a property the request format and type ! 194: must match those of the already defined property. The ! 195: existing format and type are irrelevant when using the mode ! 196: "PropModeReplace" since they will be written over. */ ! 197: ! 198: if ((format != pProp->format) && (mode != PropModeReplace)) ! 199: return(BadMatch); ! 200: if ((pProp->type != stuff->type) && (mode != PropModeReplace)) ! 201: return(BadMatch); ! 202: /* XXX should check length too */ ! 203: if (mode == PropModeReplace) ! 204: { ! 205: pProp->data = (pointer)Xrealloc((char *) pProp->data, ! 206: sizeInBytes * len); ! 207: bcopy(&stuff[1], pProp->data, len * sizeInBytes); ! 208: pProp->size = len; ! 209: pProp->type = stuff->type; ! 210: pProp->format = stuff->format; ! 211: } ! 212: else if (mode == PropModeAppend) ! 213: { ! 214: pProp->data = (pointer)Xrealloc((char *) pProp->data, ! 215: sizeInBytes * (len + pProp->size)); ! 216: bcopy(&stuff[1], &pProp->data[pProp->size * sizeInBytes], ! 217: len * sizeInBytes); ! 218: pProp->size += len; ! 219: } ! 220: else if (mode == PropModePrepend) ! 221: { ! 222: pointer tstr = pProp->data; ! 223: pProp->data = (pointer)Xalloc(sizeInBytes * (len + pProp->size)); ! 224: bcopy(tstr, &pProp->data[len * sizeInBytes], ! 225: pProp->size * sizeInBytes); ! 226: bcopy(&stuff[1], pProp->data, len * sizeInBytes); ! 227: pProp->size += len; ! 228: Xfree(tstr); ! 229: } ! 230: } ! 231: event.u.u.type = PropertyNotify; ! 232: event.u.property.window = pWin->wid; ! 233: event.u.property.state = PropertyNewValue; ! 234: event.u.property.atom = pProp->propertyName; ! 235: event.u.property.time = currentTime.milliseconds; ! 236: DeliverEvents(pWin, &event, 1); ! 237: ! 238: return(client->noClientException); ! 239: } ! 240: ! 241: DeleteProperty(pWin, propName) ! 242: WindowPtr pWin; ! 243: ATOM propName; ! 244: { ! 245: PropertyPtr pProp, prevProp; ! 246: xEvent event; ! 247: ! 248: if (!(pProp = pWin->userProps)) ! 249: return(BadAtom); ! 250: prevProp = (PropertyPtr)NULL; ! 251: while (pProp) ! 252: { ! 253: if (pProp->propertyName == propName) ! 254: break; ! 255: prevProp = pProp; ! 256: pProp = pProp->next; ! 257: } ! 258: if (pProp) ! 259: { ! 260: if (prevProp == (PropertyPtr)NULL) /* takes care of head */ ! 261: { ! 262: pWin->userProps = pProp->next; ! 263: } ! 264: else ! 265: { ! 266: prevProp->next = pProp->next; ! 267: } ! 268: Xfree(pProp->data); ! 269: Xfree(pProp); ! 270: ! 271: event.u.u.type = PropertyNotify; ! 272: event.u.property.window = pWin->wid; ! 273: event.u.property.state = PropertyDelete; ! 274: event.u.property.atom = pProp->propertyName; ! 275: event.u.property.time = currentTime.milliseconds; ! 276: DeliverEvents(pWin, &event, 1); ! 277: ! 278: return(Success); ! 279: } ! 280: else ! 281: return(BadAtom); ! 282: } ! 283: ! 284: DeleteAllWindowProperties(pWin) ! 285: WindowPtr pWin; ! 286: { ! 287: PropertyPtr pProp, pNextProp; ! 288: xEvent event; ! 289: ! 290: pProp = pWin->userProps; ! 291: while (pProp) ! 292: { ! 293: event.u.u.type = PropertyNotify; ! 294: event.u.property.window = pWin->wid; ! 295: event.u.property.state = PropertyDelete; ! 296: event.u.property.atom = pProp->propertyName; ! 297: event.u.property.time = currentTime.milliseconds; ! 298: DeliverEvents(pWin, &event, 1); ! 299: pNextProp = pProp->next; ! 300: Xfree(pProp->data); ! 301: Xfree(pProp); ! 302: pProp = pNextProp; ! 303: } ! 304: } ! 305: ! 306: /***************** ! 307: * GetProperty ! 308: * If type Any is specified, returns the property from the specified ! 309: * window regardless of its type. If a type is specified, returns the ! 310: * property only if its type equals the specified type. ! 311: * If delete is True and a property is returned, the property is also ! 312: * deleted from the window and a PropertyNotify event is generated on the ! 313: * window. ! 314: *****************/ ! 315: ! 316: int ! 317: ProcGetProperty(client) ! 318: ClientPtr client; ! 319: { ! 320: PropertyPtr pProp, prevProp; ! 321: int n, len, ind; ! 322: WindowPtr pWin; ! 323: xGetPropertyReply reply; ! 324: REQUEST(xGetPropertyReq); ! 325: ! 326: REQUEST_SIZE_MATCH(xGetPropertyReq); ! 327: pWin = (WindowPtr)LookupWindow(stuff->window, client); ! 328: client->errorValue = stuff->window; ! 329: if (pWin) ! 330: { ! 331: if (ValidAtom(stuff->property) && ! 332: ((stuff->type == AnyPropertyType) || ValidAtom(stuff->type))) ! 333: { ! 334: pProp = pWin->userProps; ! 335: prevProp = (PropertyPtr)NULL; ! 336: while (pProp) ! 337: { ! 338: if (pProp->propertyName == stuff->property) ! 339: break; ! 340: prevProp = pProp; ! 341: pProp = pProp->next; ! 342: } ! 343: reply.type = X_Reply; ! 344: reply.sequenceNumber = client->sequence; ! 345: if (pProp) ! 346: { ! 347: ! 348: /* If the request type and actual type don't match. Return the ! 349: property information, but not the data. */ ! 350: ! 351: if ((stuff->type != pProp->type) && ! 352: (stuff->type != AnyPropertyType)) ! 353: { ! 354: reply.bytesAfter = pProp->size; ! 355: reply.format = pProp->format; ! 356: reply.length = 0; ! 357: reply.nItems = 0; ! 358: reply.propertyType = pProp->type; ! 359: WriteReplyToClient(client, sizeof(xGenericReply), &reply); ! 360: return(Success); ! 361: } ! 362: ! 363: /* ! 364: * Return type, format, value to client ! 365: */ ! 366: n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */ ! 367: ind = stuff->longOffset << 2; ! 368: ! 369: /* If longOffset is invalid such that it causes "len" to ! 370: be negative, it's a value error. */ ! 371: ! 372: if ((n - ind) < 0) ! 373: return BadValue; ! 374: ! 375: len = min(n - ind, 4 * stuff->longLength); ! 376: ! 377: reply.bytesAfter = n - (ind + len); ! 378: reply.format = pProp->format; ! 379: reply.length = len >> 2; ! 380: reply.nItems = len / (pProp->format / 8 ); ! 381: reply.propertyType = pProp->type; ! 382: WriteReplyToClient(client, sizeof(xGenericReply), &reply); ! 383: switch (reply.format) { ! 384: case 32: client->pSwapReplyFunc = CopySwap32Write; break; ! 385: case 16: client->pSwapReplyFunc = CopySwap16Write; break; ! 386: default: client->pSwapReplyFunc = WriteToClient; break; ! 387: } ! 388: WriteSwappedDataToClient(client, len, pProp->data + ind); ! 389: ! 390: if (stuff->delete && (reply.bytesAfter == 0)) ! 391: { /* delete the Property */ ! 392: xEvent event; ! 393: ! 394: if (prevProp == (PropertyPtr)NULL) /* takes care of head */ ! 395: pWin->userProps = pProp->next; ! 396: else ! 397: prevProp->next = pProp->next; ! 398: Xfree(pProp->data); ! 399: Xfree(pProp); ! 400: event.u.u.type = PropertyNotify; ! 401: event.u.property.window = pWin->wid; ! 402: event.u.property.state = PropertyDelete; ! 403: event.u.property.atom = pProp->propertyName; ! 404: event.u.property.time = currentTime.milliseconds; ! 405: DeliverEvents(pWin, &event, 1); ! 406: } ! 407: } ! 408: else ! 409: { ! 410: reply.nItems = 0; ! 411: reply.length = 0; ! 412: reply.bytesAfter = 0; ! 413: reply.propertyType = None; ! 414: reply.format = 0; ! 415: WriteReplyToClient(client, sizeof(xGenericReply), &reply); ! 416: } ! 417: return(client->noClientException); ! 418: ! 419: } ! 420: else ! 421: return(BadAtom); ! 422: } ! 423: else ! 424: return (BadWindow); ! 425: } ! 426: ! 427: int ! 428: ProcListProperties(client) ! 429: ClientPtr client; ! 430: { ! 431: Atom *pAtoms, *temppAtoms; ! 432: xListPropertiesReply xlpr; ! 433: int numProps = 0; ! 434: WindowPtr pWin; ! 435: PropertyPtr pProp; ! 436: REQUEST(xResourceReq); ! 437: ! 438: REQUEST_SIZE_MATCH(xResourceReq); ! 439: pWin = (WindowPtr)LookupWindow(stuff->id, client); ! 440: if (!pWin) ! 441: return(BadWindow); ! 442: ! 443: pProp = pWin->userProps; ! 444: while (pProp) ! 445: { ! 446: pProp = pProp->next; ! 447: numProps++; ! 448: } ! 449: if (numProps) ! 450: if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom)))) ! 451: return(client->noClientException = BadAlloc); ! 452: ! 453: xlpr.type = X_Reply; ! 454: xlpr.nProperties = numProps; ! 455: xlpr.length = (numProps * sizeof(Atom)) >> 2; ! 456: xlpr.sequenceNumber = client->sequence; ! 457: pProp = pWin->userProps; ! 458: temppAtoms = pAtoms; ! 459: while (pProp) ! 460: { ! 461: *temppAtoms++ = pProp->propertyName; ! 462: pProp = pProp->next; ! 463: } ! 464: WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); ! 465: if (numProps) ! 466: { ! 467: client->pSwapReplyFunc = Swap32Write; ! 468: WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); ! 469: DEALLOCATE_LOCAL(pAtoms); ! 470: } ! 471: return(client->noClientException); ! 472: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.