aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/dps/cslibint.c
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
committerReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
commitf4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch)
tree2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/lib/dps/cslibint.c
parenta840692edc9c6d19cd7c057f68e39c7d95eb767d (diff)
downloadnx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz Keywords: Imported nx-X11-3.1.0-1.tar.gz into Git repository
Diffstat (limited to 'nx-X11/lib/dps/cslibint.c')
-rw-r--r--nx-X11/lib/dps/cslibint.c1910
1 files changed, 1910 insertions, 0 deletions
diff --git a/nx-X11/lib/dps/cslibint.c b/nx-X11/lib/dps/cslibint.c
new file mode 100644
index 000000000..84d7b753e
--- /dev/null
+++ b/nx-X11/lib/dps/cslibint.c
@@ -0,0 +1,1910 @@
+/*
+ * cslibint.c -- low level I/O
+ *
+ * (c) Copyright 1993-1994 Adobe Systems Incorporated.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sublicense this software
+ * and its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notices appear in all copies and that
+ * both those copyright notices and this permission notice appear in
+ * supporting documentation and that the name of Adobe Systems Incorporated
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. No trademark license
+ * to use the Adobe trademarks is hereby granted. If the Adobe trademark
+ * "Display PostScript"(tm) is used to describe this software, its
+ * functionality or for any other purpose, such use shall be limited to a
+ * statement that this software works in conjunction with the Display
+ * PostScript system. Proper trademark attribution to reflect Adobe's
+ * ownership of the trademark shall be given whenever any such reference to
+ * the Display PostScript system is made.
+ *
+ * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
+ * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
+ * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE
+ * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT
+ * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
+ *
+ * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
+ * Incorporated which may be registered in certain jurisdictions
+ *
+ * Portions Copyright 1985, 1986, 1987 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * Author: Adobe Systems Incorporated and MIT X Consortium
+ */
+/* $XFree86: xc/lib/dps/cslibint.c,v 1.4tsi Exp $ */
+
+/*
+ * XlibInternal.c - Internal support routines for the C subroutine
+ * interface library (Xlib) to the X Window System Protocol V11.0.
+ */
+#define NEED_EVENTS
+#define NEED_REPLIES
+
+#include <X11/Xlibint.h>
+#include <X11/Xos.h>
+#include "Xlibnet.h"
+#include <stdio.h>
+
+#include "dpsassert.h"
+#include "cslibint.h"
+
+static void _EatData32 (Display *dpy, unsigned long n);
+
+/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+ */
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define ETEST(err) (err == EAGAIN)
+#else
+#define ETEST(err) (err == EWOULDBLOCK)
+#endif
+#endif
+
+#ifdef LACHMAN
+#ifdef EMSGSIZE
+#undef EMSGSIZE
+#endif
+#define EMSGSIZE ERANGE
+#endif
+
+#if defined(SVR4) && defined(sun)
+#define SUNSYSV 1
+#endif
+
+/*
+ * The following routines are internal routines used by Xlib for protocol
+ * packet transmission and reception.
+ *
+ * XIOError(Display *) will be called if any sort of system call error occurs.
+ * This is assumed to be a fatal condition, i.e., XIOError should not return.
+ *
+ * XError(Display *, XErrorEvent *) will be called whenever an X_Error event is
+ * received. This is not assumed to be a fatal condition, i.e., it is
+ * acceptable for this procedure to return. However, XError should NOT
+ * perform any operations (directly or indirectly) on the DISPLAY.
+ *
+ * Routines declared with a return type of 'Status' return 0 on failure,
+ * and non 0 on success. Routines with no declared return type don't
+ * return anything. Whenever possible routines that create objects return
+ * the object they have created.
+ */
+
+extern _XQEvent *_qfree;
+
+static int padlength[4] = {0, 3, 2, 1};
+ /* lookup table for adding padding bytes to data that is read from
+ or written to the X socket. */
+
+static xReq _dummy_request = {
+ 0, 0, 0
+};
+/*
+ * N_XFlush - Flush the X request buffer. If the buffer is empty, no
+ * action is taken. This routine correctly handles incremental writes.
+ * This routine may have to be reworked if int < long.
+ */
+void N_XFlush (Display *dpy)
+{
+ register long size, todo;
+ register int write_stat;
+ register char *bufindex;
+
+ if (!dpy) return;
+
+ if (dpy->flags & XlibDisplayIOError) return;
+
+ size = todo = dpy->bufptr - dpy->buffer;
+ bufindex = dpy->bufptr = dpy->buffer;
+ /*
+ * While write has not written the entire buffer, keep looping
+ * until the entire buffer is written. bufindex will be incremented
+ * and size decremented as buffer is written out.
+ */
+ while (size) {
+ errno = 0;
+ write_stat = WriteToServer(dpy->fd, bufindex, (int) todo);
+ if (write_stat >= 0) {
+ size -= write_stat;
+ todo = size;
+ bufindex += write_stat;
+ } else if (ETEST(errno)) {
+ N_XWaitForWritable(dpy);
+#ifdef SUNSYSV
+ } else if (errno == 0) {
+ N_XWaitForWritable(dpy);
+#endif
+#ifdef EMSGSIZE
+ } else if (errno == EMSGSIZE) {
+ if (todo > 1)
+ todo >>= 1;
+ else
+ N_XWaitForWritable(dpy);
+#endif
+ } else if (errno != EINTR) {
+ /* Write failed! */
+ /* errno set by write system call. */
+ _XIOError(dpy);
+ }
+ }
+ dpy->last_req = (char *)&_dummy_request;
+}
+
+#ifdef NEEDFORNX
+
+int
+_XEventsQueued (Display *dpy, int mode)
+{
+ register int len;
+ int pend;
+ char buf[BUFSIZE];
+ register xReply *rep;
+
+ if (mode == QueuedAfterFlush)
+ {
+ _XFlush(dpy);
+ if (dpy->qlen)
+ return(dpy->qlen);
+ }
+ if (dpy->flags & XlibDisplayIOError) return(dpy->qlen);
+ if (BytesReadable(dpy->fd, (char *) &pend) < 0)
+ _XIOError(dpy);
+#ifdef XCONN_CHECK_FREQ
+ /* This is a crock, required because FIONREAD or equivalent is
+ * not guaranteed to detect a broken connection.
+ */
+ if (!pend && !dpy->qlen && ++dpy->conn_checker >= XCONN_CHECK_FREQ)
+ {
+ unsigned long r_mask[MSKCNT];
+ static struct timeval zero_time;
+
+ dpy->conn_checker = 0;
+ CLEARBITS(r_mask);
+ BITSET(r_mask, dpy->fd);
+ if (pend = select(dpy->fd + 1, (int *)r_mask, NULL, NULL,
+ &zero_time))
+ {
+ if (pend > 0)
+ {
+ if (BytesReadable(dpy->fd, (char *) &pend) < 0)
+ _XIOError(dpy);
+ /* we should not get zero, if we do, force a read */
+ if (!pend)
+ pend = SIZEOF(xReply);
+ }
+ else if (pend < 0 && errno != EINTR)
+ _XIOError(dpy);
+ }
+ }
+#endif /* XCONN_CHECK_FREQ */
+ if (!(len = pend))
+ return(dpy->qlen); /* _XFlush can enqueue events */
+ /* Force a read if there is not enough data. Otherwise,
+ * a select() loop at a higher-level will spin undesirably,
+ * and we've seen at least one OS that appears to not update
+ * the result from FIONREAD once it has returned nonzero.
+ */
+ if (len < SIZEOF(xReply))
+ len = SIZEOF(xReply);
+ else if (len > BUFSIZE)
+ len = BUFSIZE;
+ len /= SIZEOF(xReply);
+ pend = len * SIZEOF(xReply);
+#ifdef XCONN_CHECK_FREQ
+ dpy->conn_checker = 0;
+#endif
+ _XRead (dpy, buf, (long) pend);
+
+ /* no space between comma and type or else macro will die */
+ STARTITERATE (rep,xReply, buf, (len > 0), len--) {
+ if (rep->generic.type == X_Error)
+ _XError(dpy, (xError *)rep);
+ else /* must be an event packet */
+ _XEnq(dpy, (xEvent *) rep);
+ }
+ ENDITERATE
+ return(dpy->qlen);
+}
+
+/* _XReadEvents - Flush the output queue,
+ * then read as many events as possible (but at least 1) and enqueue them
+ */
+void _XReadEvents(Display *dpy)
+{
+ char buf[BUFSIZE];
+ long pend_not_register; /* because can't "&" a register variable */
+ register long pend;
+ register xEvent *ev;
+ Bool not_yet_flushed = True;
+
+ do {
+ /* find out how much data can be read */
+ if (BytesReadable(dpy->fd, (char *) &pend_not_register) < 0)
+ _XIOError(dpy);
+ pend = pend_not_register;
+
+ /* must read at least one xEvent; if none is pending, then
+ we'll just flush and block waiting for it */
+ if (pend < SIZEOF(xEvent)) {
+ pend = SIZEOF(xEvent);
+ /* don't flush until we block the first time */
+ if (not_yet_flushed) {
+ int qlen = dpy->qlen;
+ _XFlush (dpy);
+ if (qlen != dpy->qlen) return;
+ not_yet_flushed = False;
+ }
+ }
+
+ /* but we won't read more than the max buffer size */
+ if (pend > BUFSIZE)
+ pend = BUFSIZE;
+
+ /* round down to an integral number of XReps */
+ pend = (pend / SIZEOF(xEvent)) * SIZEOF(xEvent);
+
+ _XRead (dpy, buf, pend);
+
+ /* no space between comma and type or else macro will die */
+ STARTITERATE (ev,xEvent, buf, (pend > 0),
+ pend -= SIZEOF(xEvent)) {
+ if (ev->u.u.type == X_Error)
+ _XError (dpy, (xError *) ev);
+ else /* it's an event packet; enqueue it */
+ _XEnq (dpy, ev);
+ }
+ ENDITERATE
+ } while (dpy->head == NULL);
+}
+
+#endif /* NEEDFORNX */
+
+/*
+ * N_XRead - Read bytes from the socket taking into account incomplete
+ * reads. This routine may have to be reworked if int < long.
+ */
+int N_XRead (Display *dpy, char *data, long size)
+{
+ register long bytes_read;
+
+ if (!dpy) return 0;
+ if ((dpy->flags & XlibDisplayIOError) || size == 0) return 0;
+ errno = 0;
+ while ((bytes_read = ReadFromServer(dpy->fd, data, (int)size))
+ != size) {
+
+ if (bytes_read > 0) {
+ size -= bytes_read;
+ data += bytes_read;
+ }
+ else if (ETEST(errno)) {
+ N_XWaitForReadable(dpy);
+ errno = 0;
+ }
+#ifdef SUNSYSV
+ else if (errno == 0) {
+ N_XWaitForReadable(dpy);
+ }
+#endif
+ else if (bytes_read == 0) {
+ /* Read failed because of end of file! */
+ errno = EPIPE;
+ _XIOError(dpy);
+ }
+
+ else /* bytes_read is less than 0; presumably -1 */ {
+ /* If it's a system call interrupt, it's not an error. */
+ if (errno != EINTR)
+ _XIOError(dpy);
+ }
+ }
+ return 0;
+}
+
+#ifdef WORD64
+
+/*
+ * XXX This is a *really* stupid way of doing this....
+ * PACKBUFFERSIZE must be a multiple of 4.
+ */
+
+#define PACKBUFFERSIZE 4096
+
+
+/*
+ * _XRead32 - Read bytes from the socket unpacking each 32 bits
+ * into a long (64 bits on a CRAY computer).
+ *
+ */
+static void _doXRead32 (Display *dpy, long *data, long size, char *packbuffer)
+{
+ long *lpack,*lp;
+ long mask32 = 0x00000000ffffffff;
+ long maskw, nwords, i, bits;
+
+ _XReadPad (dpy, packbuffer, size);
+
+ lp = data;
+ lpack = (long *) packbuffer;
+ nwords = size >> 2;
+ bits = 32;
+
+ for(i=0;i<nwords;i++){
+ maskw = mask32 << bits;
+ *lp++ = ( *lpack & maskw ) >> bits;
+ bits = bits ^32;
+ if(bits){
+ lpack++;
+ }
+ }
+}
+
+void _XRead32 (Display *dpy, long *data, long len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 2;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ _doXRead32 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) _doXRead32 (dpy, data, len, packbuffer);
+}
+
+
+
+/*
+ * _XRead16 - Read bytes from the socket unpacking each 16 bits
+ * into a long (64 bits on a CRAY computer).
+ *
+ */
+static void _doXRead16 (Display *dpy, short *data, long size, char *packbuffer)
+{
+ long *lpack,*lp;
+ long mask16 = 0x000000000000ffff;
+ long maskw, nwords, i, bits;
+
+ _XRead(dpy,packbuffer,size); /* don't do a padded read... */
+
+ lp = (long *) data;
+ lpack = (long *) packbuffer;
+ nwords = size >> 1; /* number of 16 bit words to be unpacked */
+ bits = 48;
+ for(i=0;i<nwords;i++){
+ maskw = mask16 << bits;
+ *lp++ = ( *lpack & maskw ) >> bits;
+ bits -= 16;
+ if(bits < 0){
+ lpack++;
+ bits = 48;
+ }
+ }
+}
+
+void _XRead16 (Display *dpy, short *data, long len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 1;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ _doXRead16 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) _doXRead16 (dpy, data, len, packbuffer);
+}
+
+void _XRead16Pad (Display *dpy, short *data, long size)
+{
+ int slop = (size & 3);
+ short slopbuf[3];
+
+ _XRead16 (dpy, data, size);
+ if (slop > 0) {
+ _XRead16 (dpy, slopbuf, 4 - slop);
+ }
+}
+#endif /* WORD64 */
+
+
+/*
+ * N_XReadPad - Read bytes from the socket taking into account incomplete
+ * reads. If the number of bytes is not 0 mod 32, read additional pad
+ * bytes. This routine may have to be reworked if int < long.
+ */
+void N_XReadPad (Display *dpy, char *data, long size)
+{
+ register long bytes_read;
+ struct iovec iov[2];
+ char pad[3];
+
+ if (!dpy) return;
+ if ((dpy->flags & XlibDisplayIOError) || size == 0) return;
+ iov[0].iov_len = (int)size;
+ iov[0].iov_base = data;
+ /*
+ * The following hack is used to provide 32 bit long-word
+ * aligned padding. The [1] vector is of length 0, 1, 2, or 3,
+ * whatever is needed.
+ */
+
+ iov[1].iov_len = padlength[size & 3];
+ iov[1].iov_base = pad;
+ size += iov[1].iov_len;
+ errno = 0;
+ while ((bytes_read = ReadvFromServer (dpy->fd, iov, 2)) != size) {
+
+ if (bytes_read > 0) {
+ size -= bytes_read;
+ if (iov[0].iov_len < bytes_read) {
+ iov[1].iov_len += iov[0].iov_len - bytes_read;
+ iov[1].iov_base =
+ (char *)iov[1].iov_base + bytes_read - iov[0].iov_len;
+ iov[0].iov_len = 0;
+ }
+ else {
+ iov[0].iov_len -= bytes_read;
+ iov[0].iov_base = (char *)iov[0].iov_base + bytes_read;
+ }
+ }
+ else if (ETEST(errno)) {
+ N_XWaitForReadable(dpy);
+ errno = 0;
+ }
+#ifdef SUNSYSV
+ else if (errno == 0) {
+ N_XWaitForReadable(dpy);
+ }
+#endif
+ else if (bytes_read == 0) {
+ /* Read failed because of end of file! */
+ errno = EPIPE;
+ _XIOError(dpy);
+ }
+
+ else /* bytes_read is less than 0; presumably -1 */ {
+ /* If it's a system call interrupt, it's not an error. */
+ if (errno != EINTR)
+ _XIOError(dpy);
+ }
+ }
+}
+
+/*
+ * N_XSend - Flush the buffer and send the client data. 32 bit word aligned
+ * transmission is used, if size is not 0 mod 4, extra bytes are transmitted.
+ * This routine may have to be reworked if int < long;
+ */
+void N_XSend (Display *dpy, _Xconst char *data, long size)
+{
+ struct iovec iov[3];
+ static char pad[3] = {0, 0, 0};
+ /* XText8 and XText16 require that the padding bytes be zero! */
+
+ long skip = 0;
+ long dpybufsize = (dpy->bufptr - dpy->buffer);
+ long padsize = padlength[size & 3];
+ long total = dpybufsize + size + padsize;
+ long todo = total;
+
+ if (dpy->flags & XlibDisplayIOError) return;
+
+ /*
+ * There are 3 pieces that may need to be written out:
+ *
+ * o whatever is in the display buffer
+ * o the data passed in by the user
+ * o any padding needed to 32bit align the whole mess
+ *
+ * This loop looks at all 3 pieces each time through. It uses skip
+ * to figure out whether or not a given piece is needed.
+ */
+ while (total) {
+ long before = skip; /* amount of whole thing written */
+ long remain = todo; /* amount to try this time, <= total */
+ int i = 0;
+ long len;
+
+ /* You could be very general here and have "in" and "out" iovecs
+ * and write a loop without using a macro, but what the heck. This
+ * translates to:
+ *
+ * how much of this piece is new?
+ * if more new then we are trying this time, clamp
+ * if nothing new
+ * then bump down amount already written, for next piece
+ * else put new stuff in iovec, will need all of next piece
+ *
+ * Note that todo had better be at least 1 or else we'll end up
+ * writing 0 iovecs.
+ */
+#define InsertIOV(pointer, length) \
+ len = (length) - before; \
+ if (len > remain) \
+ len = remain; \
+ if (len <= 0) { \
+ before = (-len); \
+ } else { \
+ iov[i].iov_len = len; \
+ iov[i].iov_base = (pointer) + before; \
+ i++; \
+ remain -= len; \
+ before = 0; \
+ }
+
+ InsertIOV (dpy->buffer, dpybufsize)
+ InsertIOV ((char *)data, size)
+ InsertIOV (pad, padsize)
+
+ errno = 0;
+ if ((len = WritevToServer(dpy->fd, iov, i)) >= 0) {
+ skip += len;
+ total -= len;
+ todo = total;
+ } else if (ETEST(errno)) {
+ N_XWaitForWritable(dpy);
+#ifdef SUNSYSV
+ } else if (errno == 0) {
+ N_XWaitForWritable(dpy);
+#endif
+#ifdef EMSGSIZE
+ } else if (errno == EMSGSIZE) {
+ if (todo > 1)
+ todo >>= 1;
+ else
+ N_XWaitForWritable(dpy);
+#endif
+ } else if (errno != EINTR) {
+ _XIOError(dpy);
+ }
+ }
+
+ dpy->bufptr = dpy->buffer;
+ dpy->last_req = (char *) & _dummy_request;
+ return;
+}
+
+#ifdef NEEDFORNX
+/*
+ * _XAllocID - normal resource ID allocation routine. A client
+ * can roll his own and instatantiate it if he wants, but must
+ * follow the rules.
+ */
+XID _XAllocID(Display *dpy)
+{
+ XID id;
+
+ id = dpy->resource_id << dpy->resource_shift;
+ if (id <= dpy->resource_mask) {
+ dpy->resource_id++;
+ return (dpy->resource_base + id);
+ }
+ if (id != 0x10000000) {
+ (void) fprintf(stderr,
+ "Xlib: resource ID allocation space exhausted!\n");
+ id = 0x10000000;
+ dpy->resource_id = id >> dpy->resource_shift;
+ }
+ return id;
+}
+
+/*
+ * The hard part about this is that we only get 16 bits from a reply. Well,
+ * then, we have three values that will march along, with the following
+ * invariant:
+ * dpy->last_request_read <= rep->sequenceNumber <= dpy->request
+ * The right choice for rep->sequenceNumber is the largest that
+ * still meets these constraints.
+ */
+
+unsigned long
+_XSetLastRequestRead(Display *dpy, xGenericReply *rep)
+{
+ register unsigned long newseq, lastseq;
+
+ /*
+ * KeymapNotify has no sequence number, but is always guaranteed
+ * to immediately follow another event, except when generated via
+ * SendEvent (hmmm).
+ */
+ if ((rep->type & 0x7f) == KeymapNotify)
+ return(dpy->last_request_read);
+
+ newseq = (dpy->last_request_read & ~((unsigned long)0xffff)) |
+ rep->sequenceNumber;
+ lastseq = dpy->last_request_read;
+ while (newseq < lastseq) {
+ newseq += 0x10000;
+ if (newseq > dpy->request) {
+ (void) fprintf (stderr,
+ "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
+ newseq, dpy->request,
+ (unsigned int) rep->type);
+ newseq -= 0x10000;
+ break;
+ }
+ }
+
+ dpy->last_request_read = newseq;
+ return(newseq);
+}
+
+#endif /* NEEDFORNX */
+
+/*
+ * N_XReply - Wait for a reply packet and copy its contents into the
+ * specified rep. Mean while we must handle error and event packets that
+ * we may encounter.
+ */
+Status N_XReply (
+ Display *dpy,
+ xReply *rep,
+ int extra, /* number of 32-bit words expected after the reply */
+ Bool discard) /* should I discard data following "extra" words? */
+{
+ /* Pull out the serial number now, so that (currently illegal) requests
+ * generated by an error handler don't confuse us.
+ */
+ unsigned long cur_request = dpy->request;
+
+ if (dpy->flags & XlibDisplayIOError) return (0);
+
+ N_XFlush(dpy);
+ while (1) {
+ N_XRead(dpy, (char *)rep, (long)SIZEOF(xReply));
+ switch ((int)rep->generic.type) {
+
+ case X_Reply:
+ /* Reply received. Fast update for synchronous replies,
+ * but deal with multiple outstanding replies.
+ */
+ if (rep->generic.sequenceNumber == (cur_request & 0xffff))
+ dpy->last_request_read = cur_request;
+ else
+ (void) _XSetLastRequestRead(dpy, &rep->generic);
+ if (extra == 0) {
+ if (discard && (rep->generic.length > 0))
+ /* unexpectedly long reply! */
+ _EatData32 (dpy, rep->generic.length);
+ return (1);
+ }
+ if ((unsigned) extra == rep->generic.length) {
+ /*
+ * Read the extra data into storage immediately following
+ * the GenericReply structure.
+ */
+ N_XRead (dpy, (char *) (NEXTPTR(rep,xReply)),
+ ((long)extra) << 2);
+ return (1);
+ }
+ if ((unsigned) extra < rep->generic.length) {
+ /* Actual reply is longer than "extra" */
+ N_XRead (dpy, (char *) (NEXTPTR(rep,xReply)),
+ ((long)extra) << 2);
+ if (discard)
+ _EatData32 (dpy, rep->generic.length - extra);
+ return (1);
+ }
+ /*
+ *if we get here, then extra > rep->generic.length--meaning we
+ * read a reply that's shorter than we expected. This is an
+ * error, but we still need to figure out how to handle it...
+ */
+ N_XRead (dpy, (char *) (NEXTPTR(rep,xReply)),
+ ((long) rep->generic.length) << 2);
+ _XIOError (dpy);
+ return (0);
+
+ case X_Error:
+ {
+ register _XExtension *ext;
+ register Bool ret = False;
+ int ret_code;
+ xError *err = (xError *) rep;
+ unsigned long serial;
+
+ serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep);
+ /*
+ * we better see if there is an extension who may
+ * want to suppress the error.
+ */
+ for (ext = dpy->ext_procs; !ret && ext; ext = ext->next) {
+ if (ext->error)
+ ret = (*ext->error)(dpy, err, &ext->codes, &ret_code);
+ }
+ if (!ret) {
+ _XError(dpy, err);
+ ret_code = 0;
+ }
+ if (serial == cur_request)
+ return(ret_code);
+ }
+ break;
+ default:
+ /* There should never be any events on this connection! */
+ DPSFatalProc(NULL, "N_XReply read bogus X event");
+ break;
+ }
+ }
+}
+
+
+/* Read and discard "n" 8-bit bytes of data */
+
+static void
+N_XEatData (Display *dpy, unsigned long n)
+{
+#define SCRATCHSIZE 2048
+ char buf[SCRATCHSIZE];
+
+ while (n > 0) {
+ register long bytes_read = (n > SCRATCHSIZE) ? SCRATCHSIZE : n;
+ N_XRead (dpy, buf, bytes_read);
+ n -= bytes_read;
+ }
+#undef SCRATCHSIZE
+}
+
+
+/* Read and discard "n" 32-bit words. */
+
+static void _EatData32 (Display *dpy, unsigned long n)
+{
+ N_XEatData (dpy, n << 2);
+}
+
+
+#ifdef NEEDFORNX
+/*
+ * _XEnq - Place event packets on the display's queue.
+ * note that no squishing of move events in V11, since there
+ * is pointer motion hints....
+ */
+void _XEnq (Display *dpy, xEvent *event)
+{
+ register _XQEvent *qelt;
+
+/*NOSTRICT*/
+ if (qelt = _qfree) {
+ /* If _qfree is non-NULL do this, else malloc a new one. */
+ _qfree = qelt->next;
+ }
+ else if ((qelt =
+ (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) {
+ /* Malloc call failed! */
+ errno = ENOMEM;
+ _XIOError(dpy);
+ }
+ qelt->next = NULL;
+ /* go call through display to find proper event reformatter */
+ if ((*dpy->event_vec[event->u.u.type & 0177])(dpy, &qelt->event, event)) {
+ if (dpy->tail) dpy->tail->next = qelt;
+ else dpy->head = qelt;
+
+ dpy->tail = qelt;
+ dpy->qlen++;
+ } else {
+ /* ignored, or stashed away for many-to-one compression */
+ qelt->next = _qfree;
+ _qfree = qelt;
+ }
+}
+/*
+ * EventToWire in separate file in that often not needed.
+ */
+#endif /* NEEDFORNX */
+
+/*ARGSUSED*/
+Bool
+N_XUnknownWireEvent(
+ Display *dpy, /* pointer to display structure */
+ XEvent *re, /* pointer to where event should be reformatted */
+ xEvent *event) /* wire protocol event */
+{
+ char mbuf[256];
+
+ sprintf(mbuf, "NX: unhandled wire event %d, agent = %lx", re->type, (long)dpy);
+ DPSWarnProc(NULL, mbuf);
+ return(False);
+}
+
+/*ARGSUSED*/
+Status
+N_XUnknownNativeEvent(
+ Display *dpy, /* pointer to display structure */
+ XEvent *re, /* pointer to where event should be reformatted */
+ xEvent *event) /* wire protocol event */
+{
+ char mbuf[256];
+
+ sprintf(mbuf, "NX: unhandled native event %d, agent = %lx", re->type, (long)dpy);
+ DPSWarnProc(NULL, mbuf);
+ return(0);
+}
+
+#ifdef NEEDFORNX
+/*
+ * reformat a wire event into an XEvent structure of the right type.
+ */
+Bool
+_XWireToEvent(
+ Display *dpy, /* pointer to display structure */
+ XEvent *re, /* pointer to where event should be reformatted */
+ xEvent *event) /* wire protocol event */
+{
+
+ re->type = event->u.u.type & 0x7f;
+ ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy,
+ (xGenericReply *)event);
+ ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0);
+ ((XAnyEvent *)re)->display = dpy;
+
+ /* Ignore the leading bit of the event type since it is set when a
+ client sends an event rather than the server. */
+
+ switch (event-> u.u.type & 0177) {
+ case KeyPress:
+ case KeyRelease:
+ {
+ register XKeyEvent *ev = (XKeyEvent*) re;
+ ev->root = event->u.keyButtonPointer.root;
+ ev->window = event->u.keyButtonPointer.event;
+ ev->subwindow = event->u.keyButtonPointer.child;
+ ev->time = event->u.keyButtonPointer.time;
+ ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
+ ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
+ ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
+ ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
+ ev->state = event->u.keyButtonPointer.state;
+ ev->same_screen = event->u.keyButtonPointer.sameScreen;
+ ev->keycode = event->u.u.detail;
+ }
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ {
+ register XButtonEvent *ev = (XButtonEvent *) re;
+ ev->root = event->u.keyButtonPointer.root;
+ ev->window = event->u.keyButtonPointer.event;
+ ev->subwindow = event->u.keyButtonPointer.child;
+ ev->time = event->u.keyButtonPointer.time;
+ ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
+ ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
+ ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
+ ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
+ ev->state = event->u.keyButtonPointer.state;
+ ev->same_screen = event->u.keyButtonPointer.sameScreen;
+ ev->button = event->u.u.detail;
+ }
+ break;
+ case MotionNotify:
+ {
+ register XMotionEvent *ev = (XMotionEvent *)re;
+ ev->root = event->u.keyButtonPointer.root;
+ ev->window = event->u.keyButtonPointer.event;
+ ev->subwindow = event->u.keyButtonPointer.child;
+ ev->time = event->u.keyButtonPointer.time;
+ ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
+ ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
+ ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
+ ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
+ ev->state = event->u.keyButtonPointer.state;
+ ev->same_screen = event->u.keyButtonPointer.sameScreen;
+ ev->is_hint = event->u.u.detail;
+ }
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ {
+ register XCrossingEvent *ev = (XCrossingEvent *) re;
+ ev->root = event->u.enterLeave.root;
+ ev->window = event->u.enterLeave.event;
+ ev->subwindow = event->u.enterLeave.child;
+ ev->time = event->u.enterLeave.time;
+ ev->x = cvtINT16toInt(event->u.enterLeave.eventX);
+ ev->y = cvtINT16toInt(event->u.enterLeave.eventY);
+ ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX);
+ ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY);
+ ev->state = event->u.enterLeave.state;
+ ev->mode = event->u.enterLeave.mode;
+ ev->same_screen = (event->u.enterLeave.flags &
+ ELFlagSameScreen) && True;
+ ev->focus = (event->u.enterLeave.flags &
+ ELFlagFocus) && True;
+ ev->detail = event->u.u.detail;
+ }
+ break;
+ case FocusIn:
+ case FocusOut:
+ {
+ register XFocusChangeEvent *ev = (XFocusChangeEvent *) re;
+ ev->window = event->u.focus.window;
+ ev->mode = event->u.focus.mode;
+ ev->detail = event->u.u.detail;
+ }
+ break;
+ case KeymapNotify:
+ {
+ register XKeymapEvent *ev = (XKeymapEvent *) re;
+ ev->window = dpy->current;
+ bcopy ((char *)((xKeymapEvent *) event)->map,
+ &ev->key_vector[1],
+ sizeof (((xKeymapEvent *) event)->map));
+ }
+ break;
+ case Expose:
+ {
+ register XExposeEvent *ev = (XExposeEvent *) re;
+ ev->window = event->u.expose.window;
+ ev->x = event->u.expose.x;
+ ev->y = event->u.expose.y;
+ ev->width = event->u.expose.width;
+ ev->height = event->u.expose.height;
+ ev->count = event->u.expose.count;
+ }
+ break;
+ case GraphicsExpose:
+ {
+ register XGraphicsExposeEvent *ev =
+ (XGraphicsExposeEvent *) re;
+ ev->drawable = event->u.graphicsExposure.drawable;
+ ev->x = event->u.graphicsExposure.x;
+ ev->y = event->u.graphicsExposure.y;
+ ev->width = event->u.graphicsExposure.width;
+ ev->height = event->u.graphicsExposure.height;
+ ev->count = event->u.graphicsExposure.count;
+ ev->major_code = event->u.graphicsExposure.majorEvent;
+ ev->minor_code = event->u.graphicsExposure.minorEvent;
+ }
+ break;
+ case NoExpose:
+ {
+ register XNoExposeEvent *ev = (XNoExposeEvent *) re;
+ ev->drawable = event->u.noExposure.drawable;
+ ev->major_code = event->u.noExposure.majorEvent;
+ ev->minor_code = event->u.noExposure.minorEvent;
+ }
+ break;
+ case VisibilityNotify:
+ {
+ register XVisibilityEvent *ev = (XVisibilityEvent *) re;
+ ev->window = event->u.visibility.window;
+ ev->state = event->u.visibility.state;
+ }
+ break;
+ case CreateNotify:
+ {
+ register XCreateWindowEvent *ev =
+ (XCreateWindowEvent *) re;
+ ev->window = event->u.createNotify.window;
+ ev->parent = event->u.createNotify.parent;
+ ev->x = cvtINT16toInt(event->u.createNotify.x);
+ ev->y = cvtINT16toInt(event->u.createNotify.y);
+ ev->width = event->u.createNotify.width;
+ ev->height = event->u.createNotify.height;
+ ev->border_width = event->u.createNotify.borderWidth;
+ ev->override_redirect = event->u.createNotify.override;
+ }
+ break;
+ case DestroyNotify:
+ {
+ register XDestroyWindowEvent *ev =
+ (XDestroyWindowEvent *) re;
+ ev->window = event->u.destroyNotify.window;
+ ev->event = event->u.destroyNotify.event;
+ }
+ break;
+ case UnmapNotify:
+ {
+ register XUnmapEvent *ev = (XUnmapEvent *) re;
+ ev->window = event->u.unmapNotify.window;
+ ev->event = event->u.unmapNotify.event;
+ ev->from_configure = event->u.unmapNotify.fromConfigure;
+ }
+ break;
+ case MapNotify:
+ {
+ register XMapEvent *ev = (XMapEvent *) re;
+ ev->window = event->u.mapNotify.window;
+ ev->event = event->u.mapNotify.event;
+ ev->override_redirect = event->u.mapNotify.override;
+ }
+ break;
+ case MapRequest:
+ {
+ register XMapRequestEvent *ev = (XMapRequestEvent *) re;
+ ev->window = event->u.mapRequest.window;
+ ev->parent = event->u.mapRequest.parent;
+ }
+ break;
+ case ReparentNotify:
+ {
+ register XReparentEvent *ev = (XReparentEvent *) re;
+ ev->event = event->u.reparent.event;
+ ev->window = event->u.reparent.window;
+ ev->parent = event->u.reparent.parent;
+ ev->x = cvtINT16toInt(event->u.reparent.x);
+ ev->y = cvtINT16toInt(event->u.reparent.y);
+ ev->override_redirect = event->u.reparent.override;
+ }
+ break;
+ case ConfigureNotify:
+ {
+ register XConfigureEvent *ev = (XConfigureEvent *) re;
+ ev->event = event->u.configureNotify.event;
+ ev->window = event->u.configureNotify.window;
+ ev->above = event->u.configureNotify.aboveSibling;
+ ev->x = cvtINT16toInt(event->u.configureNotify.x);
+ ev->y = cvtINT16toInt(event->u.configureNotify.y);
+ ev->width = event->u.configureNotify.width;
+ ev->height = event->u.configureNotify.height;
+ ev->border_width = event->u.configureNotify.borderWidth;
+ ev->override_redirect = event->u.configureNotify.override;
+ }
+ break;
+ case ConfigureRequest:
+ {
+ register XConfigureRequestEvent *ev =
+ (XConfigureRequestEvent *) re;
+ ev->window = event->u.configureRequest.window;
+ ev->parent = event->u.configureRequest.parent;
+ ev->above = event->u.configureRequest.sibling;
+ ev->x = cvtINT16toInt(event->u.configureRequest.x);
+ ev->y = cvtINT16toInt(event->u.configureRequest.y);
+ ev->width = event->u.configureRequest.width;
+ ev->height = event->u.configureRequest.height;
+ ev->border_width = event->u.configureRequest.borderWidth;
+ ev->value_mask = event->u.configureRequest.valueMask;
+ ev->detail = event->u.u.detail;
+ }
+ break;
+ case GravityNotify:
+ {
+ register XGravityEvent *ev = (XGravityEvent *) re;
+ ev->window = event->u.gravity.window;
+ ev->event = event->u.gravity.event;
+ ev->x = cvtINT16toInt(event->u.gravity.x);
+ ev->y = cvtINT16toInt(event->u.gravity.y);
+ }
+ break;
+ case ResizeRequest:
+ {
+ register XResizeRequestEvent *ev =
+ (XResizeRequestEvent *) re;
+ ev->window = event->u.resizeRequest.window;
+ ev->width = event->u.resizeRequest.width;
+ ev->height = event->u.resizeRequest.height;
+ }
+ break;
+ case CirculateNotify:
+ {
+ register XCirculateEvent *ev = (XCirculateEvent *) re;
+ ev->window = event->u.circulate.window;
+ ev->event = event->u.circulate.event;
+ ev->place = event->u.circulate.place;
+ }
+ break;
+ case CirculateRequest:
+ {
+ register XCirculateRequestEvent *ev =
+ (XCirculateRequestEvent *) re;
+ ev->window = event->u.circulate.window;
+ ev->parent = event->u.circulate.event;
+ ev->place = event->u.circulate.place;
+ }
+ break;
+ case PropertyNotify:
+ {
+ register XPropertyEvent *ev = (XPropertyEvent *) re;
+ ev->window = event->u.property.window;
+ ev->atom = event->u.property.atom;
+ ev->time = event->u.property.time;
+ ev->state = event->u.property.state;
+ }
+ break;
+ case SelectionClear:
+ {
+ register XSelectionClearEvent *ev =
+ (XSelectionClearEvent *) re;
+ ev->window = event->u.selectionClear.window;
+ ev->selection = event->u.selectionClear.atom;
+ ev->time = event->u.selectionClear.time;
+ }
+ break;
+ case SelectionRequest:
+ {
+ register XSelectionRequestEvent *ev =
+ (XSelectionRequestEvent *) re;
+ ev->owner = event->u.selectionRequest.owner;
+ ev->requestor = event->u.selectionRequest.requestor;
+ ev->selection = event->u.selectionRequest.selection;
+ ev->target = event->u.selectionRequest.target;
+ ev->property = event->u.selectionRequest.property;
+ ev->time = event->u.selectionRequest.time;
+ }
+ break;
+ case SelectionNotify:
+ {
+ register XSelectionEvent *ev = (XSelectionEvent *) re;
+ ev->requestor = event->u.selectionNotify.requestor;
+ ev->selection = event->u.selectionNotify.selection;
+ ev->target = event->u.selectionNotify.target;
+ ev->property = event->u.selectionNotify.property;
+ ev->time = event->u.selectionNotify.time;
+ }
+ break;
+ case ColormapNotify:
+ {
+ register XColormapEvent *ev = (XColormapEvent *) re;
+ ev->window = event->u.colormap.window;
+ ev->colormap = event->u.colormap.colormap;
+ ev->new = event->u.colormap.new;
+ ev->state = event->u.colormap.state;
+ }
+ break;
+ case ClientMessage:
+ {
+ register int i;
+ register XClientMessageEvent *ev
+ = (XClientMessageEvent *) re;
+ ev->window = event->u.clientMessage.window;
+ ev->format = event->u.u.detail;
+ switch (ev->format) {
+ case 8:
+ ev->message_type = event->u.clientMessage.u.b.type;
+ for (i = 0; i < 20; i++)
+ ev->data.b[i] = event->u.clientMessage.u.b.bytes[i];
+ break;
+ case 16:
+ ev->message_type = event->u.clientMessage.u.s.type;
+ ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0);
+ ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1);
+ ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2);
+ ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3);
+ ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4);
+ ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5);
+ ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6);
+ ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7);
+ ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8);
+ ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9);
+ break;
+ case 32:
+ ev->message_type = event->u.clientMessage.u.l.type;
+ ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0);
+ ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1);
+ ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2);
+ ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3);
+ ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4);
+ break;
+ default: /* XXX should never occur */
+ break;
+ }
+ }
+ break;
+ case MappingNotify:
+ {
+ register XMappingEvent *ev = (XMappingEvent *)re;
+ ev->window = 0;
+ ev->first_keycode = event->u.mappingNotify.firstKeyCode;
+ ev->request = event->u.mappingNotify.request;
+ ev->count = event->u.mappingNotify.count;
+ }
+ break;
+ default:
+ return(_XUnknownWireEvent(dpy, re, event));
+ }
+ return(True);
+}
+
+
+#ifndef USL_SHARELIB
+
+static char *_SysErrorMsg (int n)
+{
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+ char *s = ((n >= 0 && n < sys_nerr) ? sys_errlist[n] : "unknown error");
+
+ return (s ? s : "no such error");
+}
+
+#endif /* USL sharedlibs in don't define for SVR3.2 */
+
+
+/*
+ * _XDefaultIOError - Default fatal system error reporting routine. Called
+ * when an X internal system error is encountered.
+ */
+_XDefaultIOError (Display *dpy)
+{
+ (void) fprintf (stderr,
+ "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n",
+ errno, _SysErrorMsg (errno), DisplayString (dpy));
+ (void) fprintf (stderr,
+ " after %lu requests (%lu known processed) with %d events remaining.\r\n",
+ NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy),
+ QLength(dpy));
+
+ if (errno == EPIPE) {
+ (void) fprintf (stderr,
+ " The connection was probably broken by a server shutdown or KillClient.\r\n");
+ }
+ exit(1);
+}
+
+
+static int _XPrintDefaultError (Display *dpy, XErrorEvent *event, FILE *fp)
+{
+ char buffer[BUFSIZ];
+ char mesg[BUFSIZ];
+ char number[32];
+ char *mtype = "XlibMessage";
+ register _XExtension *ext = (_XExtension *)NULL;
+ _XExtension *bext = (_XExtension *)NULL;
+ XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
+ XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
+ (void) fprintf(fp, "%s: %s\n ", mesg, buffer);
+ XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
+ mesg, BUFSIZ);
+ (void) fprintf(fp, mesg, event->request_code);
+ if (event->request_code < 128) {
+ sprintf(number, "%d", event->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
+ } else {
+ for (ext = dpy->ext_procs;
+ ext && (ext->codes.major_opcode != event->request_code);
+ ext = ext->next)
+ ;
+ if (ext)
+ strcpy(buffer, ext->name);
+ else
+ buffer[0] = '\0';
+ }
+ (void) fprintf(fp, " (%s)\n", buffer);
+ if (event->request_code >= 128) {
+ XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->minor_code);
+ if (ext) {
+ sprintf(mesg, "%s.%d", ext->name, event->minor_code);
+ XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
+ (void) fprintf(fp, " (%s)", buffer);
+ }
+ fputs("\n", fp);
+ }
+ if (event->error_code >= 128) {
+ /* kludge, try to find the extension that caused it */
+ buffer[0] = '\0';
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_string)
+ (*ext->error_string)(dpy, event->error_code, &ext->codes,
+ buffer, BUFSIZ);
+ if (buffer[0]) {
+ bext = ext;
+ break;
+ }
+ if (ext->codes.first_error &&
+ ext->codes.first_error < event->error_code &&
+ (!bext || ext->codes.first_error > bext->codes.first_error))
+ bext = ext;
+ }
+ if (bext)
+ sprintf(buffer, "%s.%d", bext->name,
+ event->error_code - bext->codes.first_error);
+ else
+ strcpy(buffer, "Value");
+ XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
+ if (mesg[0]) {
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->resourceid);
+ fputs("\n", fp);
+ }
+ /* let extensions try to print the values */
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_values)
+ (*ext->error_values)(dpy, event, fp);
+ }
+ } else if ((event->error_code == BadWindow) ||
+ (event->error_code == BadPixmap) ||
+ (event->error_code == BadCursor) ||
+ (event->error_code == BadFont) ||
+ (event->error_code == BadDrawable) ||
+ (event->error_code == BadColor) ||
+ (event->error_code == BadGC) ||
+ (event->error_code == BadIDChoice) ||
+ (event->error_code == BadValue) ||
+ (event->error_code == BadAtom)) {
+ if (event->error_code == BadValue)
+ XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
+ mesg, BUFSIZ);
+ else if (event->error_code == BadAtom)
+ XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
+ mesg, BUFSIZ);
+ else
+ XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->resourceid);
+ fputs("\n", fp);
+ }
+ XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->serial);
+ XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
+ mesg, BUFSIZ);
+ fputs("\n ", fp);
+ (void) fprintf(fp, mesg, dpy->request);
+ fputs("\n", fp);
+ if (event->error_code == BadImplementation) return 0;
+ return 1;
+}
+
+int _XDefaultError(Display *dpy, XErrorEvent *event)
+{
+ if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0;
+ exit(1);
+ /*NOTREACHED*/
+}
+
+/*ARGSUSED*/
+Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we)
+{
+ return True;
+}
+
+/*
+ * _XError - prepare to upcall user protocol error handler
+ */
+int _XError (Display *dpy, xError *rep)
+{
+ /*
+ * X_Error packet encountered! We need to unpack the error before
+ * giving it to the user.
+ */
+ XEvent event; /* make it a large event */
+
+ event.xerror.display = dpy;
+ event.xerror.type = X_Error;
+ event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep);
+ event.xerror.resourceid = rep->resourceID;
+ event.xerror.error_code = rep->errorCode;
+ event.xerror.request_code = rep->majorCode;
+ event.xerror.minor_code = rep->minorCode;
+ if (dpy->error_vec &&
+ !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep))
+ return 0;
+ if (_XErrorFunction != NULL) {
+ return ((*_XErrorFunction)(dpy, &event)); /* upcall */
+ } else {
+ return _XDefaultError(dpy, &event);
+ }
+}
+
+/*
+ * _XIOError - call user connection error handler and exit
+ */
+int _XIOError (Display *dpy)
+{
+ dpy->flags |= XlibDisplayIOError;
+ if (_XIOErrorFunction != NULL)
+ (*_XIOErrorFunction)(dpy);
+ else
+ _XDefaultIOError(dpy);
+ exit (1);
+}
+
+
+/*
+ * This routine can be used to (cheaply) get some memory within a single
+ * Xlib routine for scratch space. It is reallocated from the same place
+ * each time, unless the library needs a large scratch space.
+ */
+char *_XAllocScratch (Display *dpy, unsigned long nbytes)
+{
+ if (nbytes > dpy->scratch_length) {
+ if (dpy->scratch_buffer) Xfree (dpy->scratch_buffer);
+ if (dpy->scratch_buffer = Xmalloc((unsigned) nbytes))
+ dpy->scratch_length = nbytes;
+ else dpy->scratch_length = 0;
+ }
+ return (dpy->scratch_buffer);
+}
+
+/*
+ * Given a visual id, find the visual structure for this id on this display.
+ */
+Visual *_XVIDtoVisual (Display *dpy, VisualID id)
+{
+ register int i, j, k;
+ register Screen *sp;
+ register Depth *dp;
+ register Visual *vp;
+ for (i = 0; i < dpy->nscreens; i++) {
+ sp = &dpy->screens[i];
+ for (j = 0; j < sp->ndepths; j++) {
+ dp = &sp->depths[j];
+ /* if nvisuals == 0 then visuals will be NULL */
+ for (k = 0; k < dp->nvisuals; k++) {
+ vp = &dp->visuals[k];
+ if (vp->visualid == id) return (vp);
+ }
+ }
+ }
+ return (NULL);
+}
+
+void XFree (void *data)
+{
+ Xfree (data);
+}
+
+#ifdef _XNEEDBCOPYFUNC
+void _Xbcopy(char *b1, char *b2, length)
+{
+ if (b1 < b2) {
+ b2 += length;
+ b1 += length;
+ while (length--)
+ *--b2 = *--b1;
+ } else {
+ while (length--)
+ *b2++ = *b1++;
+ }
+}
+#endif
+
+#endif /* NEEDFORNX */
+
+void NXProcData (Display *dpy, char *data, long len)
+{
+ if (dpy->bufptr + (len) <= dpy->bufmax) {
+ bcopy(data, dpy->bufptr, (int)len);
+ dpy->bufptr += ((len) + 3) & ~3;
+ } else {
+ N_XSend(dpy, data, len);
+ }
+}
+
+
+#ifdef WORD64
+
+/*
+ * XXX This is a *really* stupid way of doing this. It should just use
+ * dpy->bufptr directly, taking into account where in the word it is.
+ */
+
+/*
+ * Data16 - Place 16 bit data in the buffer.
+ *
+ * "dpy" is a pointer to a Display.
+ * "data" is a pointer to the data.
+ * "len" is the length in bytes of the data.
+ */
+
+static void
+doData16(Display *dpy, short *data, unsigned len, char *packbuffer)
+{
+ long *lp,*lpack;
+ long i, nwords,bits;
+ long mask16 = 0x000000000000ffff;
+
+ lp = (long *)data;
+ lpack = (long *)packbuffer;
+
+/* nwords is the number of 16 bit values to be packed,
+ * the low order 16 bits of each word will be packed
+ * into 64 bit words
+ */
+ nwords = len >> 1;
+ bits = 48;
+
+ for(i=0;i<nwords;i++){
+ if (bits == 48) *lpack = 0;
+ *lpack ^= (*lp & mask16) << bits;
+ bits -= 16 ;
+ lp++;
+ if(bits < 0){
+ lpack++;
+ bits = 48;
+ }
+ }
+ Data(dpy, packbuffer, len);
+}
+
+void
+Data16 (Display *dpy, short *data, unsigned len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 1;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ doData16 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) doData16 (dpy, data, len, packbuffer);
+}
+
+/*
+ * Data32 - Place 32 bit data in the buffer.
+ *
+ * "dpy" is a pointer to a Display.
+ * "data" is a pointer to the data.
+ * "len" is the length in bytes of the data.
+ */
+
+static doData32 (Display *dpy, long *data, unsigned len, char *packbuffer)
+{
+ long *lp,*lpack;
+ long i,bits,nwords;
+ long mask32 = 0x00000000ffffffff;
+
+ lpack = (long *) packbuffer;
+ lp = data;
+
+/* nwords is the number of 32 bit values to be packed
+ * the low order 32 bits of each word will be packed
+ * into 64 bit words
+ */
+ nwords = len >> 2;
+ bits = 32;
+
+ for(i=0;i<nwords;i++){
+ if (bits == 32) *lpack = 0;
+ *lpack ^= (*lp & mask32) << bits;
+ bits = bits ^32;
+ lp++;
+ if(bits)
+ lpack++;
+ }
+ Data(dpy, packbuffer, len);
+}
+
+Data32 (Display *dpy, long *data, unsigned len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 2;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ doData32 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) doData32 (dpy, data, len, packbuffer);
+}
+
+#endif /* WORD64 */
+
+
+#ifdef NEEDFORNX
+
+/*
+ * _XFreeQ - free the queue of events, called by XCloseDisplay
+ */
+
+void _XFreeQ (void)
+{
+ register _XQEvent *qelt = _qfree;
+
+ while (qelt) {
+ register _XQEvent *qnxt = qelt->next;
+ Xfree ((char *) qelt);
+ qelt = qnxt;
+ }
+ _qfree = NULL;
+ return;
+}
+#endif /* NEEDFORNX */
+
+/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm.
+ * Otherwise, Xau will not be able to find your cookies in the Xauthority file.
+ *
+ * Note: POSIX says that the ``nodename'' member of utsname does _not_ have
+ * to have sufficient information for interfacing to the network,
+ * and so, you may be better off using gethostname (if it exists).
+ */
+
+#if (defined(_POSIX_SOURCE) && !defined(AIXV3)) || defined(hpux) || defined(USG) || defined(SVR4)
+#define NEED_UTSNAME
+#include <sys/utsname.h>
+#endif
+
+/*
+ * N_XGetHostname - similar to gethostname but allows special processing.
+ */
+int N_XGetHostname (char *buf, int maxlen)
+{
+ int len;
+
+#ifdef NEED_UTSNAME
+ struct utsname name;
+
+ uname (&name);
+ len = strlen (name.nodename);
+ if (len >= maxlen) len = maxlen - 1;
+ strncpy (buf, name.nodename, len);
+ buf[len] = '\0';
+#else
+ buf[0] = '\0';
+ (void) gethostname (buf, maxlen);
+ buf [maxlen - 1] = '\0';
+ len = strlen(buf);
+#endif /* NEED_UTSNAME */
+ return len;
+}
+
+#ifdef NEEDFORNX
+/*
+ * _XScreenOfWindow - get the Screen of a given window
+ */
+
+Screen *_XScreenOfWindow (Display *dpy, Window w)
+{
+ register int i;
+ Window root;
+ int x, y; /* dummy variables */
+ unsigned int width, height, bw, depth; /* dummy variables */
+
+ if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height,
+ &bw, &depth) == False) {
+ return None;
+ }
+ for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */
+ if (root == RootWindow (dpy, i)) {
+ return ScreenOfDisplay (dpy, i);
+ }
+ }
+ return NULL;
+}
+#endif /* NEEDFORNX */
+
+#if (MSKCNT > 4)
+/*
+ * This is a macro if MSKCNT <= 4
+ */
+int
+N_XANYSET(unsigned long *src)
+{
+ int i;
+
+ for (i=0; i<MSKCNT; i++)
+ if (src[ i ])
+ return (1);
+ return (0);
+}
+#endif
+
+#ifdef NEEDFORNX
+#ifdef CRAY
+/*
+ * Cray UniCOS does not have readv and writev so we emulate
+ */
+#include <sys/socket.h>
+
+int _XReadV (int fd, struct iovec *iov, int iovcnt)
+{
+ struct msghdr hdr;
+
+ hdr.msg_iov = iov;
+ hdr.msg_iovlen = iovcnt;
+ hdr.msg_accrights = 0;
+ hdr.msg_accrightslen = 0;
+ hdr.msg_name = 0;
+ hdr.msg_namelen = 0;
+
+ return (recvmsg (fd, &hdr, 0));
+}
+
+int _XWriteV (int fd, struct iovec *iov, int iovcnt)
+{
+ struct msghdr hdr;
+
+ hdr.msg_iov = iov;
+ hdr.msg_iovlen = iovcnt;
+ hdr.msg_accrights = 0;
+ hdr.msg_accrightslen = 0;
+ hdr.msg_name = 0;
+ hdr.msg_namelen = 0;
+
+ return (sendmsg (fd, &hdr, 0));
+}
+
+#endif /* CRAY */
+
+#if defined(SYSV) && defined(i386) && !defined(STREAMSCONN)
+/*
+ * SYSV/386 does not have readv so we emulate
+ */
+#include <sys/uio.h>
+
+int _XReadV (int fd, struct iovec *iov, int iovcnt)
+{
+ int i, len, total;
+ char *base;
+
+ errno = 0;
+ for (i=0, total=0; i<iovcnt; i++, iov++) {
+ len = iov->iov_len;
+ base = iov->iov_base;
+ while (len > 0) {
+ register int nbytes;
+ nbytes = read(fd, base, len);
+ if (nbytes < 0 && total == 0) return -1;
+ if (nbytes <= 0) return total;
+ errno = 0;
+ len -= nbytes;
+ total += nbytes;
+ base += nbytes;
+ }
+ }
+ return total;
+}
+
+#endif /* SYSV && i386 && !STREAMSCONN */
+
+#ifdef STREAMSCONN
+/*
+ * Copyright 1988, 1989 AT&T, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of AT&T not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. AT&T makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL AT&T
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ iovec.c (C source file)
+ Acc: 575557389 Mon Mar 28 08:03:09 1988
+ Mod: 575557397 Mon Mar 28 08:03:17 1988
+ Sta: 575557397 Mon Mar 28 08:03:17 1988
+ Owner: 2011
+ Group: 1985
+ Permissions: 664
+*/
+/*
+ START USER STAMP AREA
+*/
+/*
+ END USER STAMP AREA
+*/
+
+
+extern char _XsTypeofStream[];
+extern Xstream _XsStream[];
+
+#define MAX_WORKAREA 4096
+static char workarea[MAX_WORKAREA];
+
+
+
+int
+_XReadV (int fd, struct iovec v[], int n)
+{
+ int i, rc, len, size = 0;
+ char * buf = workarea;
+ char * p;
+
+ if (n <= 0 || n > 16)
+ {
+ errno = EINVAL;
+ return (-1);
+ }
+ for (i = 0; i < n; ++i)
+ {
+ if ((len = v[i].iov_len) < 0 || v[i].iov_base == NULL)
+ {
+ errno = EINVAL;
+ return (-1);
+ }
+ size += len;
+ }
+ if ((size > MAX_WORKAREA) && ((buf = malloc (size)) == NULL))
+ {
+ errno = EINVAL;
+ return (-1);
+ }
+ if((rc = (*_XsStream[_XsTypeOfStream[fd]].ReadFromStream)(fd, buf, size,
+ BUFFERING))> 0)
+ {
+ for (i = 0, p = buf; i < n; ++i)
+ {
+ memcpy (v[i].iov_base, p, len = v[i].iov_len);
+ p += len;
+ }
+ }
+ if (size > MAX_WORKAREA)
+ free (buf);
+
+ return (rc);
+}
+
+int
+_XWriteV (int fd, struct iovec v[], int n)
+{
+ int i, rc, len, size = 0;
+ char * buf = workarea;
+ char * p;
+
+ if (n <= 0 || n > 16)
+ {
+ errno = EINVAL;
+ return (-1);
+ }
+ for (i = 0; i < n; ++i)
+ {
+ if ((len = v[i].iov_len) < 0 || v[i].iov_base == NULL)
+ {
+ errno = EINVAL;
+ return (-1);
+ }
+ size += len;
+ }
+
+ if ((size > MAX_WORKAREA) && ((buf = malloc (size)) == NULL))
+ {
+ errno = EINVAL;
+ return (-1);
+ }
+ for (i = 0, p = buf; i < n; ++i)
+ {
+ memcpy (p, v[i].iov_base, len = v[i].iov_len);
+ p += len;
+ }
+ rc = (*_XsStream[_XsTypeOfStream[fd]].WriteToStream)(fd, buf, size);
+
+ if (size > MAX_WORKAREA)
+ free (buf);
+
+ return (rc);
+}
+
+
+
+#endif /* STREAMSCONN */
+#endif /* NEEDFORNX */