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