|
|
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.