|
|
1.1 ! root 1: #include "copyright.h" ! 2: /* Copyright Massachusetts Institute of Technology 1985, 1986, 1987 */ ! 3: ! 4: #ifndef lint ! 5: static char rcsid[] = "$Header: XlibInt.c,v 11.55 87/08/20 17:25:23 newman Exp $"; ! 6: #endif ! 7: ! 8: /* ! 9: * XlibInternal.c - Internal support routines for the C subroutine ! 10: * interface library (Xlib) to the X Window System Protocol V11.0. ! 11: */ ! 12: #define NEED_EVENTS ! 13: #define NEED_REPLIES ! 14: ! 15: #include <stdio.h> ! 16: #include "Xlibint.h" ! 17: ! 18: /* ! 19: * The following routines are internal routines used by Xlib for protocol ! 20: * packet transmission and reception. ! 21: * ! 22: * XIOError(Display *) will be called if any sort of system call error occurs. ! 23: * This is assumed to be a fatal condition, i.e., XIOError should not return. ! 24: * ! 25: * XError(Display *, XErrorEvent *) will be called whenever an X_Error event is ! 26: * received. This is not assumed to be a fatal condition, i.e., it is ! 27: * acceptable for this procedure to return. However, XError should NOT ! 28: * perform any operations (directly or indirectly) on the DISPLAY. ! 29: * ! 30: * Routines declared with a return type of 'Status' return 0 on failure, ! 31: * and non 0 on success. Routines with no declared return type don't ! 32: * return anything. Whenever possible routines that create objects return ! 33: * the object they have created. ! 34: */ ! 35: ! 36: _XQEvent *_qfree = NULL; /* NULL _XQEvent. */ ! 37: ! 38: static int padlength[4] = {0, 3, 2, 1}; ! 39: /* lookup table for adding padding bytes to data that is read from ! 40: or written to the X socket. */ ! 41: ! 42: static xReq _dummy_request = { ! 43: 0, 0, 0 ! 44: }; ! 45: /* ! 46: * _XFlush - Flush the X request buffer. If the buffer is empty, no ! 47: * action is taken. This routine correctly handles incremental writes. ! 48: * This routine may have to be reworked if int < long. ! 49: */ ! 50: _XFlush (dpy) ! 51: register Display *dpy; ! 52: { ! 53: register long size; ! 54: register int write_stat; ! 55: register char *bufindex; ! 56: ! 57: size = dpy->bufptr - dpy->buffer; ! 58: bufindex = dpy->bufptr = dpy->buffer; ! 59: /* ! 60: * While write has not written the entire buffer, keep looping ! 61: * until the entire buffer is written. bufindex will be incremented ! 62: * and size decremented as buffer is written out. ! 63: */ ! 64: while (size) { ! 65: write_stat = WriteToServer(dpy->fd, bufindex, (int) size); ! 66: if (write_stat > 0) { ! 67: size -= write_stat; ! 68: bufindex += write_stat; ! 69: } else { ! 70: /* Write failed! */ ! 71: /* errno set by write system call. */ ! 72: (*_XIOErrorFunction)(dpy); ! 73: } ! 74: } ! 75: dpy->last_req = (char *)&_dummy_request; ! 76: } ! 77: ! 78: /* ! 79: * _XRead - Read bytes from the socket taking into account incomplete ! 80: * reads. This routine may have to be reworked if int < long. ! 81: */ ! 82: _XRead (dpy, data, size) ! 83: register Display *dpy; ! 84: register char *data; ! 85: register long size; ! 86: { ! 87: register long bytes_read; ! 88: ! 89: if (size == 0) return; ! 90: while ((bytes_read = ReadFromServer(dpy->fd, data, (int)size)) ! 91: != size) { ! 92: ! 93: if (bytes_read > 0) { ! 94: size -= bytes_read; ! 95: data += bytes_read; ! 96: } ! 97: ! 98: else if (bytes_read == 0) { ! 99: /* Read failed because of end of file! */ ! 100: errno = EPIPE; ! 101: (*_XIOErrorFunction)(dpy); ! 102: } ! 103: ! 104: else /* bytes_read is less than 0; presumably -1 */ { ! 105: /* If it's a system call interrupt, it's not an error. */ ! 106: if (errno != EINTR) ! 107: (*_XIOErrorFunction)(dpy); ! 108: } ! 109: } ! 110: } ! 111: ! 112: /* ! 113: * _XReadPad - Read bytes from the socket taking into account incomplete ! 114: * reads. If the number of bytes is not 0 mod 32, read additional pad ! 115: * bytes. This routine may have to be reworked if int < long. ! 116: */ ! 117: _XReadPad (dpy, data, size) ! 118: register Display *dpy; ! 119: register char *data; ! 120: register long size; ! 121: { ! 122: register long bytes_read; ! 123: long padsize; ! 124: char pad[3]; ! 125: ! 126: if (size == 0) return; ! 127: /* ! 128: * The following hack is used to provide 32 bit long-word ! 129: * aligned padding. The [1] vector is of length 0, 1, 2, or 3, ! 130: * whatever is needed. ! 131: */ ! 132: padsize = padlength[size & 3]; ! 133: ! 134: while ((bytes_read = ReadFromServer (dpy->fd, data, size)) != size) { ! 135: ! 136: if (bytes_read > 0) { ! 137: size -= bytes_read; ! 138: data += bytes_read; ! 139: } ! 140: ! 141: else if (bytes_read == 0) { ! 142: /* Read failed because of end of file! */ ! 143: errno = EPIPE; ! 144: (*_XIOErrorFunction)(dpy); ! 145: } ! 146: ! 147: else /* bytes_read is less than 0; presumably -1 */ { ! 148: /* If it's a system call interrupt, it's not an error. */ ! 149: if (errno != EINTR) ! 150: (*_XIOErrorFunction)(dpy); ! 151: } ! 152: } ! 153: ! 154: size = padsize; ! 155: if (size == 0) return; ! 156: data = pad; ! 157: while ((bytes_read = ReadFromServer (dpy->fd, data, size)) != size) { ! 158: if (bytes_read > 0) { ! 159: size -= bytes_read; ! 160: data += bytes_read; ! 161: } ! 162: ! 163: else if (bytes_read == 0) { ! 164: /* Read failed because of end of file! */ ! 165: errno = EPIPE; ! 166: (*_XIOErrorFunction)(dpy); ! 167: } ! 168: ! 169: else /* bytes_read is less than 0; presumably -1 */ { ! 170: /* If it's a system call interrupt, it's not an error. */ ! 171: if (errno != EINTR) ! 172: (*_XIOErrorFunction)(dpy); ! 173: } ! 174: } ! 175: ! 176: } ! 177: ! 178: /* ! 179: * _XSend - Flush the buffer and send the client data. 32 bit word aligned ! 180: * transmission is used, if size is not 0 mod 4, extra bytes are transmitted. ! 181: * This routine may have to be reworked if int < long; ! 182: */ ! 183: _XSend (dpy, data, size) ! 184: register Display *dpy; ! 185: char *data; ! 186: register long size; ! 187: { ! 188: register long len; ! 189: static char pad[3] = {0, 0, 0}; ! 190: /* XText8 and XText16 require that the padding bytes be zero! */ ! 191: ! 192: len = dpy->bufptr - dpy->buffer; ! 193: dpy->bufptr = dpy->buffer; ! 194: if (len && WriteToServer(dpy->fd, dpy->buffer, len) != len) ! 195: (*_XIOErrorFunction)(dpy); ! 196: if (size && WriteToServer(dpy->fd, data, size) != size) ! 197: (*_XIOErrorFunction)(dpy); ! 198: /* ! 199: * The following hack is used to provide 32 bit long-word ! 200: * aligned padding. The [2] vector is of length 0, 1, 2, or 3, ! 201: * whatever is needed. ! 202: */ ! 203: len = padlength[size & 3]; ! 204: if (len && WriteToServer(dpy->fd, pad, len) != len) ! 205: (*_XIOErrorFunction)(dpy); ! 206: dpy->last_req = (char *) & _dummy_request; ! 207: } ! 208: ! 209: /* ! 210: * _XAllocID - normal resource ID allocation routine. A client ! 211: * can roll his own and instatantiate it if he wants, but must ! 212: * follow the rules. ! 213: */ ! 214: XID _XAllocID(dpy) ! 215: register Display *dpy; ! 216: { ! 217: return (dpy->resource_base + (dpy->resource_id++ << dpy->resource_shift)); ! 218: } ! 219: ! 220: /* ! 221: * _XReply - Wait for a reply packet and copy its contents into the ! 222: * specified rep. Mean while we must handle error and event packets that ! 223: * we may encounter. ! 224: */ ! 225: Status _XReply (dpy, rep, extra, discard) ! 226: register Display *dpy; ! 227: register xReply *rep; ! 228: int extra; /* number of 32-bit words expected after the reply */ ! 229: Bool discard; /* should I discard data followind "extra" words? */ ! 230: { ! 231: _XFlush(dpy); ! 232: while (1) { ! 233: _XRead(dpy, (char *)rep, (long)sizeof(xReply)); ! 234: switch ((int)rep->generic.type) { ! 235: ! 236: case X_Reply: ! 237: /* Reply recieved. */ ! 238: if (extra == 0) { ! 239: if (discard && (rep->generic.length > 0)) ! 240: /* unexpectedly long reply! */ ! 241: _EatData (dpy, rep->generic.length); ! 242: return (1); ! 243: } ! 244: if (extra == rep->generic.length) { ! 245: /* ! 246: * Read the extra data into storage immediately following ! 247: * the GenericReply structure. ! 248: */ ! 249: _XRead (dpy, (char *) (rep+1), ((long)extra)<<2); ! 250: return (1); ! 251: } ! 252: if (extra < rep->generic.length) { ! 253: /* Actual reply is longer than "extra" */ ! 254: _XRead (dpy, (char *) (rep+1), ((long)extra)<<2); ! 255: if (discard) ! 256: _EatData (dpy, rep->generic.length - extra); ! 257: return (1); ! 258: } ! 259: /* ! 260: *if we get here, then extra > rep->generic.length--meaning we ! 261: * read a reply that's shorter than we expected. This is an ! 262: * error, but we still need to figure out how to handle it... ! 263: */ ! 264: _XRead (dpy, (char *) (rep+1), (long) (rep->generic.length<<2)); ! 265: (*_XIOErrorFunction) (dpy); ! 266: return (0); ! 267: ! 268: case X_Error: ! 269: { ! 270: register _XExtension *ext; ! 271: register Bool ret = False; ! 272: int ret_code; ! 273: xError *err = (xError *) rep; ! 274: if (err->sequenceNumber == dpy->request) ! 275: /* do not die on "no such font", "can't allocate", ! 276: "can't grab" failures */ ! 277: switch ((int)err->errorCode) { ! 278: case BadName: ! 279: switch (err->majorCode) ! 280: case X_OpenFont: ! 281: case X_LookupColor: ! 282: case X_AllocNamedColor: ! 283: return(0); ! 284: break; ! 285: case BadFont: ! 286: if (err->majorCode == X_QueryFont) ! 287: return (0); ! 288: break; ! 289: case BadAlloc: ! 290: case BadAccess: ! 291: return (0); ! 292: /* ! 293: * we better see if there is an extension who may ! 294: * want to suppress the error. ! 295: */ ! 296: default: ! 297: ext = dpy->ext_procs; ! 298: while (ext) { ! 299: if (ext->error != NULL) ! 300: ret = (*ext->error) ! 301: (dpy, err, &ext->codes, &ret_code); ! 302: ext = ext->next; ! 303: } ! 304: if (ret) return (ret_code); ! 305: break; ! 306: } ! 307: _XError(dpy, err); ! 308: if (err->sequenceNumber == dpy->request) ! 309: return(0); ! 310: } ! 311: break; ! 312: default: ! 313: _XEnq(dpy, (xEvent *) rep); ! 314: break; ! 315: } ! 316: } ! 317: } ! 318: ! 319: ! 320: /* Read and discard "n" 32-bit words. */ ! 321: ! 322: static _EatData (dpy, n) ! 323: Display *dpy; ! 324: unsigned long n; ! 325: { ! 326: unsigned int bufsize; ! 327: char *buf; ! 328: n <<= 2; /* convert to number of bytes */ ! 329: buf = Xmalloc (bufsize = (n > 2048) ? 2048 : n); ! 330: while (n) { ! 331: long bytes_read = (n > bufsize) ? bufsize : n; ! 332: _XRead (dpy, buf, bytes_read); ! 333: n -= bytes_read; ! 334: } ! 335: Xfree (buf); ! 336: } ! 337: ! 338: /* ! 339: * _XEnq - Place event packets on the display's queue. ! 340: * note that no squishing of move events in V11, since there ! 341: * is pointer motion hints.... ! 342: */ ! 343: _XEnq (dpy, event) ! 344: register Display *dpy; ! 345: register xEvent *event; ! 346: { ! 347: register _XQEvent *qelt; ! 348: ! 349: /*NOSTRICT*/ ! 350: if (qelt = _qfree) { ! 351: /* If _qfree is non-NULL do this, else malloc a new one. */ ! 352: _qfree = qelt->next; ! 353: } ! 354: else if ((qelt = ! 355: (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) { ! 356: /* Malloc call failed! */ ! 357: errno = ENOMEM; ! 358: (*_XIOErrorFunction)(dpy); ! 359: } ! 360: qelt->next = NULL; ! 361: /* go call through display to find proper event reformatter */ ! 362: (*dpy->event_vec[event->u.u.type & 0177])(dpy, &qelt->event, event); ! 363: ! 364: if (dpy->tail) dpy->tail->next = qelt; ! 365: else dpy->head = qelt; ! 366: ! 367: dpy->tail = qelt; ! 368: dpy->qlen++; ! 369: } ! 370: /* ! 371: * EventToWire in seperate file in that often not needed. ! 372: */ ! 373: ! 374: /*ARGSUSED*/ ! 375: _XUnknownWireEvent(dpy, re, event) ! 376: register Display *dpy; /* pointer to display structure */ ! 377: register XEvent *re; /* pointer to where event should be reformatted */ ! 378: register xEvent *event; /* wire protocol event */ ! 379: { ! 380: (void) fprintf(stderr, ! 381: "Xlib: unhandled wire event! event number = %d, display = %x\n.", ! 382: event->u.u.type, dpy); ! 383: exit(1); ! 384: } ! 385: ! 386: /*ARGSUSED*/ ! 387: _XUnknownNativeEvent(dpy, re, event) ! 388: register Display *dpy; /* pointer to display structure */ ! 389: register XEvent *re; /* pointer to where event should be reformatted */ ! 390: register xEvent *event; /* wire protocol event */ ! 391: { ! 392: (void) fprintf(stderr, ! 393: "Xlib: unhandled native event! event number = %d, display = %x\n.", ! 394: re->type, dpy); ! 395: exit(1); ! 396: } ! 397: /* ! 398: * reformat a wire event into an XEvent structure of the right type. ! 399: */ ! 400: _XWireToEvent(dpy, re, event) ! 401: register Display *dpy; /* pointer to display structure */ ! 402: register XEvent *re; /* pointer to where event should be reformatted */ ! 403: register xEvent *event; /* wire protocol event */ ! 404: { ! 405: ! 406: ((XAnyEvent *)re)->display = dpy; ! 407: re->type = event->u.u.type; ! 408: ! 409: /* Ignore the leading bit of the event type since it is set when a ! 410: client sends an event rather than the server. */ ! 411: ! 412: switch (event-> u.u.type & 0177) { ! 413: case KeyPress: ! 414: case KeyRelease: ! 415: { ! 416: register XKeyEvent *ev = (XKeyEvent*) re; ! 417: ev->root = event->u.keyButtonPointer.root; ! 418: ev->window = event->u.keyButtonPointer.event; ! 419: ev->subwindow = event->u.keyButtonPointer.child; ! 420: ev->time = event->u.keyButtonPointer.time; ! 421: ev->x = event->u.keyButtonPointer.eventX; ! 422: ev->y = event->u.keyButtonPointer.eventY; ! 423: ev->x_root = event->u.keyButtonPointer.rootX; ! 424: ev->y_root = event->u.keyButtonPointer.rootY; ! 425: ev->state = event->u.keyButtonPointer.state; ! 426: ev->same_screen = event->u.keyButtonPointer.sameScreen; ! 427: ev->keycode = event->u.u.detail; ! 428: } ! 429: break; ! 430: case ButtonPress: ! 431: case ButtonRelease: ! 432: { ! 433: register XButtonEvent *ev = (XButtonEvent *) re; ! 434: ev->root = event->u.keyButtonPointer.root; ! 435: ev->window = event->u.keyButtonPointer.event; ! 436: ev->subwindow = event->u.keyButtonPointer.child; ! 437: ev->time = event->u.keyButtonPointer.time; ! 438: ev->x = event->u.keyButtonPointer.eventX; ! 439: ev->y = event->u.keyButtonPointer.eventY; ! 440: ev->x_root = event->u.keyButtonPointer.rootX; ! 441: ev->y_root = event->u.keyButtonPointer.rootY; ! 442: ev->state = event->u.keyButtonPointer.state; ! 443: ev->same_screen = event->u.keyButtonPointer.sameScreen; ! 444: ev->button = event->u.u.detail; ! 445: } ! 446: break; ! 447: case MotionNotify: ! 448: { ! 449: register XMotionEvent *ev = (XMotionEvent *)re; ! 450: ev->root = event->u.keyButtonPointer.root; ! 451: ev->window = event->u.keyButtonPointer.event; ! 452: ev->subwindow = event->u.keyButtonPointer.child; ! 453: ev->time = event->u.keyButtonPointer.time; ! 454: ev->x = event->u.keyButtonPointer.eventX; ! 455: ev->y = event->u.keyButtonPointer.eventY; ! 456: ev->x_root = event->u.keyButtonPointer.rootX; ! 457: ev->y_root = event->u.keyButtonPointer.rootY; ! 458: ev->state = event->u.keyButtonPointer.state; ! 459: ev->same_screen = event->u.keyButtonPointer.sameScreen; ! 460: ev->is_hint = event->u.u.detail; ! 461: } ! 462: break; ! 463: case EnterNotify: ! 464: case LeaveNotify: ! 465: { ! 466: register XCrossingEvent *ev = (XCrossingEvent *) re; ! 467: ev->root = event->u.enterLeave.root; ! 468: ev->window = event->u.enterLeave.event; ! 469: ev->subwindow = event->u.enterLeave.child; ! 470: ev->time = event->u.enterLeave.time; ! 471: ev->x = event->u.enterLeave.eventX; ! 472: ev->y = event->u.enterLeave.eventY; ! 473: ev->x_root = event->u.enterLeave.rootX; ! 474: ev->y_root = event->u.enterLeave.rootY; ! 475: ev->state = event->u.enterLeave.state; ! 476: ev->mode = event->u.enterLeave.mode; ! 477: ev->same_screen = (event->u.enterLeave.flags & ! 478: ELFlagSameScreen) && True; ! 479: ev->focus = (event->u.enterLeave.flags & ! 480: ELFlagFocus) && True; ! 481: ev->detail = event->u.u.detail; ! 482: } ! 483: break; ! 484: case FocusIn: ! 485: case FocusOut: ! 486: { ! 487: register XFocusChangeEvent *ev = (XFocusChangeEvent *) re; ! 488: ev->window = event->u.focus.window; ! 489: ev->mode = event->u.focus.mode; ! 490: ev->detail = event->u.u.detail; ! 491: } ! 492: break; ! 493: case KeymapNotify: ! 494: { ! 495: register XKeymapEvent *ev = (XKeymapEvent *) re; ! 496: ev->window = dpy->current; ! 497: bcopy ((char *)((xKeymapEvent *) event)->map, ! 498: &ev->key_vector[1], ! 499: sizeof (((xKeymapEvent *) event)->map)); ! 500: } ! 501: break; ! 502: case Expose: ! 503: { ! 504: register XExposeEvent *ev = (XExposeEvent *) re; ! 505: ev->window = event->u.expose.window; ! 506: ev->x = event->u.expose.x; ! 507: ev->y = event->u.expose.y; ! 508: ev->width = event->u.expose.width; ! 509: ev->height = event->u.expose.height; ! 510: ev->count = event->u.expose.count; ! 511: } ! 512: break; ! 513: case GraphicsExpose: ! 514: { ! 515: register XGraphicsExposeEvent *ev = ! 516: (XGraphicsExposeEvent *) re; ! 517: ev->drawable = event->u.graphicsExposure.drawable; ! 518: ev->x = event->u.graphicsExposure.x; ! 519: ev->y = event->u.graphicsExposure.y; ! 520: ev->width = event->u.graphicsExposure.width; ! 521: ev->height = event->u.graphicsExposure.height; ! 522: ev->count = event->u.graphicsExposure.count; ! 523: ev->major_code = event->u.graphicsExposure.majorEvent; ! 524: ev->minor_code = event->u.graphicsExposure.minorEvent; ! 525: } ! 526: break; ! 527: case NoExpose: ! 528: { ! 529: register XNoExposeEvent *ev = (XNoExposeEvent *) re; ! 530: ev->drawable = event->u.noExposure.drawable; ! 531: ev->major_code = event->u.noExposure.majorEvent; ! 532: ev->minor_code = event->u.noExposure.minorEvent; ! 533: } ! 534: break; ! 535: case VisibilityNotify: ! 536: { ! 537: register XVisibilityEvent *ev = (XVisibilityEvent *) re; ! 538: ev->window = event->u.visibility.window; ! 539: ev->state = event->u.visibility.state; ! 540: } ! 541: break; ! 542: case CreateNotify: ! 543: { ! 544: register XCreateWindowEvent *ev = ! 545: (XCreateWindowEvent *) re; ! 546: ev->window = event->u.createNotify.window; ! 547: ev->parent = event->u.createNotify.parent; ! 548: ev->x = event->u.createNotify.x; ! 549: ev->y = event->u.createNotify.y; ! 550: ev->width = event->u.createNotify.width; ! 551: ev->height = event->u.createNotify.height; ! 552: ev->border_width = event->u.createNotify.borderWidth; ! 553: ev->override_redirect = event->u.createNotify.override; ! 554: } ! 555: break; ! 556: case DestroyNotify: ! 557: { ! 558: register XDestroyWindowEvent *ev = ! 559: (XDestroyWindowEvent *) re; ! 560: ev->window = event->u.destroyNotify.window; ! 561: ev->event = event->u.destroyNotify.event; ! 562: } ! 563: break; ! 564: case UnmapNotify: ! 565: { ! 566: register XUnmapEvent *ev = (XUnmapEvent *) re; ! 567: ev->window = event->u.unmapNotify.window; ! 568: ev->event = event->u.unmapNotify.event; ! 569: ev->from_configure = event->u.unmapNotify.fromConfigure; ! 570: } ! 571: break; ! 572: case MapNotify: ! 573: { ! 574: register XMapEvent *ev = (XMapEvent *) re; ! 575: ev->window = event->u.mapNotify.window; ! 576: ev->event = event->u.mapNotify.event; ! 577: ev->override_redirect = event->u.mapNotify.override; ! 578: } ! 579: break; ! 580: case MapRequest: ! 581: { ! 582: register XMapRequestEvent *ev = (XMapRequestEvent *) re; ! 583: ev->window = event->u.mapRequest.window; ! 584: ev->parent = event->u.mapRequest.parent; ! 585: } ! 586: break; ! 587: case ReparentNotify: ! 588: { ! 589: register XReparentEvent *ev = (XReparentEvent *) re; ! 590: ev->event = event->u.reparent.event; ! 591: ev->window = event->u.reparent.window; ! 592: ev->parent = event->u.reparent.parent; ! 593: ev->x = event->u.reparent.x; ! 594: ev->y = event->u.reparent.y; ! 595: ev->override_redirect = event->u.reparent.override; ! 596: } ! 597: break; ! 598: case ConfigureNotify: ! 599: { ! 600: register XConfigureEvent *ev = (XConfigureEvent *) re; ! 601: ev->event = event->u.configureNotify.event; ! 602: ev->window = event->u.configureNotify.window; ! 603: ev->above = event->u.configureNotify.aboveSibling; ! 604: ev->x = event->u.configureNotify.x; ! 605: ev->y = event->u.configureNotify.y; ! 606: ev->width = event->u.configureNotify.width; ! 607: ev->height = event->u.configureNotify.height; ! 608: ev->border_width = event->u.configureNotify.borderWidth; ! 609: ev->override_redirect = event->u.configureNotify.override; ! 610: } ! 611: break; ! 612: case ConfigureRequest: ! 613: { ! 614: register XConfigureRequestEvent *ev = ! 615: (XConfigureRequestEvent *) re; ! 616: ev->window = event->u.configureRequest.window; ! 617: ev->parent = event->u.configureRequest.parent; ! 618: ev->above = event->u.configureRequest.sibling; ! 619: ev->x = event->u.configureRequest.x; ! 620: ev->y = event->u.configureRequest.y; ! 621: ev->width = event->u.configureRequest.width; ! 622: ev->height = event->u.configureRequest.height; ! 623: ev->border_width = event->u.configureRequest.borderWidth; ! 624: ev->value_mask = event->u.configureRequest.valueMask; ! 625: ev->detail = event->u.u.detail; ! 626: } ! 627: break; ! 628: case GravityNotify: ! 629: { ! 630: register XGravityEvent *ev = (XGravityEvent *) re; ! 631: ev->window = event->u.gravity.window; ! 632: ev->event = event->u.gravity.event; ! 633: ev->x = event->u.gravity.x; ! 634: ev->y = event->u.gravity.y; ! 635: } ! 636: break; ! 637: case ResizeRequest: ! 638: { ! 639: register XResizeRequestEvent *ev = ! 640: (XResizeRequestEvent *) re; ! 641: ev->window = event->u.resizeRequest.window; ! 642: ev->width = event->u.resizeRequest.width; ! 643: ev->height = event->u.resizeRequest.height; ! 644: } ! 645: break; ! 646: case CirculateNotify: ! 647: { ! 648: register XCirculateEvent *ev = (XCirculateEvent *) re; ! 649: ev->window = event->u.circulate.window; ! 650: ev->event = event->u.circulate.event; ! 651: ev->place = event->u.circulate.place; ! 652: } ! 653: break; ! 654: case CirculateRequest: ! 655: { ! 656: register XCirculateRequestEvent *ev = ! 657: (XCirculateRequestEvent *) re; ! 658: ev->window = event->u.circulate.window; ! 659: ev->parent = event->u.circulate.event; ! 660: ev->place = event->u.circulate.place; ! 661: } ! 662: break; ! 663: case PropertyNotify: ! 664: { ! 665: register XPropertyEvent *ev = (XPropertyEvent *) re; ! 666: ev->window = event->u.property.window; ! 667: ev->atom = event->u.property.atom; ! 668: ev->time = event->u.property.time; ! 669: ev->state = event->u.property.state; ! 670: } ! 671: break; ! 672: case SelectionClear: ! 673: { ! 674: register XSelectionClearEvent *ev = ! 675: (XSelectionClearEvent *) re; ! 676: ev->window = event->u.selectionClear.window; ! 677: ev->selection = event->u.selectionClear.atom; ! 678: ev->time = event->u.selectionClear.time; ! 679: } ! 680: break; ! 681: case SelectionRequest: ! 682: { ! 683: register XSelectionRequestEvent *ev = ! 684: (XSelectionRequestEvent *) re; ! 685: ev->owner = event->u.selectionRequest.owner; ! 686: ev->requestor = event->u.selectionRequest.requestor; ! 687: ev->selection = event->u.selectionRequest.selection; ! 688: ev->target = event->u.selectionRequest.target; ! 689: ev->property = event->u.selectionRequest.property; ! 690: ev->time = event->u.selectionRequest.time; ! 691: } ! 692: break; ! 693: case SelectionNotify: ! 694: { ! 695: register XSelectionEvent *ev = (XSelectionEvent *) re; ! 696: ev->requestor = event->u.selectionNotify.requestor; ! 697: ev->selection = event->u.selectionNotify.selection; ! 698: ev->target = event->u.selectionNotify.target; ! 699: ev->property = event->u.selectionNotify.property; ! 700: ev->time = event->u.selectionNotify.time; ! 701: } ! 702: break; ! 703: case ColormapNotify: ! 704: { ! 705: register XColormapEvent *ev = (XColormapEvent *) re; ! 706: ev->window = event->u.colormap.window; ! 707: ev->colormap = event->u.colormap.colormap; ! 708: ev->new = event->u.colormap.new; ! 709: ev->state = event->u.colormap.state; ! 710: } ! 711: break; ! 712: case ClientMessage: ! 713: { ! 714: register int i; ! 715: register XClientMessageEvent *ev ! 716: = (XClientMessageEvent *) re; ! 717: ev->window = event->u.clientMessage.window; ! 718: ev->format = event->u.u.detail; ! 719: switch (ev->format) { ! 720: case 8: ! 721: ev->message_type = event->u.clientMessage.u.b.type; ! 722: for (i = 0; i < 20; i++) ! 723: ev->data.b[i] = event->u.clientMessage.u.b.bytes[i]; ! 724: break; ! 725: case 16: ! 726: ev->message_type = event->u.clientMessage.u.s.type; ! 727: ev->data.s[0] = event->u.clientMessage.u.s.shorts0; ! 728: ev->data.s[1] = event->u.clientMessage.u.s.shorts1; ! 729: ev->data.s[2] = event->u.clientMessage.u.s.shorts2; ! 730: ev->data.s[3] = event->u.clientMessage.u.s.shorts3; ! 731: ev->data.s[4] = event->u.clientMessage.u.s.shorts4; ! 732: ev->data.s[5] = event->u.clientMessage.u.s.shorts5; ! 733: ev->data.s[6] = event->u.clientMessage.u.s.shorts6; ! 734: ev->data.s[7] = event->u.clientMessage.u.s.shorts7; ! 735: ev->data.s[8] = event->u.clientMessage.u.s.shorts8; ! 736: ev->data.s[9] = event->u.clientMessage.u.s.shorts9; ! 737: break; ! 738: case 32: ! 739: ev->message_type = event->u.clientMessage.u.l.type; ! 740: ev->data.l[0] = event->u.clientMessage.u.l.longs0; ! 741: ev->data.l[1] = event->u.clientMessage.u.l.longs1; ! 742: ev->data.l[2] = event->u.clientMessage.u.l.longs2; ! 743: ev->data.l[3] = event->u.clientMessage.u.l.longs3; ! 744: ev->data.l[4] = event->u.clientMessage.u.l.longs4; ! 745: break; ! 746: default: /* XXX should never occur */ ! 747: break; ! 748: } ! 749: } ! 750: break; ! 751: case MappingNotify: ! 752: { ! 753: register XMappingEvent *ev = (XMappingEvent *)re; ! 754: ev->first_keycode = event->u.mappingNotify.firstKeyCode; ! 755: ev->request = event->u.mappingNotify.request; ! 756: ev->count = event->u.mappingNotify.count; ! 757: } ! 758: break; ! 759: default: ! 760: /* XXX should do something about unknown event here */ ! 761: break; ! 762: } ! 763: } ! 764: ! 765: ! 766: /* ! 767: * _XIOError - Default fatal system error reporting routine. Called when ! 768: * an X internal system error is encountered. ! 769: */ ! 770: _XIOError (dpy) ! 771: Display *dpy; ! 772: { ! 773: if (errno == EPIPE) { ! 774: (void) fprintf (stderr, ! 775: "Connection # %d to server broken.\n", dpy->fd); ! 776: } ! 777: perror("XIO"); ! 778: exit(1); ! 779: } ! 780: ! 781: /* ! 782: * _XError - Default non-fatal error reporting routine. Called when an ! 783: * X_Error packet is encountered in the input stream. ! 784: */ ! 785: int _XError (dpy, rep) ! 786: Display *dpy; ! 787: xError *rep; ! 788: { ! 789: XErrorEvent event; ! 790: /* ! 791: * X_Error packet encountered! We need to unpack the error before ! 792: * giving it to the user. ! 793: */ ! 794: ! 795: event.display = dpy; ! 796: event.type = X_Error; ! 797: event.serial = rep->sequenceNumber; ! 798: event.resourceid = rep->resourceID; ! 799: event.error_code = rep->errorCode; ! 800: event.request_code = rep->majorCode; ! 801: event.minor_code = rep->minorCode; ! 802: if (_XErrorFunction != NULL) { ! 803: return ((*_XErrorFunction)(dpy, &event)); ! 804: } ! 805: exit(1); ! 806: return(0); /* stupid lint */ ! 807: } ! 808: ! 809: int _XDefaultError(dpy, event) ! 810: Display *dpy; ! 811: XErrorEvent *event; ! 812: { ! 813: char buffer[BUFSIZ]; ! 814: char mesg[BUFSIZ]; ! 815: char number[32]; ! 816: char *mtype = "XlibMessage"; ! 817: XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); ! 818: XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); ! 819: (void) fprintf(stderr, "%s: %s\n ", mesg, buffer); ! 820: XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", ! 821: mesg, BUFSIZ); ! 822: (void) fprintf(stderr, mesg, event->request_code); ! 823: sprintf(number, "%d", event->request_code); ! 824: XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); ! 825: (void) fprintf(stderr, " %s", buffer); ! 826: fputs("\n ", stderr); ! 827: XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code", ! 828: mesg, BUFSIZ); ! 829: (void) fprintf(stderr, mesg, event->minor_code); ! 830: fputs("\n ", stderr); ! 831: XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", ! 832: mesg, BUFSIZ); ! 833: (void) fprintf(stderr, mesg, event->resourceid); ! 834: fputs("\n ", stderr); ! 835: XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", ! 836: mesg, BUFSIZ); ! 837: (void) fprintf(stderr, mesg, event->serial); ! 838: fputs("\n ", stderr); ! 839: XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", ! 840: mesg, BUFSIZ); ! 841: (void) fprintf(stderr, mesg, dpy->request); ! 842: fputs("\n ", stderr); ! 843: if (event->error_code == BadImplementation) return 0; ! 844: exit(1); ! 845: return (0); /* stupid lint */ ! 846: } ! 847: ! 848: int (*_XIOErrorFunction)() = _XIOError; ! 849: int (*_XErrorFunction)() = _XDefaultError; ! 850: ! 851: /* ! 852: * This routine can be used to (cheaply) get some memory within a single ! 853: * Xlib routine for scratch space. It is reallocated from the same place ! 854: * each time, unless the library needs a large scratch space. ! 855: */ ! 856: char *_XAllocScratch (dpy, nbytes) ! 857: register Display *dpy; ! 858: unsigned long nbytes; ! 859: { ! 860: if (nbytes > dpy->scratch_length) { ! 861: if (dpy->scratch_buffer != NULL) Xfree (dpy->scratch_buffer); ! 862: return( dpy->scratch_length = nbytes, ! 863: dpy->scratch_buffer = Xmalloc ((unsigned)nbytes) ); ! 864: } ! 865: return (dpy->scratch_buffer); ! 866: } ! 867: ! 868: /* ! 869: * Given a visual id, find the visual structure for this id on this display. ! 870: */ ! 871: Visual *_XVIDtoVisual (dpy, id) ! 872: Display *dpy; ! 873: VisualID id; ! 874: { ! 875: register int i, j, k; ! 876: register Screen *sp; ! 877: register Depth *dp; ! 878: register Visual *vp; ! 879: for (i = 0; i < dpy->nscreens; i++) { ! 880: sp = &dpy->screens[i]; ! 881: for (j = 0; j < sp->ndepths; j++) { ! 882: dp = &sp->depths[j]; ! 883: for (k = 0; k < dp->nvisuals; k++) { ! 884: vp = &dp->visuals[k]; ! 885: if (vp->visualid == id) return (vp); ! 886: } ! 887: } ! 888: } ! 889: return (NULL); ! 890: } ! 891: ! 892: XFree (data) ! 893: char *data; ! 894: { ! 895: Xfree (data); ! 896: } ! 897: ! 898: #ifdef BIGSHORTS ! 899: UnpackShorts(from, to, bytes) ! 900: ushort_p *from; ! 901: short *to; ! 902: unsigned bytes; ! 903: { ! 904: unsigned i; ! 905: for (i = 0; i < (bytes/psizeof(short)); i++) ! 906: if (i&1) ! 907: to[i] = from[i>>1].right; ! 908: else ! 909: to[i] = from[i>>1].left; ! 910: } ! 911: ! 912: char packbuffer[1000]; ! 913: PackData(dpy, data, len) ! 914: register Display *dpy; ! 915: short *data; ! 916: unsigned len; ! 917: { ! 918: if (dpy->bufptr + len < dpy->bufmax) { ! 919: PackShorts(data, dpy->bufptr, len); ! 920: dpy->bufptr += (len + 3) & ~3; ! 921: } else { ! 922: PackShorts(data, packbuffer, len); ! 923: _XSend(dpy, packbuffer, len); ! 924: } ! 925: } ! 926: ! 927: PackShorts(from, to, bytes) ! 928: short *from; ! 929: char *to; ! 930: unsigned bytes; ! 931: { ! 932: unsigned i, n, offset; ! 933: ushort_p *uto; ! 934: ! 935: uto = (ushort_p *)to; ! 936: offset = ((int)to & 2) >> 1; /* lost 2 bits of pointer */ ! 937: n = (bytes / 2) + offset; ! 938: for (i = offset; i < n; i++) { ! 939: if (i&1) ! 940: uto[i>>1].right = from[i-offset]; ! 941: else ! 942: uto[i>>1].left = from[i-offset]; ! 943: } ! 944: } ! 945: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.