diff options
Diffstat (limited to 'nx-X11/lib/X11/XlibInt.c.X.original')
-rw-r--r-- | nx-X11/lib/X11/XlibInt.c.X.original | 3429 |
1 files changed, 0 insertions, 3429 deletions
diff --git a/nx-X11/lib/X11/XlibInt.c.X.original b/nx-X11/lib/X11/XlibInt.c.X.original deleted file mode 100644 index c042eb2e4..000000000 --- a/nx-X11/lib/X11/XlibInt.c.X.original +++ /dev/null @@ -1,3429 +0,0 @@ -/* $Xorg: XlibInt.c,v 1.8 2001/02/09 02:03:38 xorgcvs Exp $ */ -/* - -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. - -*/ -/* $XFree86: xc/lib/X11/XlibInt.c,v 3.38 2003/10/30 21:55:05 alanh Exp $ */ - -/* - * XlibInt.c - Internal support routines for the C subroutine - * interface library (Xlib) to the X Window System Protocol V11.0. - */ -#define NEED_EVENTS -#define NEED_REPLIES - -#ifdef WIN32 -#define _XLIBINT_ -#endif -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include <X11/Xpoll.h> -#include <X11/Xtrans/Xtrans.h> -#include <X11/extensions/xcmiscstr.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)()) - -#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) - -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) -#define InternalLockDisplay(d,wskip) if ((d)->lock) \ - (*(d)->lock->internal_lock_display)(d,wskip,__FILE__,__LINE__) -#else -#define InternalLockDisplay(d,wskip) if ((d)->lock) \ - (*(d)->lock->internal_lock_display)(d,wskip) -#endif - -#else /* XTHREADS else */ - -#define UnlockNextReplyReader(d) -#define UnlockNextEventReader(d) -#define InternalLockDisplay(d,wskip) - -#endif /* XTHREADS else */ - -/* 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 -#ifdef __UNIXOS2__ -#define ECHECK(err) (errno == err) -#define ESET(val) -#else -#ifdef ISC -#define ECHECK(err) ((errno == err) || ETEST()) -#else -#define ECHECK(err) (errno == err) -#endif -#define ESET(val) errno = val -#endif -#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 - -#ifdef __UNIXOS2__ -#define select(n,r,w,x,t) os2ClientSelect(n,r,w,x,t) -#include <limits.h> -#define MAX_PATH _POSIX_PATH_MAX -#endif - -#ifdef MUSTCOPY - -#define STARTITERATE(tpvar,type,start,endcond) \ - { register char *cpvar; \ - for (cpvar = (char *) (start); endcond; ) { \ - type dummy; memcpy ((char *) &dummy, cpvar, SIZEOF(type)); \ - tpvar = &dummy; -#define ITERPTR(tpvar) cpvar -#define RESETITERPTR(tpvar,type,start) cpvar = start -#define INCITERPTR(tpvar,type) cpvar += SIZEOF(type) -#define ENDITERATE }} - -#else - -#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 - -#endif /* MUSTCOPY */ - -typedef union { - xReply rep; - char buf[BUFSIZE]; -} _XAlignedBuffer; - -static char *_XAsyncReply( - Display *dpy, - register xReply *rep, - char *buf, - register int *lenp, - Bool discard); - -static void _XProcessInternalConnection( - Display *dpy, - struct _XConnectionInfo *conn_info); - -#define SEQLIMIT (65535 - (BUFSIZE / SIZEOF(xReq)) - 10) - -/* - * 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. - */ - -static xReq _dummy_request = { - 0, 0, 0 -}; - -/* - * 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 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 -#ifdef USE_POLL - filedes.events = POLLIN; - filedes.events |= POLLOUT; -#else - FD_SET(dpy->fd, &r_mask); - FD_SET(dpy->fd, &w_mask); -#endif - - do { - UnlockDisplay(dpy); -#ifdef USE_POLL - nfound = poll (&filedes, 1, -1); -#else - nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL); -#endif - InternalLockDisplay(dpy, cv != NULL); - if (nfound < 0 && !ECHECK(EINTR)) - _XIOError(dpy); - } while (nfound <= 0); - - if ( -#ifdef USE_POLL - filedes.revents & POLLIN -#else - FD_ISSET(dpy->fd, &r_mask) -#endif - ) - { - _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) - _XIOError(dpy); - 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; - } - } -} - - -#define POLLFD_CACHE_SIZE 5 - -/* initialize the struct array passed to poll() below */ -Bool _XPollfdCacheInit( - Display *dpy) -{ -#ifdef USE_POLL - struct pollfd *pfp; - - pfp = (struct pollfd *)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 -} - -/* 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 - -#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 - FD_ZERO(&r_mask); -#endif - 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 - UnlockDisplay(dpy); -#ifdef USE_POLL - result = poll(filedes, - (dpy->flags & XlibDisplayProcConni) ? 1 : 1+dpy->im_fd_length, - -1); -#else - result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL); -#endif - InternalLockDisplay(dpy, dpy->flags & XlibDisplayReply); - if (result == -1 && !ECHECK(EINTR)) _XIOError(dpy); - if (result <= 0) - continue; -#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; -} - -static -int _XSeqSyncFunction( - register Display *dpy) -{ - xGetInputFocusReply rep; - register xReq *req; - - LockDisplay(dpy); - if ((dpy->request - dpy->last_request_read) >= (BUFSIZE / SIZEOF(xReq))) { - GetEmptyReq(GetInputFocus, req); - (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); - } - /* could get XID handler while waiting for reply in MT env */ - if (dpy->synchandler == _XSeqSyncFunction) { - dpy->synchandler = dpy->savedsynchandler; - dpy->flags &= ~XlibDisplayPrivSync; - } - UnlockDisplay(dpy); - SyncHandle(); - return 0; -} - -#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; - - /* 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) - { - dpy->bufptr = dpy->buffer; - dpy->last_req = (char *)&_dummy_request; - return; - } - -#ifdef XTHREADS - while (dpy->flags & XlibDisplayWriting) { - 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) { - 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 - } else if (!ECHECK(EINTR)) { - /* Write failed! */ - /* errno set by write system call. */ - _XIOError(dpy); - } - } - dpy->last_req = (char *)&_dummy_request; - if ((dpy->request - dpy->last_request_read) >= SEQLIMIT && - !(dpy->flags & XlibDisplayPrivSync)) { - dpy->savedsynchandler = dpy->synchandler; - dpy->synchandler = _XSeqSyncFunction; - dpy->flags |= XlibDisplayPrivSync; - } - 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 (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 (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0) - _XIOError(dpy); -#ifdef XCONN_CHECK_FREQ - /* This is a crock, required because FIONREAD or equivalent is - * not guaranteed to detect a broken connection. - */ - if (!pend && !dpy->qlen && ++dpy->conn_checker >= XCONN_CHECK_FREQ) - { - 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 - filedes.fd = dpy->fd; - filedes.events = POLLIN; - if ((result = poll(&filedes, 1, 0))) -#else - 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) - _XIOError(dpy); - /* we should not get zero, if we do, force a read */ - if (!pend) - pend = SIZEOF(xReply); - } - else if (result < 0 && !ECHECK(EINTR)) - _XIOError(dpy); - } - } -#endif /* XCONN_CHECK_FREQ */ - if (!(len = pend)) { - /* _XFlush can enqueue events */ -#ifdef XTHREADS - if (cvl) -#endif - { - UnlockNextEventReader(dpy); - } - 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 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); - 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; - 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 */ - _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 ((dpy->flags & XlibDisplayIOError) || size == 0) - return 0; - ESET(0); - while ((bytes_read = _X11TransRead(dpy->trans_conn, data, (int)size)) - != size) { - - 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); - _XIOError(dpy); - } - - else /* bytes_read is less than 0; presumably -1 */ { - /* If it's a system call interrupt, it's not an error. */ - if (!ECHECK(EINTR)) - _XIOError(dpy); - } - } -#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; -} - -#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 */ - -#ifdef WORD64 - -/* - * XXX This is a *really* stupid way of doing this.... - * PACKBUFFERSIZE must be a multiple of 4. - */ - -#define PACKBUFFERSIZE 4096 - - -/* - * _XRead32 - Read bytes from the socket unpacking each 32 bits - * into a long (64 bits on a CRAY computer). - * - */ -static void _doXRead32( - register Display *dpy, - register long *data - register long size, - register char *packbuffer) -{ - long *lpack,*lp; - long mask32 = 0x00000000ffffffff; - long maskw, nwords, i, bits; - - _XReadPad (dpy, packbuffer, size); - - lp = data; - lpack = (long *) packbuffer; - nwords = size >> 2; - bits = 32; - - for(i=0;i<nwords;i++){ - maskw = mask32 << bits; - *lp++ = ( *lpack & maskw ) >> bits; - bits = bits ^32; - if(bits){ - lpack++; - } - } -} - -void _XRead32( - Display *dpy, - long *data, - long len) -{ - char packbuffer[PACKBUFFERSIZE]; - unsigned nunits = PACKBUFFERSIZE >> 2; - - for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { - _doXRead32 (dpy, data, PACKBUFFERSIZE, packbuffer); - } - if (len) _doXRead32 (dpy, data, len, packbuffer); -} - - - -/* - * _XRead16 - Read bytes from the socket unpacking each 16 bits - * into a long (64 bits on a CRAY computer). - * - */ -static _doXRead16( - register Display *dpy, - register short *data, - register long size, - char *packbuffer) -{ - long *lpack,*lp; - long mask16 = 0x000000000000ffff; - long maskw, nwords, i, bits; - - (void) _XRead(dpy,packbuffer,size); /* don't do a padded read... */ - - lp = (long *) data; - lpack = (long *) packbuffer; - nwords = size >> 1; /* number of 16 bit words to be unpacked */ - bits = 48; - for(i=0;i<nwords;i++){ - maskw = mask16 << bits; - *lp++ = ( *lpack & maskw ) >> bits; - bits -= 16; - if(bits < 0){ - lpack++; - bits = 48; - } - } -} - -void _XRead16( - Display *dpy, - short *data, - long len) -{ - char packbuffer[PACKBUFFERSIZE]; - unsigned nunits = PACKBUFFERSIZE >> 1; - - for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { - _doXRead16 (dpy, data, PACKBUFFERSIZE, packbuffer); - } - if (len) _doXRead16 (dpy, data, len, packbuffer); -} - -void _XRead16Pad( - Display *dpy, - short *data, - long size) -{ - int slop = (size & 3); - short slopbuf[3]; - - _XRead16 (dpy, data, size); - if (slop > 0) { - _XRead16 (dpy, slopbuf, 4 - slop); - } -} -#endif /* WORD64 */ - - -/* - * _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 ((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); - while ((bytes_read = _X11TransReadv (dpy->trans_conn, iov, 2)) != size) { - - 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); - _XIOError(dpy); - } - - else /* bytes_read is less than 0; presumably -1 */ { - /* If it's a system call interrupt, it's not an error. */ - if (!ECHECK(EINTR)) - _XIOError(dpy); - } - } -#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 (!size || (dpy->flags & XlibDisplayIOError)) return; - 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) { - 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 - } else if (!ECHECK(EINTR)) { - _XIOError(dpy); - } - } - dpy->last_req = (char *) & _dummy_request; - if ((dpy->request - dpy->last_request_read) >= SEQLIMIT && - !(dpy->flags & XlibDisplayPrivSync)) { - dpy->savedsynchandler = dpy->synchandler; - dpy->synchandler = _XSeqSyncFunction; - dpy->flags |= XlibDisplayPrivSync; - } - 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; - } -} - -static int -_XIDHandler( - register Display *dpy) -{ - xXCMiscGetXIDRangeReply grep; - register xXCMiscGetXIDRangeReq *greq; - - LockDisplay(dpy); - _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; - } - } - if (dpy->flags & XlibDisplayPrivSync) { - dpy->synchandler = dpy->savedsynchandler; - dpy->flags &= ~XlibDisplayPrivSync; - } - UnlockDisplay(dpy); - SyncHandle(); - return 0; -} - -/* - * _XAllocID - resource ID allocation routine. - */ -XID _XAllocID( - register Display *dpy) -{ - XID id; - - id = dpy->resource_id << dpy->resource_shift; - if (id >= dpy->resource_max) { - if (!(dpy->flags & XlibDisplayPrivSync)) { - dpy->savedsynchandler = dpy->synchandler; - dpy->flags |= XlibDisplayPrivSync; - } - dpy->synchandler = _XIDHandler; - 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) { - if (!(dpy->flags & XlibDisplayPrivSync)) { - dpy->savedsynchandler = dpy->synchandler; - dpy->flags |= XlibDisplayPrivSync; - } - dpy->synchandler = _XIDHandler; - dpy->resource_max = dpy->resource_mask + 1; - } - } - } - for (i = grep.count; i < count; i++) - ids[i] = XAllocID(dpy); -} - -/* - * 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) { - (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); -} - -/* - * _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 (dpy->flags & XlibDisplayIOError) - return 0; - -#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 - - _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 - - 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); - _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; - } - } -} - -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)) { - _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)) - { - _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; -} - -/* - * 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; - - new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo)); - if (!new_conni) - return 0; - new_conni->watch_data = (XPointer *)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; - - 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); - } - if (info_list->watch_data) - 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; - - LockDisplay(dpy); - count = 0; - for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) - count++; - fd_list = (int*) 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; -} - -static void _XProcessInternalConnection( - Display *dpy, - struct _XConnectionInfo *conn_info) -{ - dpy->flags |= XlibDisplayProcConni; -#ifdef XTHREADS - 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 */ - UnlockDisplay(dpy); - (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data); - LockDisplay(dpy); -#ifdef XTHREADS - if (dpy->lock) - xthread_clear_id(dpy->lock->conni_thread); -#endif /* XTHREADS */ - 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; - - 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; - - LockDisplay(dpy); - - /* allocate new watch data */ - for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { - wd_array = (XPointer *)Xrealloc((char *)info_list->watch_data, - (dpy->watcher_count + 1) * - sizeof(XPointer)); - if (!wd_array) { - UnlockDisplay(dpy); - return 0; - } - wd_array[dpy->watcher_count] = NULL; /* for cleanliness */ - } - - new_watcher = (struct _XConnWatchInfo*)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; - - 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 */ - - -/* Read and discard "n" 8-bit bytes of data */ - -void _XEatData( - Display *dpy, - register unsigned long n) -{ -#define SCRATCHSIZE 2048 - char buf[SCRATCHSIZE]; - - while (n > 0) { - register long bytes_read = (n > SCRATCHSIZE) ? SCRATCHSIZE : n; - (void) _XRead (dpy, buf, bytes_read); - n -= bytes_read; - } -#undef SCRATCHSIZE -} - - -/* - * _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; - - if ((qelt = dpy->qfree)) { - /* If dpy->qfree is non-NULL do this, else malloc a new one. */ - dpy->qfree = qelt->next; - } - else if ((qelt = - (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) { - /* Malloc call failed! */ - ESET(ENOMEM); - _XIOError(dpy); - } - qelt->next = NULL; - /* go call through display to find proper event reformatter */ - if ((*dpy->event_vec[event->u.u.type & 0177])(dpy, &qelt->event, event)) { - 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--; -} - -/* - * 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); -} - -/*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)); - - } - exit(1); - return(0); /* dummy - function should never return */ -} - - -static int _XPrintDefaultError( - Display *dpy, - XErrorEvent *event, - FILE *fp) -{ - char buffer[BUFSIZ]; - char mesg[BUFSIZ]; - char number[32]; - char *mtype = "XlibMessage"; - register _XExtension *ext = (_XExtension *)NULL; - _XExtension *bext = (_XExtension *)NULL; - XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); - XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); - (void) fprintf(fp, "%s: %s\n ", mesg, buffer); - XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", - mesg, BUFSIZ); - (void) fprintf(fp, mesg, event->request_code); - if (event->request_code < 128) { - sprintf(number, "%d", event->request_code); - XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); - } else { - for (ext = dpy->ext_procs; - ext && (ext->codes.major_opcode != event->request_code); - ext = ext->next) - ; - if (ext) - strcpy(buffer, ext->name); - else - buffer[0] = '\0'; - } - (void) fprintf(fp, " (%s)\n", buffer); - if (event->request_code >= 128) { - XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", - mesg, BUFSIZ); - fputs(" ", fp); - (void) fprintf(fp, mesg, event->minor_code); - if (ext) { - sprintf(mesg, "%s.%d", ext->name, event->minor_code); - XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); - (void) fprintf(fp, " (%s)", buffer); - } - fputs("\n", fp); - } - if (event->error_code >= 128) { - /* kludge, try to find the extension that caused it */ - buffer[0] = '\0'; - for (ext = dpy->ext_procs; ext; ext = ext->next) { - if (ext->error_string) - (*ext->error_string)(dpy, event->error_code, &ext->codes, - buffer, BUFSIZ); - if (buffer[0]) { - bext = ext; - break; - } - if (ext->codes.first_error && - ext->codes.first_error < (int)event->error_code && - (!bext || ext->codes.first_error > bext->codes.first_error)) - bext = ext; - } - if (bext) - sprintf(buffer, "%s.%d", bext->name, - event->error_code - bext->codes.first_error); - else - strcpy(buffer, "Value"); - XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); - if (mesg[0]) { - fputs(" ", fp); - (void) fprintf(fp, mesg, event->resourceid); - fputs("\n", fp); - } - /* let extensions try to print the values */ - for (ext = dpy->ext_procs; ext; ext = ext->next) { - if (ext->error_values) - (*ext->error_values)(dpy, event, fp); - } - } else if ((event->error_code == BadWindow) || - (event->error_code == BadPixmap) || - (event->error_code == BadCursor) || - (event->error_code == BadFont) || - (event->error_code == BadDrawable) || - (event->error_code == BadColor) || - (event->error_code == BadGC) || - (event->error_code == BadIDChoice) || - (event->error_code == BadValue) || - (event->error_code == BadAtom)) { - if (event->error_code == BadValue) - XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", - mesg, BUFSIZ); - else if (event->error_code == BadAtom) - XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", - mesg, BUFSIZ); - else - XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", - mesg, BUFSIZ); - fputs(" ", fp); - (void) fprintf(fp, mesg, event->resourceid); - fputs("\n", fp); - } - XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", - mesg, BUFSIZ); - fputs(" ", fp); - (void) fprintf(fp, mesg, event->serial); - XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", - mesg, BUFSIZ); - fputs("\n ", fp); - (void) fprintf(fp, mesg, dpy->request); - fputs("\n", fp); - if (event->error_code == BadImplementation) return 0; - return 1; -} - -int _XDefaultError( - Display *dpy, - XErrorEvent *event) -{ - if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0; - exit(1); - /*NOTREACHED*/ -} - -/*ARGSUSED*/ -Bool _XDefaultWireError(display, he, we) - 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; -#ifdef XTHREADS - if (dpy->lock) - (*dpy->lock->user_lock_display)(dpy); - UnlockDisplay(dpy); -#endif /* XTHREADS */ - rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ -#ifdef XTHREADS - LockDisplay(dpy); - if (dpy->lock) - (*dpy->lock->user_unlock_display)(dpy); -#endif /* XTHREADS */ - 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 - - if (_XIOErrorFunction != NULL) - (*_XIOErrorFunction)(dpy); - else - _XDefaultIOError(dpy); - exit (1); - return 0; -} - - -/* - * 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) { - if (dpy->scratch_buffer) Xfree (dpy->scratch_buffer); - if ((dpy->scratch_buffer = Xmalloc((unsigned) nbytes))) - dpy->scratch_length = nbytes; - else dpy->scratch_length = 0; - } - return (dpy->scratch_buffer); -} - -/* - * 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) -{ - if (dpy->scratch_buffer) - 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, - 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 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 */ - -#ifdef WORD64 - -/* - * XXX This is a *really* stupid way of doing this. It should just use - * dpy->bufptr directly, taking into account where in the word it is. - */ - -/* - * Data16 - Place 16 bit data in the buffer. - * - * "dpy" is a pointer to a Display. - * "data" is a pointer to the data. - * "len" is the length in bytes of the data. - */ - -static doData16( - register Display *dpy, - short *data, - unsigned len, - char *packbuffer) -{ - long *lp,*lpack; - long i, nwords,bits; - long mask16 = 0x000000000000ffff; - - lp = (long *)data; - lpack = (long *)packbuffer; - -/* nwords is the number of 16 bit values to be packed, - * the low order 16 bits of each word will be packed - * into 64 bit words - */ - nwords = len >> 1; - bits = 48; - - for(i=0;i<nwords;i++){ - if (bits == 48) *lpack = 0; - *lpack ^= (*lp & mask16) << bits; - bits -= 16 ; - lp++; - if(bits < 0){ - lpack++; - bits = 48; - } - } - Data(dpy, packbuffer, len); -} - -_XData16 ( - Display *dpy, - short *data, - unsigned len) -{ - char packbuffer[PACKBUFFERSIZE]; - unsigned nunits = PACKBUFFERSIZE >> 1; - - for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { - doData16 (dpy, data, PACKBUFFERSIZE, packbuffer); - } - if (len) doData16 (dpy, data, len, packbuffer); -} - -/* - * Data32 - Place 32 bit data in the buffer. - * - * "dpy" is a pointer to a Display. - * "data" is a pointer to the data. - * "len" is the length in bytes of the data. - */ - -static doData32( - register Display *dpy - long *data, - unsigned len, - char *packbuffer) -{ - long *lp,*lpack; - long i,bits,nwords; - long mask32 = 0x00000000ffffffff; - - lpack = (long *) packbuffer; - lp = data; - -/* nwords is the number of 32 bit values to be packed - * the low order 32 bits of each word will be packed - * into 64 bit words - */ - nwords = len >> 2; - bits = 32; - - for(i=0;i<nwords;i++){ - if (bits == 32) *lpack = 0; - *lpack ^= (*lp & mask32) << bits; - bits = bits ^32; - lp++; - if(bits) - lpack++; - } - Data(dpy, packbuffer, len); -} - -void _XData32( - Display *dpy, - long *data, - unsigned len, -{ - char packbuffer[PACKBUFFERSIZE]; - unsigned nunits = PACKBUFFERSIZE >> 2; - - for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { - doData32 (dpy, data, PACKBUFFERSIZE, packbuffer); - } - if (len) doData32 (dpy, data, len, packbuffer); -} - -#endif /* WORD64 */ - - -/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm. - * Otherwise, Xau will not be able to find your cookies in the Xauthority file. - * - * Note: POSIX says that the ``nodename'' member of utsname does _not_ have - * to have sufficient information for interfacing to the network, - * and so, you may be better off using gethostname (if it exists). - */ - -#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(USG) || defined(SVR4) -#define NEED_UTSNAME -#include <sys/utsname.h> -#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 (dpy, w) - Display *dpy; - Window w; -{ - register int i; - Window root; - int x, y; /* dummy variables */ - unsigned int width, height, bw, depth; /* dummy variables */ - - if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height, - &bw, &depth) == False) { - return None; - } - for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */ - if (root == RootWindow (dpy, i)) { - return ScreenOfDisplay (dpy, i); - } - } - return NULL; -} - - -#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"); -#ifdef __UNIXOS2__ - if (!drive) - drive = getenv ("X11ROOT"); -#endif - 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; - } - -#ifndef __UNIXOS2__ - /* 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; - } - } - } -#endif - 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; -} - -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 |