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