aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/X11/XlibInt.c
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2017-07-21 12:31:09 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2017-08-25 10:06:49 +0200
commitc350873c7c977efe5210484f04160be45f84ba7e (patch)
tree717d33eb315f4def1307d65108d14715696cd5cf /nx-X11/lib/X11/XlibInt.c
parent1472e7e37838f17b7ed948fa206e8c3434a9d346 (diff)
downloadnx-libs-c350873c7c977efe5210484f04160be45f84ba7e.tar.gz
nx-libs-c350873c7c977efe5210484f04160be45f84ba7e.tar.bz2
nx-libs-c350873c7c977efe5210484f04160be45f84ba7e.zip
Convert nx-X11/lib/ build flow from imake to autotools.
Diffstat (limited to 'nx-X11/lib/X11/XlibInt.c')
-rw-r--r--nx-X11/lib/X11/XlibInt.c4199
1 files changed, 0 insertions, 4199 deletions
diff --git a/nx-X11/lib/X11/XlibInt.c b/nx-X11/lib/X11/XlibInt.c
deleted file mode 100644
index 5afc65149..000000000
--- a/nx-X11/lib/X11/XlibInt.c
+++ /dev/null
@@ -1,4199 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
-/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
-/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
-/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
-/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
-/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
-/* */
-/* nx-X11, NX protocol compression and NX extensions to this software */
-/* are copyright of the aforementioned persons and companies. */
-/* */
-/* Redistribution and use of the present software is allowed according */
-/* to terms specified in the file LICENSE which comes in the source */
-/* distribution. */
-/* */
-/* All rights reserved. */
-/* */
-/* NOTE: This software has received contributions from various other */
-/* contributors, only the core maintainers and supporters are listed as */
-/* copyright holders. Please contact us, if you feel you should be listed */
-/* as copyright holder, as well. */
-/* */
-/**************************************************************************/
-
-/*
-
-Copyright 1985, 1986, 1987, 1998 The Open Group
-
-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.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-/*
- * XlibInt.c - Internal support routines for the C subroutine
- * interface library (Xlib) to the X Window System Protocol V11.0.
- */
-
-#ifdef WIN32
-#define _XLIBINT_
-#endif
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "Xlibint.h"
-#include "Xprivate.h"
-#include <nx-X11/Xpoll.h>
-#if !USE_XCB
-#include <nx-X11/Xtrans/Xtrans.h>
-#include <nx-X11/extensions/xcmiscstr.h>
-#endif /* !USE_XCB */
-#include <assert.h>
-#include <stdio.h>
-#ifdef WIN32
-#include <direct.h>
-#endif
-
-#ifdef XTHREADS
-#include "locking.h"
-
-/* these pointers get initialized by XInitThreads */
-LockInfoPtr _Xglobal_lock = NULL;
-void (*_XCreateMutex_fn)(LockInfoPtr) = NULL;
-/* struct _XCVList *(*_XCreateCVL_fn)() = NULL; */
-void (*_XFreeMutex_fn)(LockInfoPtr) = NULL;
-void (*_XLockMutex_fn)(
- LockInfoPtr /* lock */
-#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
- , char * /* file */
- , int /* line */
-#endif
- ) = NULL;
-void (*_XUnlockMutex_fn)(
- LockInfoPtr /* lock */
-#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
- , char * /* file */
- , int /* line */
-#endif
- ) = NULL;
-xthread_t (*_Xthread_self_fn)(void) = NULL;
-
-#define XThread_Self() ((*_Xthread_self_fn)())
-
-#if !USE_XCB
-#define UnlockNextReplyReader(d) if ((d)->lock) \
- (*(d)->lock->pop_reader)((d),&(d)->lock->reply_awaiters,&(d)->lock->reply_awaiters_tail)
-
-#define QueueReplyReaderLock(d) ((d)->lock ? \
- (*(d)->lock->push_reader)(d,&(d)->lock->reply_awaiters_tail) : NULL)
-#define QueueEventReaderLock(d) ((d)->lock ? \
- (*(d)->lock->push_reader)(d,&(d)->lock->event_awaiters_tail) : NULL)
-#endif /* !USE_XCB */
-
-#else /* XTHREADS else */
-
-#if !USE_XCB
-#define UnlockNextReplyReader(d)
-#define UnlockNextEventReader(d)
-#endif /* !USE_XCB */
-
-#endif /* XTHREADS else */
-
-#ifdef NX_TRANS_SOCKET
-
-#include <nx/NX.h>
-#include <nx/NXvars.h>
-
-static struct timeval retry;
-
-/*
- * From Xtranssock.c. Presently the congestion state
- * is reported by the proxy to the application, by
- * invoking the callback directly. The function will
- * be possibly used in the future, to be able to track
- * the bandwidth usage even when the NX transport is
- * not running. Note that in this sample implementation
- * the congestion state is checked very often and can
- * be surely optimized.
- */
-
-#ifdef NX_TRANS_CHANGE
-extern int _X11TransSocketCongestionChange(XtransConnInfo, int *);
-#endif
-
-#endif /* #ifdef NX_TRANS_SOCKET */
-
-/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
- * systems are broken and return EWOULDBLOCK when they should return EAGAIN
- */
-#ifdef WIN32
-#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK)
-#else
-#ifdef __CYGWIN__ /* Cygwin uses ENOBUFS to signal socket is full */
-#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
-#else
-#if defined(EAGAIN) && defined(EWOULDBLOCK)
-#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK)
-#else
-#ifdef EAGAIN
-#define ETEST() (errno == EAGAIN)
-#else
-#define ETEST() (errno == EWOULDBLOCK)
-#endif /* EAGAIN */
-#endif /* EAGAIN && EWOULDBLOCK */
-#endif /* __CYGWIN__ */
-#endif /* WIN32 */
-
-#ifdef WIN32
-#define ECHECK(err) (WSAGetLastError() == err)
-#define ESET(val) WSASetLastError(val)
-#else
-#define ECHECK(err) (errno == err)
-#define ESET(val) errno = val
-#endif
-
-#if defined(LOCALCONN) || defined(LACHMAN)
-#ifdef EMSGSIZE
-#define ESZTEST() (ECHECK(EMSGSIZE) || ECHECK(ERANGE))
-#else
-#define ESZTEST() ECHECK(ERANGE)
-#endif
-#else
-#ifdef EMSGSIZE
-#define ESZTEST() ECHECK(EMSGSIZE)
-#endif
-#endif
-
-#if !USE_XCB
-
-#define STARTITERATE(tpvar,type,start,endcond) \
- for (tpvar = (type *) (start); endcond; )
-#define ITERPTR(tpvar) (char *)tpvar
-#define RESETITERPTR(tpvar,type,start) tpvar = (type *) (start)
-#define INCITERPTR(tpvar,type) tpvar++
-#define ENDITERATE
-
-
-typedef union {
- xReply rep;
- char buf[BUFSIZE];
-} _XAlignedBuffer;
-
-static char *_XAsyncReply(
- Display *dpy,
- register xReply *rep,
- char *buf,
- register int *lenp,
- Bool discard);
-#endif /* !USE_XCB */
-
-/*
- * 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 *, xError *) 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.
- */
-
-#if !USE_XCB
-static xReq _dummy_request = {
- 0, 0, 0
-};
-
-#ifdef NX_TRANS_SOCKET
-
-/*
- * Replace the standard Select with a version giving NX a
- * chance to check its own descriptors. This doesn't cover
- * the cases where the system is using poll or when system-
- * specific defines override the Select definition (OS/2).
- */
-
-int _XSelect(int maxfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
-{
-#ifdef NX_TRANS_TEST
- fprintf(stderr, "_XSelect: Called with [%d][%p][%p][%p][%p].\n",
- maxfds, (void *) readfds, (void *) writefds, (void *) exceptfds,
- (void *) timeout);
-#endif
-
- if (NXTransRunning(NX_FD_ANY))
- {
- fd_set t_readfds, t_writefds;
- struct timeval t_timeout;
-
- int n, r, e;
-
-#ifdef NX_TRANS_TEST
-
- if (exceptfds != NULL)
- {
- fprintf(stderr, "_XSelect: WARNING! Can't handle exception fds in select.\n");
- }
-
-#endif
-
- if (readfds == NULL)
- {
- FD_ZERO(&t_readfds);
-
- readfds = &t_readfds;
- }
-
- if (writefds == NULL)
- {
- FD_ZERO(&t_writefds);
-
- writefds = &t_writefds;
- }
-
- if (timeout == NULL)
- {
- t_timeout.tv_sec = 10;
- t_timeout.tv_usec = 0;
-
- timeout = &t_timeout;
- }
-
- n = maxfds;
-
- /*
- * If the transport is gone avoid
- * sleeping until the timeout.
- */
-
- if (NXTransPrepare(&n, readfds, writefds, timeout) != 0)
- {
- NXTransSelect(&r, &e, &n, readfds, writefds, timeout);
-
- NXTransExecute(&r, &e, &n, readfds, writefds, timeout);
-
- errno = e;
-
- return r;
- }
- else
- {
- return 0;
- }
- }
- else
- {
- return select(maxfds, readfds, writefds, exceptfds, timeout);
- }
-}
-
-#else /* #ifdef NX_TRANS_SOCKET */
-
-int _XSelect(int maxfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
-{
- return select(maxfds, readfds, writefds, exceptfds, timeout);
-}
-
-#endif /* #ifdef NX_TRANS_SOCKET */
-
-/*
- * This is an OS dependent routine which:
- * 1) returns as soon as the connection can be written on....
- * 2) if the connection can be read, must enqueue events and handle errors,
- * until the connection is writable.
- */
-static void
-_XWaitForWritable(
- Display *dpy
-#ifdef XTHREADS
- ,
- xcondition_t cv /* our reading condition variable */
-#endif
- )
-{
-#ifdef USE_POLL
- struct pollfd filedes;
-#else
- fd_set r_mask;
- fd_set w_mask;
-#endif
- int nfound;
-
-#ifdef NX_TRANS_SOCKET
-#if defined(NX_TRANS_CHANGE)
- int congestion;
-#endif
- if (_XGetIOError(dpy)) {
- return;
- }
-#endif
-
-#ifdef USE_POLL
- filedes.fd = dpy->fd;
- filedes.events = 0;
-#else
- FD_ZERO(&r_mask);
- FD_ZERO(&w_mask);
-#endif
-
- for (;;) {
-#ifdef XTHREADS
- /* We allow only one thread at a time to read, to minimize
- passing of read data between threads.
- Now, who is it? If there is a non-NULL reply_awaiters and
- we (i.e., our cv) are not at the head of it, then whoever
- is at the head is the reader, and we don't read.
- Otherwise there is no reply_awaiters or we are at the
- head, having just appended ourselves.
- In this case, if there is a event_awaiters, then whoever
- is at the head of it got there before we did, and they are the
- reader.
-
- Last cases: no event_awaiters and we are at the head of
- reply_awaiters or reply_awaiters is NULL: we are the reader,
- since there is obviously no one else involved.
-
- XXX - what if cv is NULL and someone else comes along after
- us while we are waiting?
- */
-
- if (!dpy->lock ||
- (!dpy->lock->event_awaiters &&
- (!dpy->lock->reply_awaiters ||
- dpy->lock->reply_awaiters->cv == cv)))
-#endif
-
-#ifndef NX_TRANS_SOCKET
-#ifdef USE_POLL
- filedes.events = POLLIN;
- filedes.events |= POLLOUT;
-#else
- FD_SET(dpy->fd, &r_mask);
- FD_SET(dpy->fd, &w_mask);
-#endif
-#endif /* #ifndef NX_TRANS_SOCKET */
-
- do {
-#ifdef NX_TRANS_SOCKET
- /*
- * Give a chance to the registered client to perform
- * any needed operation before entering the select.
- */
-
-#ifdef NX_TRANS_TEST
- fprintf(stderr, "_XWaitForWritable: WAIT! Waiting for the display to become writable.\n");
-#endif
- NXTransFlush(dpy->fd);
-
- if (_NXDisplayBlockFunction != NULL) {
- (*_NXDisplayBlockFunction)(dpy, NXBlockWrite);
- }
-
- /*
- * Need to set again the descriptors as we could have
- * run multiple selects before having the possibility
- * to read or write to the X connection.
- */
-
-#ifdef USE_POLL
- filedes.events = POLLIN;
- filedes.events |= POLLOUT;
-#else
- FD_SET(dpy->fd, &r_mask);
- FD_SET(dpy->fd, &w_mask);
-#endif
-#endif /* #ifdef NX_TRANS_SOCKET */
- UnlockDisplay(dpy);
-#ifdef USE_POLL
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XWaitForWritable: Calling poll().\n");
-#endif
- nfound = poll (&filedes, 1, -1);
-#else /* USE_POLL */
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XWaitForWritable: Calling select() after [%ld] ms.\n",
- NXTransTime());
-#endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) */
-#ifdef NX_TRANS_SOCKET
- /*
- * Give a chance to the callback to detect
- * the failure of the display even if we
- * miss the interrupt inside the select.
- */
-
- if (_NXDisplayErrorFunction != NULL) {
- retry.tv_sec = 5;
- retry.tv_usec = 0;
- nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, &retry);
- } else {
- nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL);
- }
-#else /* NX_TRANS_SOCKET */
- nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL);
-#endif /* NX_TRANS_SOCKET */
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XWaitForWritable: Out of select() with [%d] after [%ld] ms.\n",
- nfound, NXTransTime());
-
- if (FD_ISSET(dpy->fd, &r_mask))
- {
- BytesReadable_t pend;
-
- _X11TransBytesReadable(dpy->trans_conn, &pend);
-
- fprintf(stderr, "_XWaitForWritable: Descriptor [%d] is ready with [%ld] bytes to read.\n",
- dpy->fd, pend);
- }
-
- if (FD_ISSET(dpy->fd, &w_mask))
- {
- fprintf(stderr, "_XWaitForWritable: Descriptor [%d] has become writable.\n\n",
- dpy->fd);
- }
-#endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) */
-#endif /* USE_POLL */
- InternalLockDisplay(dpy, cv != NULL);
-#ifdef NX_TRANS_SOCKET
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
- if (_NXDisplayCongestionFunction != NULL &&
- _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
- (*_NXDisplayCongestionFunction)(dpy, congestion);
- }
-#endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE) */
- if (nfound <= 0) {
- if ((nfound == -1 && !(ECHECK(EINTR) || ETEST())) ||
- (_NXDisplayErrorFunction != NULL &&
- (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
- _XIOError(dpy);
- return;
- }
- }
-#else /* NX_TRANS_SOCKET */
- if (nfound < 0 && !(ECHECK(EINTR) || ETEST()))
- _XIOError(dpy);
-#endif /* NX_TRANS_SOCKET */
- } while (nfound <= 0);
-
- if (
-#ifdef USE_POLL
- filedes.revents & POLLIN
-#else /* USE_POLL */
- FD_ISSET(dpy->fd, &r_mask)
-#endif /* USE_POLL */
- )
- {
- _XAlignedBuffer buf;
- BytesReadable_t pend;
- register int len;
- register xReply *rep;
-
- /* find out how much data can be read */
- if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0)
-#ifdef NX_TRANS_SOCKET
- {
- _XIOError(dpy);
-
- return;
- }
-#else /* NX_TRANS_SOCKET */
- _XIOError(dpy);
-#endif /* NX_TRANS_SOCKET */
- len = pend;
-
- /* must read at least one xEvent; if none is pending, then
- we'll just block waiting for it */
- if (len < SIZEOF(xReply)
-#ifdef XTHREADS
- || dpy->async_handlers
-#endif
- )
- len = SIZEOF(xReply);
-
- /* but we won't read more than the max buffer size */
- if (len > BUFSIZE) len = BUFSIZE;
-
- /* round down to an integral number of XReps */
- len = (len / SIZEOF(xReply)) * SIZEOF(xReply);
-
- (void) _XRead (dpy, buf.buf, (long) len);
-
- STARTITERATE(rep,xReply,buf.buf,len > 0) {
- if (rep->generic.type == X_Reply) {
- int tmp = len;
- RESETITERPTR(rep,xReply,
- _XAsyncReply (dpy, rep,
- ITERPTR(rep), &tmp, True));
- len = tmp;
- pend = len;
- } else {
- if (rep->generic.type == X_Error)
- _XError (dpy, (xError *)rep);
- else /* must be an event packet */
- _XEnq (dpy, (xEvent *)rep);
- INCITERPTR(rep,xReply);
- len -= SIZEOF(xReply);
- }
- } ENDITERATE
-#ifdef XTHREADS
- if (dpy->lock && dpy->lock->event_awaiters)
- ConditionSignal(dpy, dpy->lock->event_awaiters->cv);
-#endif
- }
-#ifdef USE_POLL
- if (filedes.revents & (POLLOUT|POLLHUP|POLLERR))
-#else
- if (FD_ISSET(dpy->fd, &w_mask))
-#endif
- {
-#ifdef XTHREADS
- if (dpy->lock) {
- ConditionBroadcast(dpy, dpy->lock->writers);
- }
-#endif
- return;
- }
- }
-}
-#endif /* !USE_XCB */
-
-
-#define POLLFD_CACHE_SIZE 5
-
-/* initialize the struct array passed to poll() below */
-Bool _XPollfdCacheInit(
- Display *dpy)
-{
-#ifdef USE_POLL
- struct pollfd *pfp;
-
- pfp = Xmalloc(POLLFD_CACHE_SIZE * sizeof(struct pollfd));
- if (!pfp)
- return False;
- pfp[0].fd = dpy->fd;
- pfp[0].events = POLLIN;
-
- dpy->filedes = (XPointer)pfp;
-#endif
- return True;
-}
-
-void _XPollfdCacheAdd(
- Display *dpy,
- int fd)
-{
-#ifdef USE_POLL
- struct pollfd *pfp = (struct pollfd *)dpy->filedes;
-
- if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) {
- pfp[dpy->im_fd_length].fd = fd;
- pfp[dpy->im_fd_length].events = POLLIN;
- }
-#endif
-}
-
-/* ARGSUSED */
-void _XPollfdCacheDel(
- Display *dpy,
- int fd) /* not used */
-{
-#ifdef USE_POLL
- struct pollfd *pfp = (struct pollfd *)dpy->filedes;
- struct _XConnectionInfo *conni;
-
- /* just recalculate whole list */
- if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) {
- int loc = 1;
- for (conni = dpy->im_fd_info; conni; conni=conni->next) {
- pfp[loc].fd = conni->fd;
- pfp[loc].events = POLLIN;
- loc++;
- }
- }
-#endif
-}
-
-#if !USE_XCB
-/* returns True iff there is an event in the queue newer than serial_num */
-
-static Bool
-_XNewerQueuedEvent(
- Display *dpy,
- int serial_num)
-{
- _XQEvent *qev;
-
- if (dpy->next_event_serial_num == serial_num)
- return False;
-
- qev = dpy->head;
- while (qev) {
- if (qev->qserial_num >= serial_num) {
- return True;
- }
- qev = qev->next;
- }
- return False;
-}
-
-static int
-_XWaitForReadable(
- Display *dpy)
-{
- int result;
- int fd = dpy->fd;
- struct _XConnectionInfo *ilist;
- register int saved_event_serial = 0;
- int in_read_events = 0;
- register Bool did_proc_conni = False;
-#ifdef USE_POLL
- struct pollfd *filedes;
-#else
- fd_set r_mask;
- int highest_fd = fd;
-#endif
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
- int congestion;
-#endif
-#ifdef NX_TRANS_SOCKET
- if (_XGetIOError(dpy)) {
- return -1;
- }
-#endif
-
-#ifdef USE_POLL
- if (dpy->im_fd_length + 1 > POLLFD_CACHE_SIZE
- && !(dpy->flags & XlibDisplayProcConni)) {
- /* XXX - this fallback is gross */
- int i;
-
- filedes = (struct pollfd *)Xmalloc(dpy->im_fd_length * sizeof(struct pollfd));
- filedes[0].fd = fd;
- filedes[0].events = POLLIN;
- for (ilist=dpy->im_fd_info, i=1; ilist; ilist=ilist->next, i++) {
- filedes[i].fd = ilist->fd;
- filedes[i].events = POLLIN;
- }
- } else {
- filedes = (struct pollfd *)dpy->filedes;
- }
-#else /* USE_POLL */
- FD_ZERO(&r_mask);
-#endif /* USE_POLL */
- for (;;) {
-#ifndef USE_POLL
- FD_SET(fd, &r_mask);
- if (!(dpy->flags & XlibDisplayProcConni))
- for (ilist=dpy->im_fd_info; ilist; ilist=ilist->next) {
- FD_SET(ilist->fd, &r_mask);
- if (ilist->fd > highest_fd)
- highest_fd = ilist->fd;
- }
-#endif /* USE_POLL */
- UnlockDisplay(dpy);
-#ifdef USE_POLL
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XWaitForReadable: Calling poll().\n");
-#endif
- result = poll(filedes,
- (dpy->flags & XlibDisplayProcConni) ? 1 : 1+dpy->im_fd_length,
- -1);
-#else /* USE_POLL */
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XWaitForReadable: Calling select().\n");
-#endif
-#ifdef NX_TRANS_SOCKET
- /*
- * Give a chance to the registered application
- * to perform any needed operation.
- */
-
-#ifdef NX_TRANS_TEST
- fprintf(stderr, "_XWaitForReadable: WAIT! Waiting for the display to become readable.\n");
-#endif
- NXTransFlush(dpy->fd);
-
- if (_NXDisplayBlockFunction != NULL) {
- (*_NXDisplayBlockFunction)(dpy, NXBlockRead);
- }
-
- if (_NXDisplayErrorFunction != NULL) {
- retry.tv_sec = 5;
- retry.tv_usec = 0;
- result = Select(highest_fd + 1, &r_mask, NULL, NULL, &retry);
- } else {
- result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL);
- }
-#else /* NX_TRANS_SOCKET */
- result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL);
-#endif /* NX_TRANS_SOCKET */
-#endif /* USE_POLL */
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XWaitForReadable: Out of select with result [%d] and errno [%d].\n",
- result, (result < 0 ? errno : 0));
-#endif
- InternalLockDisplay(dpy, dpy->flags & XlibDisplayReply);
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
- if (_NXDisplayCongestionFunction != NULL &&
- _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
- (*_NXDisplayCongestionFunction)(dpy, congestion);
- }
-#endif
-#ifdef NX_TRANS_SOCKET
- if (result <= 0) {
- if ((result == -1 && !(ECHECK(EINTR) || ETEST())) ||
- (_NXDisplayErrorFunction != NULL &&
- (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
- _XIOError(dpy);
- return -1;
- }
- continue;
- }
-#else
- if (result == -1 && !(ECHECK(EINTR) || ETEST())) _XIOError(dpy);
- if (result <= 0)
- continue;
-#endif
-#ifdef USE_POLL
- if (filedes[0].revents & (POLLIN|POLLHUP|POLLERR))
-#else
- if (FD_ISSET(fd, &r_mask))
-#endif
- break;
- if (!(dpy->flags & XlibDisplayProcConni)) {
- int i;
-
- saved_event_serial = dpy->next_event_serial_num;
- /* dpy flags can be clobbered by internal connection callback */
- in_read_events = dpy->flags & XlibDisplayReadEvents;
- for (ilist=dpy->im_fd_info, i=1; ilist; ilist=ilist->next, i++) {
-#ifdef USE_POLL
- if (filedes[i].revents & POLLIN)
-#else
- if (FD_ISSET(ilist->fd, &r_mask))
-#endif
- {
- _XProcessInternalConnection(dpy, ilist);
- did_proc_conni = True;
- }
- }
-#ifdef USE_POLL
- if (dpy->im_fd_length + 1 > POLLFD_CACHE_SIZE)
- Xfree(filedes);
-#endif
- }
- if (did_proc_conni) {
- /* some internal connection callback might have done an
- XPutBackEvent. We notice it here and if we needed an event,
- we can return all the way. */
- if (_XNewerQueuedEvent(dpy, saved_event_serial)
- && (in_read_events
-#ifdef XTHREADS
- || (dpy->lock && dpy->lock->event_awaiters)
-#endif
- ))
- return -2;
- did_proc_conni = False;
- }
- }
-#ifdef XTHREADS
-#ifdef XTHREADS_DEBUG
- printf("thread %x _XWaitForReadable returning\n", XThread_Self());
-#endif
-#endif
- return 0;
-}
-#endif /* !USE_XCB */
-
-static int sync_hazard(Display *dpy)
-{
- unsigned long span = dpy->request - dpy->last_request_read;
- unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10);
- return span >= 65535 - hazard - 10;
-}
-
-static
-void sync_while_locked(Display *dpy)
-{
-#ifdef XTHREADS
- if (dpy->lock)
- (*dpy->lock->user_lock_display)(dpy);
-#endif
- UnlockDisplay(dpy);
- SyncHandle();
- InternalLockDisplay(dpy, /* don't skip user locks */ 0);
-#ifdef XTHREADS
- if (dpy->lock)
- (*dpy->lock->user_unlock_display)(dpy);
-#endif
-}
-
-void _XSeqSyncFunction(
- register Display *dpy)
-{
- xGetInputFocusReply rep;
- _X_UNUSED register xReq *req;
-
-#ifdef NX_TRANS_SOCKET
-#ifdef NX_TRANS_DEBUG
- fprintf(stderr, "_XSeqSyncFunction: Going to synchronize the display.\n");
-#endif
-
- if (dpy->flags & XlibDisplayIOError)
- {
-#ifdef NX_TRANS_DEBUG
- fprintf(stderr, "_XSeqSyncFunction: Returning 0 with I/O error detected.\n");
-#endif
- return;
- }
-#endif /* NX_TRANS_SOCKET */
- if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) {
- GetEmptyReq(GetInputFocus, req);
- (void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
- sync_while_locked(dpy);
- } else if (sync_hazard(dpy))
- _XSetPrivSyncFunction(dpy);
-}
-
-/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */
-static int
-_XPrivSyncFunction (Display *dpy)
-{
-#ifdef XTHREADS
- assert(!dpy->lock_fns);
-#endif
- assert(dpy->synchandler == _XPrivSyncFunction);
- assert((dpy->flags & XlibDisplayPrivSync) != 0);
- dpy->synchandler = dpy->savedsynchandler;
- dpy->savedsynchandler = NULL;
- dpy->flags &= ~XlibDisplayPrivSync;
- if(dpy->synchandler)
- dpy->synchandler(dpy);
- _XIDHandler(dpy);
- _XSeqSyncFunction(dpy);
- return 0;
-}
-
-void _XSetPrivSyncFunction(Display *dpy)
-{
-#ifdef XTHREADS
- if (dpy->lock_fns)
- return;
-#endif
- if (!(dpy->flags & XlibDisplayPrivSync)) {
- dpy->savedsynchandler = dpy->synchandler;
- dpy->synchandler = _XPrivSyncFunction;
- dpy->flags |= XlibDisplayPrivSync;
- }
-}
-
-void _XSetSeqSyncFunction(Display *dpy)
-{
- if (sync_hazard(dpy))
- _XSetPrivSyncFunction (dpy);
-}
-
-#if !USE_XCB
-#ifdef XTHREADS
-static void _XFlushInt(
- register Display *dpy,
- register xcondition_t cv);
-#endif
-
-/*
- * _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 _XFlush(
- register Display *dpy)
-{
-#ifdef XTHREADS
- /* With multi-threading we introduce an internal routine to which
- we can pass a condition variable to do locking correctly. */
-
- _XFlushInt(dpy, NULL);
-}
-
-/* _XFlushInt - Internal version of _XFlush used to do multi-threaded
- * locking correctly.
- */
-
-static void _XFlushInt(
- register Display *dpy,
- register xcondition_t cv)
-{
-#endif /* XTHREADS*/
- register long size, todo;
- register int write_stat;
- register char *bufindex;
- _XExtension *ext;
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
- int congestion;
-#endif
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XFlushInt: Entering flush with [%d] bytes to write.\n",
- (dpy->bufptr - dpy->buffer));
-#endif
- /* This fix resets the bufptr to the front of the buffer so
- * additional appends to the bufptr will not corrupt memory. Since
- * the server is down, these appends are no-op's anyway but
- * callers of _XFlush() are not verifying this before they call it.
- */
- if (dpy->flags & XlibDisplayIOError)
- {
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XFlushInt: Returning with I/O error detected.\n");
-#endif
- dpy->bufptr = dpy->buffer;
- dpy->last_req = (char *)&_dummy_request;
- return;
- }
-
-#ifdef XTHREADS
-#ifdef NX_TRANS_SOCKET
- while (dpy->flags & XlibDisplayWriting) {
- if (_XGetIOError(dpy)) {
- return;
- }
-#else
- while (dpy->flags & XlibDisplayWriting) {
-#endif
- if (dpy->lock) {
- ConditionWait(dpy, dpy->lock->writers);
- } else {
- _XWaitForWritable (dpy, cv);
- }
- }
-#endif
- size = todo = dpy->bufptr - dpy->buffer;
- if (!size) return;
-#ifdef XTHREADS
- dpy->flags |= XlibDisplayWriting;
- /* make sure no one else can put in data */
- dpy->bufptr = dpy->bufmax;
-#endif
- for (ext = dpy->flushes; ext; ext = ext->next_flush)
- (*ext->before_flush)(dpy, &ext->codes, dpy->buffer, size);
- bufindex = 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) {
- ESET(0);
- write_stat = _X11TransWrite(dpy->trans_conn,
- bufindex, (int) todo);
- if (write_stat >= 0) {
-#ifdef NX_TRANS_SOCKET
- if (_NXDisplayWriteFunction != NULL) {
- (*_NXDisplayWriteFunction)(dpy, write_stat);
- }
-#ifdef NX_TRANS_CHANGE
- if (_NXDisplayCongestionFunction != NULL &&
- _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
- (*_NXDisplayCongestionFunction)(dpy, congestion);
- }
-#endif
-#endif
- size -= write_stat;
- todo = size;
- bufindex += write_stat;
- } else if (ETEST()) {
- _XWaitForWritable(dpy
-#ifdef XTHREADS
- , cv
-#endif
- );
-#ifdef SUNSYSV
- } else if (ECHECK(0)) {
- _XWaitForWritable(dpy
-#ifdef XTHREADS
- , cv
-#endif
- );
-#endif
-#ifdef ESZTEST
- } else if (ESZTEST()) {
- if (todo > 1)
- todo >>= 1;
- else {
- _XWaitForWritable(dpy
-#ifdef XTHREADS
- , cv
-#endif
- );
- }
-#endif
-#ifdef NX_TRANS_SOCKET
- } else if (!ECHECK(EINTR) ||
- (_NXDisplayErrorFunction != NULL &&
- (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
- _XIOError(dpy);
- return;
- }
-#else
- } else if (!ECHECK(EINTR)) {
- /* Write failed! */
- /* errno set by write system call. */
- _XIOError(dpy);
- }
-#endif
-#ifdef NX_TRANS_SOCKET
- if (_XGetIOError(dpy)) {
- return;
- }
-#endif
- }
- dpy->last_req = (char *)&_dummy_request;
- _XSetSeqSyncFunction(dpy);
- dpy->bufptr = dpy->buffer;
-#ifdef XTHREADS
- dpy->flags &= ~XlibDisplayWriting;
-#endif
-}
-
-int
-_XEventsQueued(
- register Display *dpy,
- int mode)
-{
- register int len;
- BytesReadable_t pend;
- _XAlignedBuffer buf;
- register xReply *rep;
- char *read_buf;
-#ifdef XTHREADS
- int entry_event_serial_num;
- struct _XCVList *cvl = NULL;
- xthread_t self;
-
-#ifdef XTHREADS_DEBUG
- printf("_XEventsQueued called in thread %x\n", XThread_Self());
-#endif
-#endif /* XTHREADS*/
-
- if (mode == QueuedAfterFlush)
- {
- _XFlush(dpy);
- if (dpy->qlen)
- return(dpy->qlen);
- }
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- if (dpy->flags & XlibDisplayIOError) {
- fprintf(stderr, "_XEventsQueued: Returning [%d] after display failure.\n",
- dpy->qlen);
- }
-#endif
- if (dpy->flags & XlibDisplayIOError) return(dpy->qlen);
-
-#ifdef XTHREADS
- /* create our condition variable and append to list,
- * unless we were called from within XProcessInternalConnection
- * or XLockDisplay
- */
- xthread_clear_id(self);
- if (dpy->lock && (xthread_have_id (dpy->lock->conni_thread)
- || xthread_have_id (dpy->lock->locking_thread)))
- /* some thread is in XProcessInternalConnection or XLockDisplay
- so we have to see if we are it */
- self = XThread_Self();
- if (!xthread_have_id(self)
- || (!xthread_equal(self, dpy->lock->conni_thread)
- && !xthread_equal(self, dpy->lock->locking_thread))) {
- /* In the multi-threaded case, if there is someone else
- reading events, then there aren't any available, so
- we just return. If we waited we would block.
- */
- if (dpy->lock && dpy->lock->event_awaiters)
- return dpy->qlen;
- /* nobody here but us, so lock out any newcomers */
- cvl = QueueEventReaderLock(dpy);
- }
-
- while (dpy->lock && cvl && dpy->lock->reply_first) {
- /* note which events we have already seen so we'll know
- if _XReply (in another thread) reads one */
- entry_event_serial_num = dpy->next_event_serial_num;
- ConditionWait(dpy, cvl->cv);
- /* did _XReply read an event we can return? */
- if (_XNewerQueuedEvent(dpy, entry_event_serial_num))
- {
- UnlockNextEventReader(dpy);
- return 0;
- }
- }
-#endif /* XTHREADS*/
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XEventsQueued: Checking bytes readable.\n");
-#endif
- if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0)
-#ifdef NX_TRANS_SOCKET
- {
- _XIOError(dpy);
-
- return (dpy->qlen);
- }
-#else
- _XIOError(dpy);
-#endif
-#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)
- {
- int result;
-#ifdef USE_POLL
- struct pollfd filedes;
-#else
- fd_set r_mask;
- static struct timeval zero_time;
-#endif
-
- dpy->conn_checker = 0;
-#ifdef USE_POLL
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XEventsQueued: Calling poll().\n");
-#endif
- filedes.fd = dpy->fd;
- filedes.events = POLLIN;
- if ((result = poll(&filedes, 1, 0)))
-#else
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XEventsQueued: Calling select().\n");
-#endif
- FD_ZERO(&r_mask);
- FD_SET(dpy->fd, &r_mask);
- if ((result = Select(dpy->fd + 1, &r_mask, NULL, NULL, &zero_time)))
-#endif
- {
- if (result > 0)
- {
- if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0)
-#ifdef NX_TRANS_SOCKET
- {
- _XIOError(dpy);
-
- return (dpy->qlen);
- }
-#else
- _XIOError(dpy);
-#endif
- /* we should not get zero, if we do, force a read */
- if (!pend)
- pend = SIZEOF(xReply);
- }
-#ifdef NX_TRANS_SOCKET
- if (result <= 0) {
- if ((result == -1 && !(ECHECK(EINTR) || ETEST())) ||
- (_NXDisplayErrorFunction != NULL &&
- (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
- _XIOError(dpy);
- return (dpy->qlen);
- }
- }
-#else
- else if (result < 0 && !(ECHECK(EINTR) || ETEST()))
-#endif
- _XIOError(dpy);
- }
- }
-#endif /* XCONN_CHECK_FREQ */
- if (!(len = pend)) {
- /* _XFlush can enqueue events */
-#ifdef XTHREADS
- if (cvl)
-#endif
- {
- UnlockNextEventReader(dpy);
- }
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XEventsQueued: Returning [%d].\n", dpy->qlen);
-#endif
- return(dpy->qlen);
- }
- /* 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.
- */
-#ifdef XTHREADS
- if (dpy->lock && dpy->lock->reply_awaiters) {
- read_buf = (char *)dpy->lock->reply_awaiters->buf;
- len = SIZEOF(xReply);
- } else
-#endif /* XTHREADS*/
- {
- read_buf = buf.buf;
-
- if (len < SIZEOF(xReply)
-#ifdef XTHREADS
- || dpy->async_handlers
-#endif
- )
- len = SIZEOF(xReply);
- else if (len > BUFSIZE)
- len = BUFSIZE;
- len = (len / SIZEOF(xReply)) * SIZEOF(xReply);
- }
-#ifdef XCONN_CHECK_FREQ
- dpy->conn_checker = 0;
-#endif
-
- (void) _XRead (dpy, read_buf, (long) len);
-
-#ifdef NX_TRANS_SOCKET
- if (_XGetIOError(dpy)) {
- return(dpy->qlen);
- }
-#endif
-#ifdef XTHREADS
- /* what did we actually read: reply or event? */
- if (dpy->lock && dpy->lock->reply_awaiters) {
- if (((xReply *)read_buf)->generic.type == X_Reply ||
- ((xReply *)read_buf)->generic.type == X_Error)
- {
- dpy->lock->reply_was_read = True;
- dpy->lock->reply_first = True;
- if (read_buf != (char *)dpy->lock->reply_awaiters->buf)
- memcpy(dpy->lock->reply_awaiters->buf, read_buf,
- len);
- if (cvl) {
- UnlockNextEventReader(dpy);
- }
- return(dpy->qlen); /* we read, so we can return */
- } else if (read_buf != buf.buf)
- memcpy(buf.buf, read_buf, len);
- }
-#endif /* XTHREADS*/
-
- STARTITERATE(rep,xReply,buf.buf,len > 0) {
- if (rep->generic.type == X_Reply) {
- int tmp = len;
- RESETITERPTR(rep,xReply,
- _XAsyncReply (dpy, rep,
- ITERPTR(rep), &tmp, True));
- len = tmp;
- pend = len;
- } else {
- if (rep->generic.type == X_Error)
- _XError (dpy, (xError *)rep);
- else /* must be an event packet */
- _XEnq (dpy, (xEvent *)rep);
- INCITERPTR(rep,xReply);
- len -= SIZEOF(xReply);
- }
- } ENDITERATE
-
-#ifdef XTHREADS
- if (cvl)
-#endif
- {
- UnlockNextEventReader(dpy);
- }
- return(dpy->qlen);
-}
-
-/* _XReadEvents - Flush the output queue,
- * then read as many events as possible (but at least 1) and enqueue them
- */
-void _XReadEvents(
- register Display *dpy)
-{
- _XAlignedBuffer buf;
- BytesReadable_t pend;
- int len;
- register xReply *rep;
- Bool not_yet_flushed = True;
- char *read_buf;
- int i;
- int entry_event_serial_num = dpy->next_event_serial_num;
-#ifdef XTHREADS
- struct _XCVList *cvl = NULL;
- xthread_t self;
-
-#ifdef XTHREADS_DEBUG
- printf("_XReadEvents called in thread %x\n",
- XThread_Self());
-#endif
- /* create our condition variable and append to list,
- * unless we were called from within XProcessInternalConnection
- * or XLockDisplay
- */
- xthread_clear_id(self);
- if (dpy->lock && (xthread_have_id (dpy->lock->conni_thread)
- || xthread_have_id (dpy->lock->locking_thread)))
- /* some thread is in XProcessInternalConnection or XLockDisplay
- so we have to see if we are it */
- self = XThread_Self();
- if (!xthread_have_id(self)
- || (!xthread_equal(self, dpy->lock->conni_thread)
- && !xthread_equal(self, dpy->lock->locking_thread)))
- cvl = QueueEventReaderLock(dpy);
-#endif /* XTHREADS */
-
- do {
-#ifdef XTHREADS
- /* if it is not our turn to read an event off the wire,
- wait til we're at head of list */
- if (dpy->lock && cvl &&
- (dpy->lock->event_awaiters != cvl ||
- dpy->lock->reply_first)) {
- ConditionWait(dpy, cvl->cv);
- continue;
- }
-#endif /* XTHREADS */
- /* find out how much data can be read */
- if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0)
- {
- _XIOError(dpy);
-#ifdef NX_TRANS_SOCKET
- return;
-#endif
- }
- len = pend;
-
- /* must read at least one xEvent; if none is pending, then
- we'll just flush and block waiting for it */
- if (len < SIZEOF(xEvent)
-#ifdef XTHREADS
- || dpy->async_handlers
-#endif
- ) {
- len = SIZEOF(xEvent);
- /* don't flush until the first time we would block */
- if (not_yet_flushed) {
- _XFlush (dpy);
- if (_XNewerQueuedEvent(dpy, entry_event_serial_num)) {
- /* _XReply has read an event for us */
- goto got_event;
- }
- not_yet_flushed = False;
- }
- }
-
-#ifdef XTHREADS
- /* If someone is waiting for a reply, gamble that
- the reply will be the next thing on the wire
- and read it into their buffer. */
- if (dpy->lock && dpy->lock->reply_awaiters) {
- read_buf = (char *)dpy->lock->reply_awaiters->buf;
- len = SIZEOF(xReply);
- } else
-#endif /* XTHREADS*/
- {
- read_buf = buf.buf;
-
- /* but we won't read more than the max buffer size */
- if (len > BUFSIZE)
- len = BUFSIZE;
-
- /* round down to an integral number of XReps */
- len = (len / SIZEOF(xEvent)) * SIZEOF(xEvent);
- }
-
-#ifdef XTHREADS
- if (xthread_have_id(self))
- /* save value we may have to stick in conni_thread */
- dpy->lock->reading_thread = self;
-#endif /* XTHREADS */
- dpy->flags |= XlibDisplayReadEvents;
- i = _XRead (dpy, read_buf, (long) len);
- dpy->flags &= ~XlibDisplayReadEvents;
-#ifdef NX_TRANS_SOCKET
- if (dpy->flags & XlibDisplayIOError)
- {
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XReadEvents: Returning with I/O error detected.\n");
-#endif
- return;
- }
-#endif
- if (i == -2) {
- /* special flag from _XRead to say that internal connection has
- done XPutBackEvent. Which we can use so we're done. */
- got_event:
-#ifdef XTHREADS
- if (dpy->lock && dpy->lock->lock_wait) {
- if (dpy->lock->event_awaiters != cvl)
- /* since it is not us, must be user lock thread */
- ConditionSignal(dpy,
- dpy->lock->event_awaiters->cv);
- (*dpy->lock->lock_wait)(dpy);
- continue;
- }
-#endif
- break;
- }
-#ifdef XTHREADS
- if (xthread_have_id(self))
- xthread_clear_id(dpy->lock->reading_thread);
-
- /* what did we actually read: reply or event? */
- if (dpy->lock && dpy->lock->reply_awaiters) {
- if (((xReply *)read_buf)->generic.type == X_Reply ||
- ((xReply *)read_buf)->generic.type == X_Error)
- {
- dpy->lock->reply_was_read = True;
- dpy->lock->reply_first = True;
- if (read_buf != (char *)dpy->lock->reply_awaiters->buf)
- memcpy(dpy->lock->reply_awaiters->buf,
- read_buf, len);
- ConditionSignal(dpy, dpy->lock->reply_awaiters->cv);
- continue;
- } else if (read_buf != buf.buf)
- memcpy(buf.buf, read_buf, len);
- }
-#endif /* XTHREADS */
-
- STARTITERATE(rep,xReply,buf.buf,len > 0) {
- if (rep->generic.type == X_Reply) {
- RESETITERPTR(rep,xReply,
- _XAsyncReply (dpy, rep,
- ITERPTR(rep), &len, True));
- pend = len;
- } else {
- if (rep->generic.type == X_Error)
- _XError (dpy, (xError *) rep);
- else /* must be an event packet */
- {
- if (rep->generic.type == GenericEvent)
- {
- int evlen;
- evlen = (rep->generic.length << 2);
- if (_XRead(dpy, &read_buf[len], evlen) == -2)
- goto got_event; /* XXX: aargh! */
- }
-
- _XEnq (dpy, (xEvent *)rep);
- }
- INCITERPTR(rep,xReply);
- len -= SIZEOF(xReply);
- }
- } ENDITERATE;
- } while (!_XNewerQueuedEvent(dpy, entry_event_serial_num));
-
- UnlockNextEventReader(dpy);
-}
-
-/*
- * _XRead - Read bytes from the socket taking into account incomplete
- * reads. This routine may have to be reworked if int < long.
- */
-int _XRead(
- register Display *dpy,
- register char *data,
- register long size)
-{
- register long bytes_read;
-#ifdef XTHREADS
- int original_size = size;
-#endif
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
- int congestion;
-#endif
-
- if ((dpy->flags & XlibDisplayIOError) || size == 0)
- return 0;
- ESET(0);
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
- while (1) {
- /*
- * Need to check the congestion state
- * after the read so split the statement
- * in multiple blocks.
- */
-
- bytes_read = _X11TransRead(dpy->trans_conn, data, (int)size);
- if (_NXDisplayCongestionFunction != NULL &&
- _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
- (*_NXDisplayCongestionFunction)(dpy, congestion);
- }
- if (bytes_read == size) {
- break;
- }
-#else
- while ((bytes_read = _X11TransRead(dpy->trans_conn, data, (int)size))
- != size) {
-#endif
-
- if (bytes_read > 0) {
- size -= bytes_read;
- data += bytes_read;
- }
- else if (ETEST()) {
- if (_XWaitForReadable(dpy) == -2)
- return -2; /* internal connection did XPutBackEvent */
- ESET(0);
- }
-#ifdef SUNSYSV
- else if (ECHECK(0)) {
- if (_XWaitForReadable(dpy) == -2)
- return -2; /* internal connection did XPutBackEvent */
- }
-#endif
- else if (bytes_read == 0) {
- /* Read failed because of end of file! */
- ESET(EPIPE);
-#ifdef NX_TRANS_SOCKET
- _XIOError(dpy);
-
- return -1;
-#else
- _XIOError(dpy);
-#endif
- }
-
- else /* bytes_read is less than 0; presumably -1 */ {
- /* If it's a system call interrupt, it's not an error. */
-#ifdef NX_TRANS_SOCKET
- if (!ECHECK(EINTR) ||
- (_NXDisplayErrorFunction != NULL &&
- (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
- _XIOError(dpy);
- return -1;
- }
-#else
- if (!ECHECK(EINTR))
- _XIOError(dpy);
-#endif
- }
-#ifdef NX_TRANS_SOCKET
- if (_XGetIOError(dpy)) {
- return -1;
- }
-#endif
- }
-#ifdef XTHREADS
- if (dpy->lock && dpy->lock->reply_bytes_left > 0)
- {
- dpy->lock->reply_bytes_left -= original_size;
- if (dpy->lock->reply_bytes_left == 0) {
- dpy->flags &= ~XlibDisplayReply;
- UnlockNextReplyReader(dpy);
- }
- }
-#endif /* XTHREADS*/
- return 0;
-}
-#endif /* !USE_XCB */
-
-#ifdef LONG64
-void _XRead32(
- Display *dpy,
- register long *data,
- long len)
-{
- register int *buf;
- register long i;
-
- if (len) {
- (void) _XRead(dpy, (char *)data, len);
- i = len >> 2;
- buf = (int *)data + i;
- data += i;
- while (--i >= 0)
- *--data = *--buf;
- }
-}
-#endif /* LONG64 */
-
-
-
-#if !USE_XCB
-/*
- * _XReadPad - Read bytes from the socket taking into account incomplete
- * reads. If the number of bytes is not 0 mod 4, read additional pad
- * bytes. This routine may have to be reworked if int < long.
- */
-void _XReadPad(
- register Display *dpy,
- register char *data,
- register long size)
-{
- register long bytes_read;
- struct iovec iov[2];
- char pad[3];
-#ifdef XTHREADS
- int original_size;
-#endif
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
- int congestion;
-#endif
-
- 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 = -size & 3;
- iov[1].iov_base = pad;
- size += iov[1].iov_len;
-#ifdef XTHREADS
- original_size = size;
-#endif
- ESET(0);
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
- while (1) {
- bytes_read = _X11TransReadv (dpy->trans_conn, iov, 2);
- if (_NXDisplayCongestionFunction != NULL &&
- _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
- (*_NXDisplayCongestionFunction)(dpy, congestion);
- }
- if (bytes_read == size) {
- break;
- }
-#else
- while ((bytes_read = _X11TransReadv (dpy->trans_conn, iov, 2)) != size) {
-#endif
-
- if (bytes_read > 0) {
- size -= bytes_read;
- if (iov[0].iov_len < bytes_read) {
- int pad_bytes_read = bytes_read - iov[0].iov_len;
- iov[1].iov_len -= pad_bytes_read;
- iov[1].iov_base =
- (char *)iov[1].iov_base + pad_bytes_read;
- 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()) {
- _XWaitForReadable(dpy);
- ESET(0);
- }
-#ifdef SUNSYSV
- else if (ECHECK(0)) {
- _XWaitForReadable(dpy);
- }
-#endif
- else if (bytes_read == 0) {
- /* Read failed because of end of file! */
- ESET(EPIPE);
-#ifdef NX_TRANS_SOCKET
- _XIOError(dpy);
-
- return;
-#else
- _XIOError(dpy);
-#endif
- }
-
- else /* bytes_read is less than 0; presumably -1 */ {
- /* If it's a system call interrupt, it's not an error. */
-#ifdef NX_TRANS_SOCKET
- if (!ECHECK(EINTR) ||
- (_NXDisplayErrorFunction != NULL &&
- (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
- _XIOError(dpy);
- return;
- }
-#else
- if (!ECHECK(EINTR))
- _XIOError(dpy);
-#endif
- }
-#ifdef NX_TRANS_SOCKET
- if (_XGetIOError(dpy)) {
- return;
- }
-#endif
- }
-#ifdef XTHREADS
- if (dpy->lock && dpy->lock->reply_bytes_left > 0)
- {
- dpy->lock->reply_bytes_left -= original_size;
- if (dpy->lock->reply_bytes_left == 0) {
- dpy->flags &= ~XlibDisplayReply;
- UnlockNextReplyReader(dpy);
- }
- }
-#endif /* XTHREADS*/
-}
-
-/*
- * _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
-_XSend (
- register Display *dpy,
- _Xconst char *data,
- register long size)
-{
- struct iovec iov[3];
- static char const pad[3] = {0, 0, 0};
- /* XText8 and XText16 require that the padding bytes be zero! */
-
- long skip, dbufsize, padsize, total, todo;
- _XExtension *ext;
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
- int congestion;
-#endif
-
-#ifdef NX_TRANS_SOCKET
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XSend: Sending data with [%d] bytes to write.\n",
- (dpy->bufptr - dpy->buffer));
-#endif
- if (!size || (dpy->flags & XlibDisplayIOError))
- {
- if (dpy->flags & XlibDisplayIOError)
- {
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XSend: Returning with I/O error detected.\n");
-#endif
- dpy->bufptr = dpy->buffer;
- dpy->last_req = (char *)&_dummy_request;
- }
-
- return;
- }
-#else
- if (!size || (dpy->flags & XlibDisplayIOError)) return;
-#endif
- dbufsize = dpy->bufptr - dpy->buffer;
-#ifdef XTHREADS
- dpy->flags |= XlibDisplayWriting;
- /* make sure no one else can put in data */
- dpy->bufptr = dpy->bufmax;
-#endif
- padsize = -size & 3;
- for (ext = dpy->flushes; ext; ext = ext->next_flush) {
- (*ext->before_flush)(dpy, &ext->codes, dpy->buffer, dbufsize);
- (*ext->before_flush)(dpy, &ext->codes, (char *)data, size);
- if (padsize)
- (*ext->before_flush)(dpy, &ext->codes, pad, padsize);
- }
- skip = 0;
- todo = total = dbufsize + size + padsize;
-
- /*
- * 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, dbufsize)
- InsertIOV ((char *)data, size)
- InsertIOV ((char *)pad, padsize)
-
- ESET(0);
- if ((len = _X11TransWritev(dpy->trans_conn, iov, i)) >= 0) {
-#ifdef NX_TRANS_SOCKET
- if (_NXDisplayWriteFunction != NULL) {
- (*_NXDisplayWriteFunction)(dpy, len);
- }
-#ifdef NX_TRANS_CHANGE
- if (_NXDisplayCongestionFunction != NULL &&
- _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
- (*_NXDisplayCongestionFunction)(dpy, congestion);
- }
-#endif
-#endif
- skip += len;
- total -= len;
- todo = total;
- } else if (ETEST()) {
- _XWaitForWritable(dpy
-#ifdef XTHREADS
- , NULL
-#endif
- );
-#ifdef SUNSYSV
- } else if (ECHECK(0)) {
- _XWaitForWritable(dpy
-#ifdef XTHREADS
- , NULL
-#endif
- );
-#endif
-#ifdef ESZTEST
- } else if (ESZTEST()) {
- if (todo > 1)
- todo >>= 1;
- else {
- _XWaitForWritable(dpy
-#ifdef XTHREADS
- , NULL
-#endif
- );
- }
-#endif
-#ifdef NX_TRANS_SOCKET
- } else if (!ECHECK(EINTR) ||
- (_NXDisplayErrorFunction != NULL &&
- (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
- _XIOError(dpy);
- return;
- }
-#else
- } else if (!ECHECK(EINTR)) {
- _XIOError(dpy);
- }
-#endif
-#ifdef NX_TRANS_SOCKET
- if (_XGetIOError(dpy)) {
- return;
- }
-#endif
- }
- dpy->last_req = (char *) & _dummy_request;
- _XSetSeqSyncFunction(dpy);
- dpy->bufptr = dpy->buffer;
-#ifdef XTHREADS
- dpy->flags &= ~XlibDisplayWriting;
-#endif
- return;
-}
-
-static void
-_XGetMiscCode(
- register Display *dpy)
-{
- xQueryExtensionReply qrep;
- register xQueryExtensionReq *qreq;
- xXCMiscGetVersionReply vrep;
- register xXCMiscGetVersionReq *vreq;
-
- if (dpy->xcmisc_opcode)
- return;
- GetReq(QueryExtension, qreq);
- qreq->nbytes = sizeof(XCMiscExtensionName) - 1;
- qreq->length += (qreq->nbytes+(unsigned)3)>>2;
- _XSend(dpy, XCMiscExtensionName, (long)qreq->nbytes);
- if (!_XReply (dpy, (xReply *)&qrep, 0, xTrue))
- dpy->xcmisc_opcode = -1;
- else {
- GetReq(XCMiscGetVersion, vreq);
- vreq->reqType = qrep.major_opcode;
- vreq->miscReqType = X_XCMiscGetVersion;
- vreq->majorVersion = XCMiscMajorVersion;
- vreq->minorVersion = XCMiscMinorVersion;
- if (!_XReply (dpy, (xReply *)&vrep, 0, xTrue))
- dpy->xcmisc_opcode = -1;
- else
- dpy->xcmisc_opcode = qrep.major_opcode;
- }
-}
-
-void
-_XIDHandler(
- register Display *dpy)
-{
- xXCMiscGetXIDRangeReply grep;
- register xXCMiscGetXIDRangeReq *greq;
-
- if (dpy->resource_max == dpy->resource_mask + 1) {
- _XGetMiscCode(dpy);
- if (dpy->xcmisc_opcode > 0) {
- GetReq(XCMiscGetXIDRange, greq);
- greq->reqType = dpy->xcmisc_opcode;
- greq->miscReqType = X_XCMiscGetXIDRange;
- if (_XReply (dpy, (xReply *)&grep, 0, xTrue) && grep.count) {
- dpy->resource_id = ((grep.start_id - dpy->resource_base) >>
- dpy->resource_shift);
- dpy->resource_max = dpy->resource_id;
- if (grep.count > 5)
- dpy->resource_max += grep.count - 6;
- dpy->resource_max <<= dpy->resource_shift;
- }
- sync_while_locked(dpy);
- }
- }
-}
-
-/*
- * _XAllocID - resource ID allocation routine.
- */
-XID _XAllocID(
- register Display *dpy)
-{
- XID id;
-
- id = dpy->resource_id << dpy->resource_shift;
- if (id >= dpy->resource_max) {
- _XSetPrivSyncFunction(dpy);
- dpy->resource_max = dpy->resource_mask + 1;
- }
- 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;
-}
-
-/*
- * _XAllocIDs - multiple resource ID allocation routine.
- */
-void _XAllocIDs(
- register Display *dpy,
- XID *ids,
- int count)
-{
- XID id;
- int i;
- xXCMiscGetXIDListReply grep;
- register xXCMiscGetXIDListReq *greq;
-
- id = dpy->resource_id << dpy->resource_shift;
- if (dpy->resource_max <= dpy->resource_mask &&
- id <= dpy->resource_mask &&
- (dpy->resource_max - id) > ((count - 1) << dpy->resource_shift)) {
- id += dpy->resource_base;
- for (i = 0; i < count; i++) {
- ids[i] = id;
- id += (1 << dpy->resource_shift);
- dpy->resource_id++;
- }
- return;
- }
- grep.count = 0;
- _XGetMiscCode(dpy);
- if (dpy->xcmisc_opcode > 0) {
- GetReq(XCMiscGetXIDList, greq);
- greq->reqType = dpy->xcmisc_opcode;
- greq->miscReqType = X_XCMiscGetXIDList;
- greq->count = count;
- if (_XReply(dpy, (xReply *)&grep, 0, xFalse) && grep.count) {
- _XRead32(dpy, (long *) ids, 4L * (long) (grep.count));
- for (i = 0; i < grep.count; i++) {
- id = (ids[i] - dpy->resource_base) >> dpy->resource_shift;
- if (id >= dpy->resource_id)
- dpy->resource_id = id;
- }
- if (id >= dpy->resource_max) {
- _XSetPrivSyncFunction(dpy);
- dpy->resource_max = dpy->resource_mask + 1;
- }
- }
- }
- for (i = grep.count; i < count; i++)
- ids[i] = XAllocID(dpy);
-}
-#endif /* !USE_XCB */
-
-/*
- * The hard part about this is that we only get 16 bits from a reply.
- * We have three values that will march along, with the following invariant:
- * dpy->last_request_read <= rep->sequenceNumber <= dpy->request
- * We have to keep
- * dpy->request - dpy->last_request_read < 2^16
- * or else we won't know for sure what value to use in events. We do this
- * by forcing syncs when we get close.
- */
-
-unsigned long
-_XSetLastRequestRead(
- register Display *dpy,
- register xGenericReply *rep)
-{
- register unsigned long newseq, lastseq;
-
- lastseq = dpy->last_request_read;
- /*
- * 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(lastseq);
-
- newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber;
-
- if (newseq < lastseq) {
- newseq += 0x10000;
- if (newseq > dpy->request) {
-#ifdef NX_TRANS_SOCKET
- if (_NXLostSequenceFunction != NULL)
- {
- (*_NXLostSequenceFunction)(dpy, newseq, dpy->request,
- (unsigned int) rep->type);
- }
- else
-#endif /* #ifdef NX_TRANS_SOCKET */
- {
- (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;
- }
- }
-
- dpy->last_request_read = newseq;
- return(newseq);
-}
-
-#if !USE_XCB
-/*
- * _XReply - Wait for a reply packet and copy its contents into the
- * specified rep. Meanwhile we must handle error and event packets that
- * we may encounter.
- */
-Status
-_XReply (
- register Display *dpy,
- register 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;
-#ifdef XTHREADS
- struct _XCVList *cvl;
-#endif
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XReply: Going to wait for an X reply.\n");
-#endif
-
-#ifdef NX_TRANS_SOCKET
- if (dpy->flags & XlibDisplayIOError)
- {
-#ifdef NX_TRANS_DEBUG
- fprintf(stderr, "_XReply: Returning 0 with I/O error detected.\n");
-#endif
- return 0;
- }
-#else
- if (dpy->flags & XlibDisplayIOError)
- return 0;
-#endif
-
-#ifdef XTHREADS
- /* create our condition variable and append to list */
- cvl = QueueReplyReaderLock(dpy);
- if (cvl) {
- cvl->buf = rep;
- if (dpy->lock->reply_awaiters == cvl && !dpy->lock->event_awaiters)
- dpy->lock->reply_first = True;
- }
-
-#ifdef XTHREADS_DEBUG
- printf("_XReply called in thread %x, adding %x to cvl\n",
- XThread_Self(), cvl);
-#endif
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XReply: Going to flush the display buffer.\n");
-#endif
- _XFlushInt(dpy, cvl ? cvl->cv : NULL);
- /* if it is not our turn to read a reply off the wire,
- * wait til we're at head of list. if there is an event waiter,
- * and our reply hasn't been read, they'll be in select and will
- * hand control back to us next.
- */
- if(dpy->lock &&
- (dpy->lock->reply_awaiters != cvl || !dpy->lock->reply_first)) {
- ConditionWait(dpy, cvl->cv);
- }
- dpy->flags |= XlibDisplayReply;
-#else /* XTHREADS else */
- _XFlush(dpy);
-#endif
-
-#ifdef NX_TRANS_SOCKET
- /*
- * We are going to block waiting for the remote
- * X server. Be sure that the proxy has flushed
- * all the data.
- */
-
-#ifdef NX_TRANS_TEST
- fprintf(stderr, "_XReply: Requesting a flush of the NX transport.\n");
-#endif
- NXTransFlush(dpy->fd);
-#endif
-
- for (;;) {
-#ifdef XTHREADS
- /* Did another thread's _XReadEvents get our reply by accident? */
- if (!dpy->lock || !dpy->lock->reply_was_read)
-#endif
- (void) _XRead(dpy, (char *)rep, (long)SIZEOF(xReply));
-#ifdef XTHREADS
- if (dpy->lock)
- dpy->lock->reply_was_read = False;
-#endif
-
- 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 {
- int pend = SIZEOF(xReply);
- if (_XAsyncReply(dpy, rep, (char *)rep, &pend, False)
- != (char *)rep)
- continue;
- }
- if (extra <= rep->generic.length) {
- if (extra > 0)
- /*
- * Read the extra data into storage immediately
- * following the GenericReply structure.
- */
- (void) _XRead (dpy, (char *) (NEXTPTR(rep,xReply)),
- ((long)extra) << 2);
- if (discard) {
- if (extra < rep->generic.length)
- _XEatData(dpy, (rep->generic.length - extra) << 2);
- }
-#ifdef XTHREADS
- if (dpy->lock) {
- if (discard) {
- dpy->lock->reply_bytes_left = 0;
- } else {
- dpy->lock->reply_bytes_left =
- (rep->generic.length - extra) << 2;
- }
- if (dpy->lock->reply_bytes_left == 0) {
- dpy->flags &= ~XlibDisplayReply;
- UnlockNextReplyReader(dpy);
- }
- } else
- dpy->flags &= ~XlibDisplayReply;
-#endif
- 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...
- */
- (void) _XRead (dpy, (char *) (NEXTPTR(rep,xReply)),
- ((long) rep->generic.length) << 2);
- dpy->flags &= ~XlibDisplayReply;
- UnlockNextReplyReader(dpy);
-#ifdef NX_TRANS_SOCKET
- /*
- * The original code has provision
- * for returning already.
- */
-#endif
- _XIOError (dpy);
- return (0);
-
- case X_Error:
- {
- register _XExtension *ext;
- register Bool ret = False;
- int ret_code;
- xError *err = (xError *) rep;
- unsigned long serial;
-
- dpy->flags &= ~XlibDisplayReply;
- serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep);
- if (serial == cur_request)
- /* do not die on "no such font", "can't allocate",
- "can't grab" failures */
- switch ((int)err->errorCode) {
- case BadName:
- switch (err->majorCode) {
- case X_LookupColor:
- case X_AllocNamedColor:
- UnlockNextReplyReader(dpy);
- return(0);
- }
- break;
- case BadFont:
- if (err->majorCode == X_QueryFont) {
- UnlockNextReplyReader(dpy);
- return (0);
- }
- break;
- case BadAlloc:
- case BadAccess:
- UnlockNextReplyReader(dpy);
- return (0);
- }
- /*
- * 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) {
- UnlockNextReplyReader(dpy);
- return(ret_code);
- }
-
- } /* case X_Error */
- break;
- default:
- _XEnq(dpy, (xEvent *) rep);
-#ifdef XTHREADS
- if (dpy->lock && dpy->lock->event_awaiters)
- ConditionSignal(dpy, dpy->lock->event_awaiters->cv);
-#endif
- break;
- }
-#ifdef NX_TRANS_SOCKET
- if (_XGetIOError(dpy)) {
- UnlockNextReplyReader(dpy);
- return 0;
- }
-#endif
- }
-}
-
-static char *
-_XAsyncReply(
- Display *dpy,
- register xReply *rep,
- char *buf,
- register int *lenp,
- Bool discard)
-{
- register _XAsyncHandler *async, *next;
- register int len;
- register Bool consumed = False;
- char *nbuf;
-
- (void) _XSetLastRequestRead(dpy, &rep->generic);
- len = SIZEOF(xReply) + (rep->generic.length << 2);
- if (len < SIZEOF(xReply)) {
-#ifdef NX_TRANS_SOCKET
-
- /*
- * The original code has provision
- * for returning already.
- */
-
-#endif
- _XIOError (dpy);
- buf += *lenp;
- *lenp = 0;
- return buf;
- }
-
- for (async = dpy->async_handlers; async; async = next) {
- next = async->next;
- if ((consumed = (*async->handler)(dpy, rep, buf, *lenp, async->data)))
- break;
- }
- if (!consumed) {
- if (!discard)
- return buf;
- (void) fprintf(stderr,
- "Xlib: unexpected async reply (sequence 0x%lx)!\n",
- dpy->last_request_read);
-#ifdef XTHREADS
-#ifdef XTHREADS_DEBUG
- printf("thread %x, unexpected async reply\n", XThread_Self());
-#endif
-#endif
- if (len > *lenp)
- _XEatData(dpy, len - *lenp);
- }
- if (len < SIZEOF(xReply))
- {
-#ifdef NX_TRANS_SOCKET
-
- /*
- * The original code has provision
- * for returning already.
- */
-
-#endif
- _XIOError (dpy);
- buf += *lenp;
- *lenp = 0;
- return buf;
- }
- if (len >= *lenp) {
- buf += *lenp;
- *lenp = 0;
- return buf;
- }
- *lenp -= len;
- buf += len;
- len = *lenp;
- nbuf = buf;
- while (len > SIZEOF(xReply)) {
- if (*buf == X_Reply)
- return nbuf;
- buf += SIZEOF(xReply);
- len -= SIZEOF(xReply);
- }
- if (len > 0 && len < SIZEOF(xReply)) {
- buf = nbuf;
- len = SIZEOF(xReply) - len;
- nbuf -= len;
- memmove(nbuf, buf, *lenp);
- (void) _XRead(dpy, nbuf + *lenp, (long)len);
- *lenp += len;
- }
- return nbuf;
-}
-#endif /* !USE_XCB */
-
-/*
- * Support for internal connections, such as an IM might use.
- * By Stephen Gildea, X Consortium, September 1993
- */
-
-/* _XRegisterInternalConnection
- * Each IM (or Xlib extension) that opens a file descriptor that Xlib should
- * include in its select/poll mask must call this function to register the
- * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch
- * will also be called.
- *
- * Whenever Xlib detects input available on fd, it will call callback
- * with call_data to process it. If non-Xlib code calls select/poll
- * and detects input available, it must call XProcessInternalConnection,
- * which will call the associated callback.
- *
- * Non-Xlib code can learn about these additional fds by calling
- * XInternalConnectionNumbers or, more typically, by registering
- * a XConnectionWatchProc with XAddConnectionWatch
- * to be called when fds are registered or unregistered.
- *
- * Returns True if registration succeeded, False if not, typically
- * because could not allocate memory.
- * Assumes Display locked when called.
- */
-Status
-_XRegisterInternalConnection(
- Display* dpy,
- int fd,
- _XInternalConnectionProc callback,
- XPointer call_data
-)
-{
- struct _XConnectionInfo *new_conni, **iptr;
- struct _XConnWatchInfo *watchers;
- XPointer *wd;
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XRegisterInternalConnection: Got called.\n");
-#endif
- new_conni = Xmalloc(sizeof(struct _XConnectionInfo));
- if (!new_conni)
- return 0;
- new_conni->watch_data = Xmalloc(dpy->watcher_count * sizeof(XPointer));
- if (!new_conni->watch_data) {
- Xfree(new_conni);
- return 0;
- }
- new_conni->fd = fd;
- new_conni->read_callback = callback;
- new_conni->call_data = call_data;
- new_conni->next = NULL;
- /* link new structure onto end of list */
- for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next)
- ;
- *iptr = new_conni;
- dpy->im_fd_length++;
- _XPollfdCacheAdd(dpy, fd);
-
- for (watchers=dpy->conn_watchers, wd=new_conni->watch_data;
- watchers;
- watchers=watchers->next, wd++) {
- *wd = NULL; /* for cleanliness */
- (*watchers->fn) (dpy, watchers->client_data, fd, True, wd);
- }
-
- return 1;
-}
-
-/* _XUnregisterInternalConnection
- * Each IM (or Xlib extension) that closes a file descriptor previously
- * registered with _XRegisterInternalConnection must call this function.
- * Any XConnectionWatchProc registered by XAddConnectionWatch
- * will also be called.
- *
- * Assumes Display locked when called.
- */
-void
-_XUnregisterInternalConnection(
- Display* dpy,
- int fd
-)
-{
- struct _XConnectionInfo *info_list, **prev;
- struct _XConnWatchInfo *watch;
- XPointer *wd;
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XUnregisterInternalConnection: Got called.\n");
-#endif
- for (prev = &dpy->im_fd_info; (info_list = *prev);
- prev = &info_list->next) {
- if (info_list->fd == fd) {
- *prev = info_list->next;
- dpy->im_fd_length--;
- for (watch=dpy->conn_watchers, wd=info_list->watch_data;
- watch;
- watch=watch->next, wd++) {
- (*watch->fn) (dpy, watch->client_data, fd, False, wd);
- }
- Xfree (info_list->watch_data);
- Xfree (info_list);
- break;
- }
- }
- _XPollfdCacheDel(dpy, fd);
-}
-
-/* XInternalConnectionNumbers
- * Returns an array of fds and an array of corresponding call data.
- * Typically a XConnectionWatchProc registered with XAddConnectionWatch
- * will be used instead of this function to discover
- * additional fds to include in the select/poll mask.
- *
- * The list is allocated with Xmalloc and should be freed by the caller
- * with Xfree;
- */
-Status
-XInternalConnectionNumbers(
- Display *dpy,
- int **fd_return,
- int *count_return
-)
-{
- int count;
- struct _XConnectionInfo *info_list;
- int *fd_list;
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "XInternalConnectionNumbers: Got called.\n");
-#endif
- LockDisplay(dpy);
- count = 0;
- for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next)
- count++;
- fd_list = Xmalloc (count * sizeof(int));
- if (!fd_list) {
- UnlockDisplay(dpy);
- return 0;
- }
- count = 0;
- for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
- fd_list[count] = info_list->fd;
- count++;
- }
- UnlockDisplay(dpy);
-
- *fd_return = fd_list;
- *count_return = count;
- return 1;
-}
-
-void _XProcessInternalConnection(
- Display *dpy,
- struct _XConnectionInfo *conn_info)
-{
- dpy->flags |= XlibDisplayProcConni;
-#if defined(XTHREADS) && !USE_XCB
- if (dpy->lock) {
- /* check cache to avoid call to thread_self */
- if (xthread_have_id(dpy->lock->reading_thread))
- dpy->lock->conni_thread = dpy->lock->reading_thread;
- else
- dpy->lock->conni_thread = XThread_Self();
- }
-#endif /* XTHREADS && !USE_XCB */
- UnlockDisplay(dpy);
- (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data);
- LockDisplay(dpy);
-#if defined(XTHREADS) && !USE_XCB
- if (dpy->lock)
- xthread_clear_id(dpy->lock->conni_thread);
-#endif /* XTHREADS && !USE_XCB */
- dpy->flags &= ~XlibDisplayProcConni;
-}
-
-/* XProcessInternalConnection
- * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection
- * for this fd.
- * The Display is NOT locked during the call.
- */
-void
-XProcessInternalConnection(
- Display* dpy,
- int fd
-)
-{
- struct _XConnectionInfo *info_list;
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "XProcessInternalConnection: Got called.\n");
-#endif
-
- LockDisplay(dpy);
- for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
- if (info_list->fd == fd) {
- _XProcessInternalConnection(dpy, info_list);
- break;
- }
- }
- UnlockDisplay(dpy);
-}
-
-/* XAddConnectionWatch
- * Register a callback to be called whenever _XRegisterInternalConnection
- * or _XUnregisterInternalConnection is called.
- * Callbacks are called with the Display locked.
- * If any connections are already registered, the callback is immediately
- * called for each of them.
- */
-Status
-XAddConnectionWatch(
- Display* dpy,
- XConnectionWatchProc callback,
- XPointer client_data
-)
-{
- struct _XConnWatchInfo *new_watcher, **wptr;
- struct _XConnectionInfo *info_list;
- XPointer *wd_array;
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "XAddConnectionWatch: Got called.\n");
-#endif
- LockDisplay(dpy);
-
- /* allocate new watch data */
- for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
- wd_array = Xrealloc(info_list->watch_data,
- (dpy->watcher_count + 1) * sizeof(XPointer));
- if (!wd_array) {
- UnlockDisplay(dpy);
- return 0;
- }
- info_list->watch_data = wd_array;
- wd_array[dpy->watcher_count] = NULL; /* for cleanliness */
- }
-
- new_watcher = Xmalloc(sizeof(struct _XConnWatchInfo));
- if (!new_watcher) {
- UnlockDisplay(dpy);
- return 0;
- }
- new_watcher->fn = callback;
- new_watcher->client_data = client_data;
- new_watcher->next = NULL;
-
- /* link new structure onto end of list */
- for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next)
- ;
- *wptr = new_watcher;
- dpy->watcher_count++;
-
- /* call new watcher on all currently registered fds */
- for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
- (*callback) (dpy, client_data, info_list->fd, True,
- info_list->watch_data + dpy->watcher_count - 1);
- }
-
- UnlockDisplay(dpy);
- return 1;
-}
-
-/* XRemoveConnectionWatch
- * Unregister a callback registered by XAddConnectionWatch.
- * Both callback and client_data must match what was passed to
- * XAddConnectionWatch.
- */
-void
-XRemoveConnectionWatch(
- Display* dpy,
- XConnectionWatchProc callback,
- XPointer client_data
-)
-{
- struct _XConnWatchInfo *watch;
- struct _XConnWatchInfo *previous = NULL;
- struct _XConnectionInfo *conni;
- int counter = 0;
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "XRemoveConnectionWatch: Got called.\n");
-#endif
- LockDisplay(dpy);
- for (watch=dpy->conn_watchers; watch; watch=watch->next) {
- if (watch->fn == callback && watch->client_data == client_data) {
- if (previous)
- previous->next = watch->next;
- else
- dpy->conn_watchers = watch->next;
- Xfree (watch);
- dpy->watcher_count--;
- /* remove our watch_data for each connection */
- for (conni=dpy->im_fd_info; conni; conni=conni->next) {
- /* don't bother realloc'ing; these arrays are small anyway */
- /* overlapping */
- memmove(conni->watch_data+counter,
- conni->watch_data+counter+1,
- dpy->watcher_count - counter);
- }
- break;
- }
- previous = watch;
- counter++;
- }
- UnlockDisplay(dpy);
-}
-
-/* end of internal connections support */
-
-
-#if !USE_XCB
-/* Read and discard "n" 8-bit bytes of data */
-
-void _XEatData(
- Display *dpy,
- register unsigned long n)
-{
-#define SCRATCHSIZE 2048
- char buf[SCRATCHSIZE];
-
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
- fprintf(stderr, "_XEatData: Going to eat [%ld] bytes of data from descriptor [%d].\n",
- n, dpy->fd);
-#endif
- while (n > 0) {
- register long bytes_read = (n > SCRATCHSIZE) ? SCRATCHSIZE : n;
- (void) _XRead (dpy, buf, bytes_read);
- n -= bytes_read;
- }
-#undef SCRATCHSIZE
-}
-
-/*
- Port from libXfixes commit
- b031e3b60fa1af9e49449f23d4a84395868be3ab We need this here to
- enable linking of current libXrender against libNX_X11 instead of
- the system's libX11
-
- The original implementation of this function (libX11 commit
- 9f5d83706543696fc944c1835a403938c06f2cc5) uses xcb stuff which we
- do not have in libNX_X11. So we take a workaround from another
- lib. This workaround had been implemented temporarily in a couple
- of X libs, see e.g. https://lists.x.org/archives/xorg-devel/2013-July/036763.html.
-*/
-#include <nx-X11/Xmd.h> /* for LONG64 on 64-bit platforms */
-#include <limits.h>
-
-void _XEatDataWords(Display *dpy, unsigned long n)
-{
-#ifndef LONG64
- if (n >= (ULONG_MAX >> 2))
- _XIOError(dpy);
-#endif
- _XEatData (dpy, n << 2);
-}
-#endif /* !USE_XCB */
-
-/* Cookie jar implementation
- dpy->cookiejar is a linked list. _XEnq receives the events but leaves
- them in the normal EQ. _XStoreEvent returns the cookie event (minus
- data pointer) and adds it to the cookiejar. _XDeq just removes
- the entry like any other event but resets the data pointer for
- cookie events (to avoid double-free, the memory is re-used by Xlib).
-
- _XFetchEventCookie (called from XGetEventData) removes a cookie from the
- jar. _XFreeEventCookies removes all unclaimed cookies from the jar
- (called by XNextEvent).
-
- _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the
- normal EQ.
- */
-
-#include "utlist.h"
-struct stored_event {
- XGenericEventCookie ev;
- struct stored_event *prev;
- struct stored_event *next;
-};
-
-Bool
-_XIsEventCookie(Display *dpy, XEvent *ev)
-{
- return (ev->xcookie.type == GenericEvent &&
- dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL);
-}
-
-/**
- * Free all events in the event list.
- */
-void
-_XFreeEventCookies(Display *dpy)
-{
- struct stored_event **head, *e, *tmp;
-
- if (!dpy->cookiejar)
- return;
-
- head = (struct stored_event**)&dpy->cookiejar;
-
- DL_FOREACH_SAFE(*head, e, tmp) {
- if (dpy->cookiejar == e)
- dpy->cookiejar = NULL;
- XFree(e->ev.data);
- XFree(e);
- }
-}
-
-/**
- * Add an event to the display's event list. This event must be freed on the
- * next call to XNextEvent().
- */
-void
-_XStoreEventCookie(Display *dpy, XEvent *event)
-{
- XGenericEventCookie* cookie = &event->xcookie;
- struct stored_event **head, *add;
-
- if (!_XIsEventCookie(dpy, event))
- return;
-
- head = (struct stored_event**)(&dpy->cookiejar);
-
- add = Xmalloc(sizeof(struct stored_event));
- if (!add) {
- ESET(ENOMEM);
- _XIOError(dpy);
- }
- add->ev = *cookie;
- DL_APPEND(*head, add);
- cookie->data = NULL; /* don't return data yet, must be claimed */
-}
-
-/**
- * Return the event with the given cookie and remove it from the list.
- */
-Bool
-_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev)
-{
- Bool ret = False;
- struct stored_event **head, *event;
- head = (struct stored_event**)&dpy->cookiejar;
-
- if (!_XIsEventCookie(dpy, (XEvent*)ev))
- return ret;
-
- DL_FOREACH(*head, event) {
- if (event->ev.cookie == ev->cookie &&
- event->ev.extension == ev->extension &&
- event->ev.evtype == ev->evtype) {
- *ev = event->ev;
- DL_DELETE(*head, event);
- Xfree(event);
- ret = True;
- break;
- }
- }
-
- return ret;
-}
-
-Bool
-_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out)
-{
- Bool ret = False;
- int extension;
-
- if (!_XIsEventCookie(dpy, (XEvent*)in) || !out)
- return ret;
-
- extension = in->extension & 0x7F;
-
- if (!dpy->generic_event_copy_vec[extension])
- return ret;
-
- ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out));
- out->cookie = ret ? ++dpy->next_cookie : 0;
- return ret;
-}
-
-
-/*
- * _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(
- register Display *dpy,
- register xEvent *event)
-{
- register _XQEvent *qelt;
- int type, extension;
-
- if ((qelt = dpy->qfree)) {
- /* If dpy->qfree is non-NULL do this, else malloc a new one. */
- dpy->qfree = qelt->next;
- }
- else if ((qelt = Xmalloc(sizeof(_XQEvent))) == NULL) {
- /* Malloc call failed! */
- ESET(ENOMEM);
-#ifdef NX_TRANS_SOCKET
- _XIOError(dpy);
-
- return;
-#else
- _XIOError(dpy);
-#endif
- }
- qelt->next = NULL;
-
- type = event->u.u.type & 0177;
- extension = ((xGenericEvent*)event)->extension;
-
- qelt->event.type = type;
- /* If an extension has registered a generic_event_vec handler, then
- * it can handle event cookies. Otherwise, proceed with the normal
- * event handlers.
- *
- * If the generic_event_vec is called, qelt->event is a event cookie
- * with the data pointer and the "free" pointer set. Data pointer is
- * some memory allocated by the extension.
- */
- if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) {
- XGenericEventCookie *cookie = &qelt->event.xcookie;
- (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event);
- cookie->cookie = ++dpy->next_cookie;
-
- qelt->qserial_num = dpy->next_event_serial_num++;
- if (dpy->tail) dpy->tail->next = qelt;
- else dpy->head = qelt;
-
- dpy->tail = qelt;
- dpy->qlen++;
- } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) {
- qelt->qserial_num = dpy->next_event_serial_num++;
- 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 = dpy->qfree;
- dpy->qfree = qelt;
- }
-}
-
-/*
- * _XDeq - Remove event packet from the display's queue.
- */
-void _XDeq(
- register Display *dpy,
- register _XQEvent *prev, /* element before qelt */
- register _XQEvent *qelt) /* element to be unlinked */
-{
- if (prev) {
- if ((prev->next = qelt->next) == NULL)
- dpy->tail = prev;
- } else {
- /* no prev, so removing first elt */
- if ((dpy->head = qelt->next) == NULL)
- dpy->tail = NULL;
- }
- qelt->qserial_num = 0;
- qelt->next = dpy->qfree;
- dpy->qfree = qelt;
- dpy->qlen--;
-
- if (_XIsEventCookie(dpy, &qelt->event)) {
- XGenericEventCookie* cookie = &qelt->event.xcookie;
- /* dpy->qfree is re-used, reset memory to avoid double free on
- * _XFreeDisplayStructure */
- cookie->data = NULL;
- }
-}
-
-/*
- * EventToWire in separate file in that often not needed.
- */
-
-/*ARGSUSED*/
-Bool
-_XUnknownWireEvent(
- register Display *dpy, /* pointer to display structure */
- register XEvent *re, /* pointer to where event should be reformatted */
- register xEvent *event) /* wire protocol event */
-{
-#ifdef notdef
- (void) fprintf(stderr,
- "Xlib: unhandled wire event! event number = %d, display = %x\n.",
- event->u.u.type, dpy);
-#endif
- return(False);
-}
-
-Bool
-_XUnknownWireEventCookie(
- Display *dpy, /* pointer to display structure */
- XGenericEventCookie *re, /* pointer to where event should be reformatted */
- xEvent *event) /* wire protocol event */
-{
-#ifdef notdef
- fprintf(stderr,
- "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.",
- ((xGenericEvent*)event)->extension, dpy);
-#endif
- return(False);
-}
-
-Bool
-_XUnknownCopyEventCookie(
- Display *dpy, /* pointer to display structure */
- XGenericEventCookie *in, /* source */
- XGenericEventCookie *out) /* destination */
-{
-#ifdef notdef
- fprintf(stderr,
- "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.",
- in->extension, dpy);
-#endif
- return(False);
-}
-
-/*ARGSUSED*/
-Status
-_XUnknownNativeEvent(
- register Display *dpy, /* pointer to display structure */
- register XEvent *re, /* pointer to where event should be reformatted */
- register xEvent *event) /* wire protocol event */
-{
-#ifdef notdef
- (void) fprintf(stderr,
- "Xlib: unhandled native event! event number = %d, display = %x\n.",
- re->type, dpy);
-#endif
- return(0);
-}
-/*
- * reformat a wire event into an XEvent structure of the right type.
- */
-Bool
-_XWireToEvent(
- register Display *dpy, /* pointer to display structure */
- register XEvent *re, /* pointer to where event should be reformatted */
- register 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 = None;
- memcpy(&ev->key_vector[1],
- (char *)((xKeymapEvent *) event)->map,
- 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);
-}
-
-
-/*
- * _XDefaultIOError - Default fatal system error reporting routine. Called
- * when an X internal system error is encountered.
- */
-int _XDefaultIOError(
- Display *dpy)
-{
- if (ECHECK(EPIPE)) {
- (void) fprintf (stderr,
- "X connection to %s broken (explicit kill or server shutdown).\r\n",
- DisplayString (dpy));
- } else {
- (void) fprintf (stderr,
- "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n",
-#ifdef WIN32
- WSAGetLastError(), strerror(WSAGetLastError()),
-#else
- errno, strerror (errno),
-#endif
- DisplayString (dpy));
- (void) fprintf (stderr,
- " after %lu requests (%lu known processed) with %d events remaining.\r\n",
- NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy),
- QLength(dpy));
-
- }
-#ifdef NX_TRANS_SOCKET
- if (_NXHandleDisplayError == 1)
- {
-#ifdef NX_TRANS_TEST
- fprintf(stderr, "_XDefaultIOError: Going to return from the error handler.\n");
-#endif
- return 0;
- }
- else
- {
-#ifdef NX_TRANS_TEST
- fprintf(stderr, "_XDefaultIOError: Going to exit from the program.\n");
-#endif
-#ifdef NX_TRANS_EXIT
- NXTransExit(1);
-#else
- exit(1);
-#endif
- }
-#else
- exit(1);
-#endif /* #ifdef NX_TRANS_SOCKET */
- /*NOTREACHED*/
-}
-
-
-static int _XPrintDefaultError(
- Display *dpy,
- XErrorEvent *event,
- FILE *fp)
-{
- char buffer[BUFSIZ];
- char mesg[BUFSIZ];
- char number[32];
- const 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) {
- snprintf(number, sizeof(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) {
- strncpy(buffer, ext->name, BUFSIZ);
- buffer[BUFSIZ - 1] = '\0';
- } 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) {
- snprintf(mesg, sizeof(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 < (int)event->error_code &&
- (!bext || ext->codes.first_error > bext->codes.first_error))
- bext = ext;
- }
- if (bext)
- snprintf(buffer, sizeof(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;
-
- /*
- * Store in dpy flags that the client is exiting on an unhandled XError
- * (pretend it is an IOError, since the application is dying anyway it
- * does not make a difference).
- * This is useful for _XReply not to hang if the application makes Xlib
- * calls in _fini as part of process termination.
- */
- dpy->flags |= XlibDisplayIOError;
-
- exit(1);
- /*NOTREACHED*/
-}
-
-/*ARGSUSED*/
-Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we)
-{
- return True;
-}
-
-/*
- * _XError - upcall internal or user protocol error handler
- */
-int _XError (
- Display *dpy,
- register 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 */
- register _XAsyncHandler *async, *next;
-
- event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep);
-
- for (async = dpy->async_handlers; async; async = next) {
- next = async->next;
- if ((*async->handler)(dpy, (xReply *)rep,
- (char *)rep, SIZEOF(xError), async->data))
- return 0;
- }
-
- event.xerror.display = dpy;
- event.xerror.type = X_Error;
- 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) {
- int rtn_val;
-#if defined(XTHREADS) && !USE_XCB
- if (dpy->lock)
- (*dpy->lock->user_lock_display)(dpy);
- UnlockDisplay(dpy);
-#endif /* XTHREADS && !USE_XCB */
- rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */
-#if defined(XTHREADS) && !USE_XCB
- LockDisplay(dpy);
- if (dpy->lock)
- (*dpy->lock->user_unlock_display)(dpy);
-#endif /* XTHREADS && !USE_XCB */
- return rtn_val;
- } else {
- return _XDefaultError(dpy, (XErrorEvent *)&event);
- }
-}
-
-/*
- * _XIOError - call user connection error handler and exit
- */
-int
-_XIOError (
- Display *dpy)
-{
- dpy->flags |= XlibDisplayIOError;
-#ifdef WIN32
- errno = WSAGetLastError();
-#endif
-
- /* This assumes that the thread calling exit will call any atexit handlers.
- * If this does not hold, then an alternate solution would involve
- * registering an atexit handler to take over the lock, which would only
- * assume that the same thread calls all the atexit handlers. */
-#ifdef XTHREADS
- if (dpy->lock)
- (*dpy->lock->user_lock_display)(dpy);
-#endif
- UnlockDisplay(dpy);
-
- if (_XIOErrorFunction != NULL)
- (*_XIOErrorFunction)(dpy);
- else
- _XDefaultIOError(dpy);
-#ifdef NX_TRANS_SOCKET
- /*
- * Check if we are supposed to return in the case
- * of a display failure. The client which originated
- * the X operation will have to check the value of
- * the XlibDisplayIOError flag and handle appropria-
- * tely the display disconnection.
- */
-
- if (_NXHandleDisplayError == 0)
- {
-#ifdef NX_TRANS_EXIT
- NXTransExit(1);
-#else
- exit(1);
-#endif
- }
-
- /*
- * We are going to return. Reset the display
- * buffers. Further writes will be discarded.
- */
-
-#ifdef NX_TRANS_TEST
- fprintf(stderr, "_XIOError: Resetting the display buffer.\n");
-#endif
-
- dpy->bufptr = dpy->buffer;
- dpy->last_req = (char *) &_dummy_request;
-
-#ifdef NX_TRANS_TEST
- fprintf(stderr, "_XIOError: Resetting the display flags.\n");
-#endif
-
- dpy->flags &= ~XlibDisplayProcConni;
- dpy->flags &= ~XlibDisplayPrivSync;
- dpy->flags &= ~XlibDisplayReadEvents;
- dpy->flags &= ~XlibDisplayWriting;
- dpy->flags &= ~XlibDisplayReply;
- /* shut up the compiler by returning something */
- return 0;
-#else
- exit (1);
-#endif
- /*NOTREACHED*/
-}
-
-
-/*
- * This routine can be used to (cheaply) get some memory within a single
- * Xlib routine for scratch space. A single buffer is reused each time
- * if possible. To be MT safe, you can only call this between a call to
- * GetReq* and a call to Data* or _XSend*, or in a context when the thread
- * is guaranteed to not unlock the display.
- */
-char *_XAllocScratch(
- register Display *dpy,
- unsigned long nbytes)
-{
- if (nbytes > dpy->scratch_length) {
- Xfree (dpy->scratch_buffer);
- dpy->scratch_buffer = Xmalloc(nbytes);
- if (dpy->scratch_buffer)
- dpy->scratch_length = nbytes;
- else dpy->scratch_length = 0;
- }
- return (dpy->scratch_buffer);
-}
-
-/*
- * Scratch space allocator you can call any time, multiple times, and be
- * MT safe, but you must hand the buffer back with _XFreeTemp.
- */
-char *_XAllocTemp(
- register Display *dpy,
- unsigned long nbytes)
-{
- char *buf;
-
- buf = _XAllocScratch(dpy, nbytes);
- dpy->scratch_buffer = NULL;
- dpy->scratch_length = 0;
- return buf;
-}
-
-void _XFreeTemp(
- register Display *dpy,
- char *buf,
- unsigned long nbytes)
-{
-
- Xfree(dpy->scratch_buffer);
- dpy->scratch_buffer = buf;
- dpy->scratch_length = nbytes;
-}
-
-/*
- * 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);
-}
-
-int
-XFree (void *data)
-{
- Xfree (data);
- return 1;
-}
-
-#ifdef _XNEEDBCOPYFUNC
-void _Xbcopy(b1, b2, length)
- register char *b1, *b2;
- register length;
-{
- if (b1 < b2) {
- b2 += length;
- b1 += length;
- while (length--)
- *--b2 = *--b1;
- } else {
- while (length--)
- *b2++ = *b1++;
- }
-}
-#endif
-
-#ifdef DataRoutineIsProcedure
-void Data(
- Display *dpy,
- _Xconst char *data,
- long len)
-{
- if (dpy->bufptr + (len) <= dpy->bufmax) {
- memcpy(dpy->bufptr, data, (int)len);
- dpy->bufptr += ((len) + 3) & ~3;
- } else {
- _XSend(dpy, data, len);
- }
-}
-#endif /* DataRoutineIsProcedure */
-
-
-#ifdef LONG64
-int
-_XData32(
- Display *dpy,
- register _Xconst long *data,
- unsigned len)
-{
- register int *buf;
- register long i;
-
- while (len) {
- buf = (int *)dpy->bufptr;
- i = dpy->bufmax - (char *)buf;
- if (!i) {
- _XFlush(dpy);
- continue;
- }
- if (len < i)
- i = len;
- dpy->bufptr = (char *)buf + i;
- len -= i;
- i >>= 2;
- while (--i >= 0)
- *buf++ = *data++;
- }
- return 0;
-}
-#endif /* LONG64 */
-
-
-
-/* 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(SVR4)
-#define NEED_UTSNAME
-#include <sys/utsname.h>
-#else
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#endif
-
-/*
- * _XGetHostname - similar to gethostname but allows special processing.
- */
-int _XGetHostname (
- char *buf,
- int maxlen)
-{
- int len;
-
-#ifdef NEED_UTSNAME
- struct utsname name;
-
- if (maxlen <= 0 || buf == NULL)
- return 0;
-
- uname (&name);
- len = strlen (name.nodename);
- if (len >= maxlen) len = maxlen - 1;
- strncpy (buf, name.nodename, len);
- buf[len] = '\0';
-#else
- if (maxlen <= 0 || buf == NULL)
- return 0;
-
- buf[0] = '\0';
- (void) gethostname (buf, maxlen);
- buf [maxlen - 1] = '\0';
- len = strlen(buf);
-#endif /* NEED_UTSNAME */
- return len;
-}
-
-
-/*
- * _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 NULL;
- }
- for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */
- if (root == RootWindow (dpy, i)) {
- return ScreenOfDisplay (dpy, i);
- }
- }
- return NULL;
-}
-
-/*
- * WARNING: This implementation's pre-conditions and post-conditions
- * must remain compatible with the old macro-based implementations of
- * GetReq, GetReqExtra, GetResReq, and GetEmptyReq. The portions of the
- * Display structure affected by those macros are part of libX11's
- * ABI.
- */
-void *_XGetRequest(Display *dpy, CARD8 type, size_t len)
-{
- xReq *req;
-
- if (dpy->bufptr + len > dpy->bufmax)
- _XFlush(dpy);
- /* Request still too large, so do not allow it to overflow. */
- if (dpy->bufptr + len > dpy->bufmax) {
- fprintf(stderr,
- "Xlib: request %d length %zd would exceed buffer size.\n",
- type, len);
- /* Changes failure condition from overflow to NULL dereference. */
- return NULL;
- }
-
- if (len % 4)
- fprintf(stderr,
- "Xlib: request %d length %zd not a multiple of 4.\n",
- type, len);
-
- dpy->last_req = dpy->bufptr;
-
- req = (xReq*)dpy->bufptr;
- req->reqType = type;
- req->length = len / 4;
- dpy->bufptr += len;
- dpy->request++;
- return req;
-}
-
-#if defined(WIN32)
-
-/*
- * These functions are intended to be used internally to Xlib only.
- * These functions will always prefix the path with a DOS drive in the
- * form "<drive-letter>:". As such, these functions are only suitable
- * for use by Xlib function that supply a root-based path to some
- * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will
- * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir".
- */
-
-static int access_file (path, pathbuf, len_pathbuf, pathret)
- char* path;
- char* pathbuf;
- int len_pathbuf;
- char** pathret;
-{
- if (access (path, F_OK) == 0) {
- if (strlen (path) < len_pathbuf)
- *pathret = pathbuf;
- else
- *pathret = Xmalloc (strlen (path) + 1);
- if (*pathret) {
- strcpy (*pathret, path);
- return 1;
- }
- }
- return 0;
-}
-
-static int AccessFile (path, pathbuf, len_pathbuf, pathret)
- char* path;
- char* pathbuf;
- int len_pathbuf;
- char** pathret;
-{
- unsigned long drives;
- int i, len;
- char* drive;
- char buf[MAX_PATH];
- char* bufp;
-
- /* just try the "raw" name first and see if it works */
- if (access_file (path, pathbuf, len_pathbuf, pathret))
- return 1;
-
- /* try the places set in the environment */
- drive = getenv ("_XBASEDRIVE");
- if (!drive)
- drive = "C:";
- len = strlen (drive) + strlen (path);
- if (len < MAX_PATH) bufp = buf;
- else bufp = Xmalloc (len + 1);
- strcpy (bufp, drive);
- strcat (bufp, path);
- if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
- if (bufp != buf) Xfree (bufp);
- return 1;
- }
-
- /* one last place to look */
- drive = getenv ("HOMEDRIVE");
- if (drive) {
- len = strlen (drive) + strlen (path);
- if (len < MAX_PATH) bufp = buf;
- else bufp = Xmalloc (len + 1);
- strcpy (bufp, drive);
- strcat (bufp, path);
- if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
- if (bufp != buf) Xfree (bufp);
- return 1;
- }
- }
-
- /* tried everywhere else, go fishing */
-#define C_DRIVE ('C' - 'A')
-#define Z_DRIVE ('Z' - 'A')
- /* does OS/2 (with or with gcc-emx) have getdrives? */
- drives = _getdrives ();
- for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */
- if ((1 << i) & drives) {
- len = 2 + strlen (path);
- if (len < MAX_PATH) bufp = buf;
- else bufp = Xmalloc (len + 1);
- *bufp = 'A' + i;
- *(bufp + 1) = ':';
- *(bufp + 2) = '\0';
- strcat (bufp, path);
- if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
- if (bufp != buf) Xfree (bufp);
- return 1;
- }
- }
- }
- return 0;
-}
-
-int _XOpenFile(path, flags)
- _Xconst char* path;
- int flags;
-{
- char buf[MAX_PATH];
- char* bufp = NULL;
- int ret = -1;
- UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
-
- if (AccessFile (path, buf, MAX_PATH, &bufp))
- ret = open (bufp, flags);
-
- (void) SetErrorMode (olderror);
-
- if (bufp != buf) Xfree (bufp);
-
- return ret;
-}
-
-int _XOpenFileMode(path, flags, mode)
- _Xconst char* path;
- int flags;
- mode_t mode;
-{
- char buf[MAX_PATH];
- char* bufp = NULL;
- int ret = -1;
- UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
-
- if (AccessFile (path, buf, MAX_PATH, &bufp))
- ret = open (bufp, flags, mode);
-
- (void) SetErrorMode (olderror);
-
- if (bufp != buf) Xfree (bufp);
-
- return ret;
-}
-
-void* _XFopenFile(path, mode)
- _Xconst char* path;
- _Xconst char* mode;
-{
- char buf[MAX_PATH];
- char* bufp = NULL;
- void* ret = NULL;
- UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
-
- if (AccessFile (path, buf, MAX_PATH, &bufp))
- ret = fopen (bufp, mode);
-
- (void) SetErrorMode (olderror);
-
- if (bufp != buf) Xfree (bufp);
-
- return ret;
-}
-
-int _XAccessFile(path)
- _Xconst char* path;
-{
- char buf[MAX_PATH];
- char* bufp;
- int ret = -1;
- UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
-
- ret = AccessFile (path, buf, MAX_PATH, &bufp);
-
- (void) SetErrorMode (olderror);
-
- if (bufp != buf) Xfree (bufp);
-
- return ret;
-}
-
-#endif
-
-#ifdef WIN32
-#undef _Xdebug
-int _Xdebug = 0;
-int *_Xdebug_p = &_Xdebug;
-void (**_XCreateMutex_fn_p)(LockInfoPtr) = &_XCreateMutex_fn;
-void (**_XFreeMutex_fn_p)(LockInfoPtr) = &_XFreeMutex_fn;
-void (**_XLockMutex_fn_p)(LockInfoPtr
-#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
- , char * /* file */
- , int /* line */
-#endif
- ) = &_XLockMutex_fn;
-void (**_XUnlockMutex_fn_p)(LockInfoPtr
-#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
- , char * /* file */
- , int /* line */
-#endif
- ) = &_XUnlockMutex_fn;
-LockInfoPtr *_Xglobal_lock_p = &_Xglobal_lock;
-#endif