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