XlibInt.c revision c17aa6b1
11ab64890Smrg/* 21ab64890Smrg 31ab64890SmrgCopyright 1985, 1986, 1987, 1998 The Open Group 41ab64890Smrg 51ab64890SmrgPermission to use, copy, modify, distribute, and sell this software and its 61ab64890Smrgdocumentation for any purpose is hereby granted without fee, provided that 71ab64890Smrgthe above copyright notice appear in all copies and that both that 81ab64890Smrgcopyright notice and this permission notice appear in supporting 91ab64890Smrgdocumentation. 101ab64890Smrg 111ab64890SmrgThe above copyright notice and this permission notice shall be included 121ab64890Smrgin all copies or substantial portions of the Software. 131ab64890Smrg 141ab64890SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 151ab64890SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 161ab64890SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 171ab64890SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 181ab64890SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 191ab64890SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 201ab64890SmrgOTHER DEALINGS IN THE SOFTWARE. 211ab64890Smrg 221ab64890SmrgExcept as contained in this notice, the name of The Open Group shall 231ab64890Smrgnot be used in advertising or otherwise to promote the sale, use or 241ab64890Smrgother dealings in this Software without prior written authorization 251ab64890Smrgfrom The Open Group. 261ab64890Smrg 271ab64890Smrg*/ 281ab64890Smrg 291ab64890Smrg/* 301ab64890Smrg * XlibInt.c - Internal support routines for the C subroutine 311ab64890Smrg * interface library (Xlib) to the X Window System Protocol V11.0. 321ab64890Smrg */ 331ab64890Smrg 341ab64890Smrg#ifdef WIN32 351ab64890Smrg#define _XLIBINT_ 361ab64890Smrg#endif 371ab64890Smrg#ifdef HAVE_CONFIG_H 381ab64890Smrg#include <config.h> 391ab64890Smrg#endif 401ab64890Smrg#include "Xlibint.h" 4161b2299dSmrg#include "Xprivate.h" 421ab64890Smrg#include <X11/Xpoll.h> 4361b2299dSmrg#include <assert.h> 441ab64890Smrg#include <stdio.h> 451ab64890Smrg#ifdef WIN32 461ab64890Smrg#include <direct.h> 471ab64890Smrg#endif 481ab64890Smrg 491ab64890Smrg#ifdef XTHREADS 501ab64890Smrg#include "locking.h" 511ab64890Smrg 521ab64890Smrg/* these pointers get initialized by XInitThreads */ 531ab64890SmrgLockInfoPtr _Xglobal_lock = NULL; 541ab64890Smrgvoid (*_XCreateMutex_fn)(LockInfoPtr) = NULL; 551ab64890Smrg/* struct _XCVList *(*_XCreateCVL_fn)() = NULL; */ 561ab64890Smrgvoid (*_XFreeMutex_fn)(LockInfoPtr) = NULL; 571ab64890Smrgvoid (*_XLockMutex_fn)( 581ab64890Smrg LockInfoPtr /* lock */ 591ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 601ab64890Smrg , char * /* file */ 611ab64890Smrg , int /* line */ 621ab64890Smrg#endif 631ab64890Smrg ) = NULL; 641ab64890Smrgvoid (*_XUnlockMutex_fn)( 651ab64890Smrg LockInfoPtr /* lock */ 661ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 671ab64890Smrg , char * /* file */ 681ab64890Smrg , int /* line */ 691ab64890Smrg#endif 701ab64890Smrg ) = NULL; 711ab64890Smrgxthread_t (*_Xthread_self_fn)(void) = NULL; 721ab64890Smrg 731ab64890Smrg#define XThread_Self() ((*_Xthread_self_fn)()) 741ab64890Smrg 75295fb823Smrg#endif /* XTHREADS */ 761ab64890Smrg 771ab64890Smrg/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX 781ab64890Smrg * systems are broken and return EWOULDBLOCK when they should return EAGAIN 791ab64890Smrg */ 801ab64890Smrg#ifdef WIN32 811ab64890Smrg#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK) 821ab64890Smrg#else 831ab64890Smrg#ifdef __CYGWIN__ /* Cygwin uses ENOBUFS to signal socket is full */ 841ab64890Smrg#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) 851ab64890Smrg#else 861ab64890Smrg#if defined(EAGAIN) && defined(EWOULDBLOCK) 871ab64890Smrg#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK) 881ab64890Smrg#else 891ab64890Smrg#ifdef EAGAIN 901ab64890Smrg#define ETEST() (errno == EAGAIN) 911ab64890Smrg#else 921ab64890Smrg#define ETEST() (errno == EWOULDBLOCK) 931ab64890Smrg#endif /* EAGAIN */ 941ab64890Smrg#endif /* EAGAIN && EWOULDBLOCK */ 951ab64890Smrg#endif /* __CYGWIN__ */ 961ab64890Smrg#endif /* WIN32 */ 971ab64890Smrg 981ab64890Smrg#ifdef WIN32 991ab64890Smrg#define ECHECK(err) (WSAGetLastError() == err) 1001ab64890Smrg#define ESET(val) WSASetLastError(val) 1011ab64890Smrg#else 1021ab64890Smrg#ifdef __UNIXOS2__ 1031ab64890Smrg#define ECHECK(err) (errno == err) 1041ab64890Smrg#define ESET(val) 1051ab64890Smrg#else 1061ab64890Smrg#define ECHECK(err) (errno == err) 1071ab64890Smrg#define ESET(val) errno = val 1081ab64890Smrg#endif 1091ab64890Smrg#endif 1101ab64890Smrg 1111ab64890Smrg#if defined(LOCALCONN) || defined(LACHMAN) 1121ab64890Smrg#ifdef EMSGSIZE 1131ab64890Smrg#define ESZTEST() (ECHECK(EMSGSIZE) || ECHECK(ERANGE)) 1141ab64890Smrg#else 1151ab64890Smrg#define ESZTEST() ECHECK(ERANGE) 1161ab64890Smrg#endif 1171ab64890Smrg#else 1181ab64890Smrg#ifdef EMSGSIZE 1191ab64890Smrg#define ESZTEST() ECHECK(EMSGSIZE) 1201ab64890Smrg#endif 1211ab64890Smrg#endif 1221ab64890Smrg 1231ab64890Smrg#ifdef __UNIXOS2__ 1241ab64890Smrg#include <limits.h> 1251ab64890Smrg#define MAX_PATH _POSIX_PATH_MAX 1261ab64890Smrg#endif 1271ab64890Smrg 1281ab64890Smrg/* 1291ab64890Smrg * The following routines are internal routines used by Xlib for protocol 1301ab64890Smrg * packet transmission and reception. 1311ab64890Smrg * 1321ab64890Smrg * _XIOError(Display *) will be called if any sort of system call error occurs. 1331ab64890Smrg * This is assumed to be a fatal condition, i.e., XIOError should not return. 1341ab64890Smrg * 1351ab64890Smrg * _XError(Display *, xError *) will be called whenever an X_Error event is 1361ab64890Smrg * received. This is not assumed to be a fatal condition, i.e., it is 1371ab64890Smrg * acceptable for this procedure to return. However, XError should NOT 1381ab64890Smrg * perform any operations (directly or indirectly) on the DISPLAY. 1391ab64890Smrg * 1401ab64890Smrg * Routines declared with a return type of 'Status' return 0 on failure, 14161b2299dSmrg * and non 0 on success. Routines with no declared return type don't 1421ab64890Smrg * return anything. Whenever possible routines that create objects return 1431ab64890Smrg * the object they have created. 1441ab64890Smrg */ 1451ab64890Smrg 1461ab64890Smrg#define POLLFD_CACHE_SIZE 5 1471ab64890Smrg 1481ab64890Smrg/* initialize the struct array passed to poll() below */ 1491ab64890SmrgBool _XPollfdCacheInit( 1501ab64890Smrg Display *dpy) 1511ab64890Smrg{ 1521ab64890Smrg#ifdef USE_POLL 1531ab64890Smrg struct pollfd *pfp; 1541ab64890Smrg 1551ab64890Smrg pfp = (struct pollfd *)Xmalloc(POLLFD_CACHE_SIZE * sizeof(struct pollfd)); 1561ab64890Smrg if (!pfp) 1571ab64890Smrg return False; 1581ab64890Smrg pfp[0].fd = dpy->fd; 1591ab64890Smrg pfp[0].events = POLLIN; 1601ab64890Smrg 1611ab64890Smrg dpy->filedes = (XPointer)pfp; 1621ab64890Smrg#endif 1631ab64890Smrg return True; 1641ab64890Smrg} 1651ab64890Smrg 1661ab64890Smrgvoid _XPollfdCacheAdd( 1671ab64890Smrg Display *dpy, 1681ab64890Smrg int fd) 1691ab64890Smrg{ 1701ab64890Smrg#ifdef USE_POLL 1711ab64890Smrg struct pollfd *pfp = (struct pollfd *)dpy->filedes; 1721ab64890Smrg 1731ab64890Smrg if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { 1741ab64890Smrg pfp[dpy->im_fd_length].fd = fd; 1751ab64890Smrg pfp[dpy->im_fd_length].events = POLLIN; 1761ab64890Smrg } 1771ab64890Smrg#endif 1781ab64890Smrg} 1791ab64890Smrg 1801ab64890Smrg/* ARGSUSED */ 1811ab64890Smrgvoid _XPollfdCacheDel( 1821ab64890Smrg Display *dpy, 1831ab64890Smrg int fd) /* not used */ 1841ab64890Smrg{ 1851ab64890Smrg#ifdef USE_POLL 1861ab64890Smrg struct pollfd *pfp = (struct pollfd *)dpy->filedes; 1871ab64890Smrg struct _XConnectionInfo *conni; 1881ab64890Smrg 1891ab64890Smrg /* just recalculate whole list */ 1901ab64890Smrg if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { 1911ab64890Smrg int loc = 1; 1921ab64890Smrg for (conni = dpy->im_fd_info; conni; conni=conni->next) { 1931ab64890Smrg pfp[loc].fd = conni->fd; 1941ab64890Smrg pfp[loc].events = POLLIN; 1951ab64890Smrg loc++; 1961ab64890Smrg } 1971ab64890Smrg } 1981ab64890Smrg#endif 1991ab64890Smrg} 2001ab64890Smrg 20161b2299dSmrgstatic int sync_hazard(Display *dpy) 20261b2299dSmrg{ 20361b2299dSmrg unsigned long span = dpy->request - dpy->last_request_read; 20461b2299dSmrg unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10); 20561b2299dSmrg return span >= 65535 - hazard - 10; 20661b2299dSmrg} 20761b2299dSmrg 2081ab64890Smrgstatic 20988de56ccSmrgvoid sync_while_locked(Display *dpy) 21088de56ccSmrg{ 21188de56ccSmrg#ifdef XTHREADS 21288de56ccSmrg if (dpy->lock) 21388de56ccSmrg (*dpy->lock->user_lock_display)(dpy); 21488de56ccSmrg#endif 21588de56ccSmrg UnlockDisplay(dpy); 21688de56ccSmrg SyncHandle(); 21788de56ccSmrg InternalLockDisplay(dpy, /* don't skip user locks */ 0); 21888de56ccSmrg#ifdef XTHREADS 21988de56ccSmrg if (dpy->lock) 22088de56ccSmrg (*dpy->lock->user_unlock_display)(dpy); 22188de56ccSmrg#endif 22288de56ccSmrg} 22388de56ccSmrg 22488de56ccSmrgvoid _XSeqSyncFunction( 2251ab64890Smrg register Display *dpy) 2261ab64890Smrg{ 2271ab64890Smrg xGetInputFocusReply rep; 2281ab64890Smrg register xReq *req; 2291ab64890Smrg 23061b2299dSmrg if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) { 2311ab64890Smrg GetEmptyReq(GetInputFocus, req); 2321ab64890Smrg (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); 23388de56ccSmrg sync_while_locked(dpy); 23461b2299dSmrg } else if (sync_hazard(dpy)) 23561b2299dSmrg _XSetPrivSyncFunction(dpy); 2361ab64890Smrg} 2371ab64890Smrg 23888de56ccSmrg/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */ 23961b2299dSmrgstatic int 24061b2299dSmrg_XPrivSyncFunction (Display *dpy) 24161b2299dSmrg{ 242e0787e08Smrg#ifdef XTHREADS 24388de56ccSmrg assert(!dpy->lock_fns); 24488de56ccSmrg#endif 24561b2299dSmrg assert(dpy->synchandler == _XPrivSyncFunction); 24661b2299dSmrg assert((dpy->flags & XlibDisplayPrivSync) != 0); 24761b2299dSmrg dpy->synchandler = dpy->savedsynchandler; 24861b2299dSmrg dpy->savedsynchandler = NULL; 24961b2299dSmrg dpy->flags &= ~XlibDisplayPrivSync; 25088de56ccSmrg if(dpy->synchandler) 25188de56ccSmrg dpy->synchandler(dpy); 25261b2299dSmrg _XIDHandler(dpy); 25361b2299dSmrg _XSeqSyncFunction(dpy); 25461b2299dSmrg return 0; 25561b2299dSmrg} 25661b2299dSmrg 25761b2299dSmrgvoid _XSetPrivSyncFunction(Display *dpy) 2581ab64890Smrg{ 25988de56ccSmrg#ifdef XTHREADS 26088de56ccSmrg if (dpy->lock_fns) 26188de56ccSmrg return; 26288de56ccSmrg#endif 26361b2299dSmrg if (!(dpy->flags & XlibDisplayPrivSync)) { 2641ab64890Smrg dpy->savedsynchandler = dpy->synchandler; 26561b2299dSmrg dpy->synchandler = _XPrivSyncFunction; 2661ab64890Smrg dpy->flags |= XlibDisplayPrivSync; 2671ab64890Smrg } 2681ab64890Smrg} 2691ab64890Smrg 27061b2299dSmrgvoid _XSetSeqSyncFunction(Display *dpy) 27161b2299dSmrg{ 27261b2299dSmrg if (sync_hazard(dpy)) 27361b2299dSmrg _XSetPrivSyncFunction (dpy); 27461b2299dSmrg} 27561b2299dSmrg 2761ab64890Smrg#ifdef LONG64 2771ab64890Smrgvoid _XRead32( 2781ab64890Smrg Display *dpy, 2791ab64890Smrg register long *data, 2801ab64890Smrg long len) 2811ab64890Smrg{ 2821ab64890Smrg register int *buf; 2831ab64890Smrg register long i; 2841ab64890Smrg 2851ab64890Smrg if (len) { 2861ab64890Smrg (void) _XRead(dpy, (char *)data, len); 2871ab64890Smrg i = len >> 2; 2881ab64890Smrg buf = (int *)data + i; 2891ab64890Smrg data += i; 2901ab64890Smrg while (--i >= 0) 2911ab64890Smrg *--data = *--buf; 2921ab64890Smrg } 2931ab64890Smrg} 2941ab64890Smrg#endif /* LONG64 */ 2951ab64890Smrg 2961ab64890Smrg#ifdef WORD64 2971ab64890Smrg 2981ab64890Smrg/* 2991ab64890Smrg * XXX This is a *really* stupid way of doing this.... 3001ab64890Smrg * PACKBUFFERSIZE must be a multiple of 4. 3011ab64890Smrg */ 3021ab64890Smrg 3031ab64890Smrg#define PACKBUFFERSIZE 4096 3041ab64890Smrg 3051ab64890Smrg 3061ab64890Smrg/* 3071ab64890Smrg * _XRead32 - Read bytes from the socket unpacking each 32 bits 3081ab64890Smrg * into a long (64 bits on a CRAY computer). 30961b2299dSmrg * 3101ab64890Smrg */ 3111ab64890Smrgstatic void _doXRead32( 3121ab64890Smrg register Display *dpy, 3131ab64890Smrg register long *data 3141ab64890Smrg register long size, 3151ab64890Smrg register char *packbuffer) 3161ab64890Smrg{ 3171ab64890Smrg long *lpack,*lp; 3181ab64890Smrg long mask32 = 0x00000000ffffffff; 3191ab64890Smrg long maskw, nwords, i, bits; 3201ab64890Smrg 3211ab64890Smrg _XReadPad (dpy, packbuffer, size); 3221ab64890Smrg 3231ab64890Smrg lp = data; 3241ab64890Smrg lpack = (long *) packbuffer; 3251ab64890Smrg nwords = size >> 2; 3261ab64890Smrg bits = 32; 3271ab64890Smrg 3281ab64890Smrg for(i=0;i<nwords;i++){ 3291ab64890Smrg maskw = mask32 << bits; 3301ab64890Smrg *lp++ = ( *lpack & maskw ) >> bits; 3311ab64890Smrg bits = bits ^32; 3321ab64890Smrg if(bits){ 3331ab64890Smrg lpack++; 3341ab64890Smrg } 3351ab64890Smrg } 3361ab64890Smrg} 3371ab64890Smrg 3381ab64890Smrgvoid _XRead32( 3391ab64890Smrg Display *dpy, 3401ab64890Smrg long *data, 3411ab64890Smrg long len) 3421ab64890Smrg{ 3431ab64890Smrg char packbuffer[PACKBUFFERSIZE]; 3441ab64890Smrg unsigned nunits = PACKBUFFERSIZE >> 2; 3451ab64890Smrg 3461ab64890Smrg for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { 3471ab64890Smrg _doXRead32 (dpy, data, PACKBUFFERSIZE, packbuffer); 3481ab64890Smrg } 3491ab64890Smrg if (len) _doXRead32 (dpy, data, len, packbuffer); 3501ab64890Smrg} 3511ab64890Smrg 3521ab64890Smrg 3531ab64890Smrg 3541ab64890Smrg/* 3551ab64890Smrg * _XRead16 - Read bytes from the socket unpacking each 16 bits 3561ab64890Smrg * into a long (64 bits on a CRAY computer). 3571ab64890Smrg * 3581ab64890Smrg */ 3591ab64890Smrgstatic _doXRead16( 3601ab64890Smrg register Display *dpy, 3611ab64890Smrg register short *data, 3621ab64890Smrg register long size, 3631ab64890Smrg char *packbuffer) 3641ab64890Smrg{ 3651ab64890Smrg long *lpack,*lp; 3661ab64890Smrg long mask16 = 0x000000000000ffff; 3671ab64890Smrg long maskw, nwords, i, bits; 3681ab64890Smrg 3691ab64890Smrg (void) _XRead(dpy,packbuffer,size); /* don't do a padded read... */ 3701ab64890Smrg 3711ab64890Smrg lp = (long *) data; 3721ab64890Smrg lpack = (long *) packbuffer; 3731ab64890Smrg nwords = size >> 1; /* number of 16 bit words to be unpacked */ 3741ab64890Smrg bits = 48; 3751ab64890Smrg for(i=0;i<nwords;i++){ 3761ab64890Smrg maskw = mask16 << bits; 3771ab64890Smrg *lp++ = ( *lpack & maskw ) >> bits; 3781ab64890Smrg bits -= 16; 3791ab64890Smrg if(bits < 0){ 3801ab64890Smrg lpack++; 3811ab64890Smrg bits = 48; 3821ab64890Smrg } 3831ab64890Smrg } 3841ab64890Smrg} 3851ab64890Smrg 3861ab64890Smrgvoid _XRead16( 3871ab64890Smrg Display *dpy, 3881ab64890Smrg short *data, 3891ab64890Smrg long len) 3901ab64890Smrg{ 3911ab64890Smrg char packbuffer[PACKBUFFERSIZE]; 3921ab64890Smrg unsigned nunits = PACKBUFFERSIZE >> 1; 3931ab64890Smrg 3941ab64890Smrg for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { 3951ab64890Smrg _doXRead16 (dpy, data, PACKBUFFERSIZE, packbuffer); 3961ab64890Smrg } 3971ab64890Smrg if (len) _doXRead16 (dpy, data, len, packbuffer); 3981ab64890Smrg} 3991ab64890Smrg 4001ab64890Smrgvoid _XRead16Pad( 4011ab64890Smrg Display *dpy, 4021ab64890Smrg short *data, 4031ab64890Smrg long size) 4041ab64890Smrg{ 4051ab64890Smrg int slop = (size & 3); 4061ab64890Smrg short slopbuf[3]; 4071ab64890Smrg 4081ab64890Smrg _XRead16 (dpy, data, size); 4091ab64890Smrg if (slop > 0) { 4101ab64890Smrg _XRead16 (dpy, slopbuf, 4 - slop); 4111ab64890Smrg } 4121ab64890Smrg} 4131ab64890Smrg#endif /* WORD64 */ 4141ab64890Smrg 4151ab64890Smrg/* 4161ab64890Smrg * The hard part about this is that we only get 16 bits from a reply. 4171ab64890Smrg * We have three values that will march along, with the following invariant: 4181ab64890Smrg * dpy->last_request_read <= rep->sequenceNumber <= dpy->request 4191ab64890Smrg * We have to keep 4201ab64890Smrg * dpy->request - dpy->last_request_read < 2^16 4211ab64890Smrg * or else we won't know for sure what value to use in events. We do this 4221ab64890Smrg * by forcing syncs when we get close. 4231ab64890Smrg */ 4241ab64890Smrg 4251ab64890Smrgunsigned long 4261ab64890Smrg_XSetLastRequestRead( 4271ab64890Smrg register Display *dpy, 4281ab64890Smrg register xGenericReply *rep) 4291ab64890Smrg{ 4301ab64890Smrg register unsigned long newseq, lastseq; 4311ab64890Smrg 4321ab64890Smrg lastseq = dpy->last_request_read; 4331ab64890Smrg /* 4341ab64890Smrg * KeymapNotify has no sequence number, but is always guaranteed 4351ab64890Smrg * to immediately follow another event, except when generated via 4361ab64890Smrg * SendEvent (hmmm). 4371ab64890Smrg */ 4381ab64890Smrg if ((rep->type & 0x7f) == KeymapNotify) 4391ab64890Smrg return(lastseq); 4401ab64890Smrg 4411ab64890Smrg newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber; 4421ab64890Smrg 4431ab64890Smrg if (newseq < lastseq) { 4441ab64890Smrg newseq += 0x10000; 4451ab64890Smrg if (newseq > dpy->request) { 44661b2299dSmrg (void) fprintf (stderr, 4471ab64890Smrg "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n", 44861b2299dSmrg newseq, dpy->request, 4491ab64890Smrg (unsigned int) rep->type); 4501ab64890Smrg newseq -= 0x10000; 4511ab64890Smrg } 4521ab64890Smrg } 4531ab64890Smrg 4541ab64890Smrg dpy->last_request_read = newseq; 4551ab64890Smrg return(newseq); 4561ab64890Smrg} 4571ab64890Smrg 4581ab64890Smrg/* 4591ab64890Smrg * Support for internal connections, such as an IM might use. 4601ab64890Smrg * By Stephen Gildea, X Consortium, September 1993 4611ab64890Smrg */ 4621ab64890Smrg 4631ab64890Smrg/* _XRegisterInternalConnection 4641ab64890Smrg * Each IM (or Xlib extension) that opens a file descriptor that Xlib should 4651ab64890Smrg * include in its select/poll mask must call this function to register the 4661ab64890Smrg * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch 4671ab64890Smrg * will also be called. 4681ab64890Smrg * 4691ab64890Smrg * Whenever Xlib detects input available on fd, it will call callback 4701ab64890Smrg * with call_data to process it. If non-Xlib code calls select/poll 4711ab64890Smrg * and detects input available, it must call XProcessInternalConnection, 4721ab64890Smrg * which will call the associated callback. 4731ab64890Smrg * 4741ab64890Smrg * Non-Xlib code can learn about these additional fds by calling 4751ab64890Smrg * XInternalConnectionNumbers or, more typically, by registering 4761ab64890Smrg * a XConnectionWatchProc with XAddConnectionWatch 4771ab64890Smrg * to be called when fds are registered or unregistered. 4781ab64890Smrg * 4791ab64890Smrg * Returns True if registration succeeded, False if not, typically 4801ab64890Smrg * because could not allocate memory. 4811ab64890Smrg * Assumes Display locked when called. 4821ab64890Smrg */ 4831ab64890SmrgStatus 4841ab64890Smrg_XRegisterInternalConnection( 4851ab64890Smrg Display* dpy, 4861ab64890Smrg int fd, 4871ab64890Smrg _XInternalConnectionProc callback, 4881ab64890Smrg XPointer call_data 4891ab64890Smrg) 4901ab64890Smrg{ 4911ab64890Smrg struct _XConnectionInfo *new_conni, **iptr; 4921ab64890Smrg struct _XConnWatchInfo *watchers; 4931ab64890Smrg XPointer *wd; 4941ab64890Smrg 4951ab64890Smrg new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo)); 4961ab64890Smrg if (!new_conni) 4971ab64890Smrg return 0; 4981ab64890Smrg new_conni->watch_data = (XPointer *)Xmalloc(dpy->watcher_count * sizeof(XPointer)); 4991ab64890Smrg if (!new_conni->watch_data) { 5001ab64890Smrg Xfree(new_conni); 5011ab64890Smrg return 0; 5021ab64890Smrg } 5031ab64890Smrg new_conni->fd = fd; 5041ab64890Smrg new_conni->read_callback = callback; 5051ab64890Smrg new_conni->call_data = call_data; 5061ab64890Smrg new_conni->next = NULL; 5071ab64890Smrg /* link new structure onto end of list */ 5081ab64890Smrg for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next) 5091ab64890Smrg ; 5101ab64890Smrg *iptr = new_conni; 5111ab64890Smrg dpy->im_fd_length++; 5121ab64890Smrg _XPollfdCacheAdd(dpy, fd); 5131ab64890Smrg 5141ab64890Smrg for (watchers=dpy->conn_watchers, wd=new_conni->watch_data; 5151ab64890Smrg watchers; 5161ab64890Smrg watchers=watchers->next, wd++) { 5171ab64890Smrg *wd = NULL; /* for cleanliness */ 5181ab64890Smrg (*watchers->fn) (dpy, watchers->client_data, fd, True, wd); 5191ab64890Smrg } 5201ab64890Smrg 5211ab64890Smrg return 1; 5221ab64890Smrg} 5231ab64890Smrg 5241ab64890Smrg/* _XUnregisterInternalConnection 5251ab64890Smrg * Each IM (or Xlib extension) that closes a file descriptor previously 5261ab64890Smrg * registered with _XRegisterInternalConnection must call this function. 5271ab64890Smrg * Any XConnectionWatchProc registered by XAddConnectionWatch 5281ab64890Smrg * will also be called. 5291ab64890Smrg * 5301ab64890Smrg * Assumes Display locked when called. 5311ab64890Smrg */ 5321ab64890Smrgvoid 5331ab64890Smrg_XUnregisterInternalConnection( 5341ab64890Smrg Display* dpy, 5351ab64890Smrg int fd 5361ab64890Smrg) 5371ab64890Smrg{ 5381ab64890Smrg struct _XConnectionInfo *info_list, **prev; 5391ab64890Smrg struct _XConnWatchInfo *watch; 5401ab64890Smrg XPointer *wd; 5411ab64890Smrg 5421ab64890Smrg for (prev = &dpy->im_fd_info; (info_list = *prev); 5431ab64890Smrg prev = &info_list->next) { 5441ab64890Smrg if (info_list->fd == fd) { 5451ab64890Smrg *prev = info_list->next; 5461ab64890Smrg dpy->im_fd_length--; 5471ab64890Smrg for (watch=dpy->conn_watchers, wd=info_list->watch_data; 5481ab64890Smrg watch; 5491ab64890Smrg watch=watch->next, wd++) { 5501ab64890Smrg (*watch->fn) (dpy, watch->client_data, fd, False, wd); 5511ab64890Smrg } 5521ab64890Smrg if (info_list->watch_data) 5531ab64890Smrg Xfree (info_list->watch_data); 5541ab64890Smrg Xfree (info_list); 5551ab64890Smrg break; 5561ab64890Smrg } 5571ab64890Smrg } 5581ab64890Smrg _XPollfdCacheDel(dpy, fd); 5591ab64890Smrg} 5601ab64890Smrg 5611ab64890Smrg/* XInternalConnectionNumbers 5621ab64890Smrg * Returns an array of fds and an array of corresponding call data. 5631ab64890Smrg * Typically a XConnectionWatchProc registered with XAddConnectionWatch 5641ab64890Smrg * will be used instead of this function to discover 5651ab64890Smrg * additional fds to include in the select/poll mask. 5661ab64890Smrg * 5671ab64890Smrg * The list is allocated with Xmalloc and should be freed by the caller 5681ab64890Smrg * with Xfree; 5691ab64890Smrg */ 5701ab64890SmrgStatus 5711ab64890SmrgXInternalConnectionNumbers( 5721ab64890Smrg Display *dpy, 5731ab64890Smrg int **fd_return, 5741ab64890Smrg int *count_return 5751ab64890Smrg) 5761ab64890Smrg{ 5771ab64890Smrg int count; 5781ab64890Smrg struct _XConnectionInfo *info_list; 5791ab64890Smrg int *fd_list; 5801ab64890Smrg 5811ab64890Smrg LockDisplay(dpy); 5821ab64890Smrg count = 0; 5831ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) 5841ab64890Smrg count++; 5851ab64890Smrg fd_list = (int*) Xmalloc (count * sizeof(int)); 5861ab64890Smrg if (!fd_list) { 5871ab64890Smrg UnlockDisplay(dpy); 5881ab64890Smrg return 0; 5891ab64890Smrg } 5901ab64890Smrg count = 0; 5911ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 5921ab64890Smrg fd_list[count] = info_list->fd; 5931ab64890Smrg count++; 5941ab64890Smrg } 5951ab64890Smrg UnlockDisplay(dpy); 5961ab64890Smrg 5971ab64890Smrg *fd_return = fd_list; 5981ab64890Smrg *count_return = count; 5991ab64890Smrg return 1; 6001ab64890Smrg} 6011ab64890Smrg 6021ab64890Smrgvoid _XProcessInternalConnection( 6031ab64890Smrg Display *dpy, 6041ab64890Smrg struct _XConnectionInfo *conn_info) 6051ab64890Smrg{ 6061ab64890Smrg dpy->flags |= XlibDisplayProcConni; 6071ab64890Smrg UnlockDisplay(dpy); 6081ab64890Smrg (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data); 6091ab64890Smrg LockDisplay(dpy); 6101ab64890Smrg dpy->flags &= ~XlibDisplayProcConni; 6111ab64890Smrg} 6121ab64890Smrg 6131ab64890Smrg/* XProcessInternalConnection 6141ab64890Smrg * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection 6151ab64890Smrg * for this fd. 6161ab64890Smrg * The Display is NOT locked during the call. 6171ab64890Smrg */ 6181ab64890Smrgvoid 6191ab64890SmrgXProcessInternalConnection( 6201ab64890Smrg Display* dpy, 6211ab64890Smrg int fd 6221ab64890Smrg) 6231ab64890Smrg{ 6241ab64890Smrg struct _XConnectionInfo *info_list; 6251ab64890Smrg 6261ab64890Smrg LockDisplay(dpy); 6271ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 6281ab64890Smrg if (info_list->fd == fd) { 6291ab64890Smrg _XProcessInternalConnection(dpy, info_list); 6301ab64890Smrg break; 6311ab64890Smrg } 6321ab64890Smrg } 6331ab64890Smrg UnlockDisplay(dpy); 6341ab64890Smrg} 6351ab64890Smrg 6361ab64890Smrg/* XAddConnectionWatch 6371ab64890Smrg * Register a callback to be called whenever _XRegisterInternalConnection 6381ab64890Smrg * or _XUnregisterInternalConnection is called. 6391ab64890Smrg * Callbacks are called with the Display locked. 6401ab64890Smrg * If any connections are already registered, the callback is immediately 6411ab64890Smrg * called for each of them. 6421ab64890Smrg */ 6431ab64890SmrgStatus 6441ab64890SmrgXAddConnectionWatch( 6451ab64890Smrg Display* dpy, 6461ab64890Smrg XConnectionWatchProc callback, 6471ab64890Smrg XPointer client_data 6481ab64890Smrg) 6491ab64890Smrg{ 6501ab64890Smrg struct _XConnWatchInfo *new_watcher, **wptr; 6511ab64890Smrg struct _XConnectionInfo *info_list; 6521ab64890Smrg XPointer *wd_array; 6531ab64890Smrg 6541ab64890Smrg LockDisplay(dpy); 6551ab64890Smrg 6561ab64890Smrg /* allocate new watch data */ 6571ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 6581ab64890Smrg wd_array = (XPointer *)Xrealloc((char *)info_list->watch_data, 6591ab64890Smrg (dpy->watcher_count + 1) * 6601ab64890Smrg sizeof(XPointer)); 6611ab64890Smrg if (!wd_array) { 6621ab64890Smrg UnlockDisplay(dpy); 6631ab64890Smrg return 0; 6641ab64890Smrg } 665c17aa6b1Smrg info_list->watch_data = wd_array; 6661ab64890Smrg wd_array[dpy->watcher_count] = NULL; /* for cleanliness */ 6671ab64890Smrg } 6681ab64890Smrg 6691ab64890Smrg new_watcher = (struct _XConnWatchInfo*)Xmalloc(sizeof(struct _XConnWatchInfo)); 6701ab64890Smrg if (!new_watcher) { 6711ab64890Smrg UnlockDisplay(dpy); 6721ab64890Smrg return 0; 6731ab64890Smrg } 6741ab64890Smrg new_watcher->fn = callback; 6751ab64890Smrg new_watcher->client_data = client_data; 6761ab64890Smrg new_watcher->next = NULL; 6771ab64890Smrg 6781ab64890Smrg /* link new structure onto end of list */ 6791ab64890Smrg for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next) 6801ab64890Smrg ; 6811ab64890Smrg *wptr = new_watcher; 6821ab64890Smrg dpy->watcher_count++; 6831ab64890Smrg 6841ab64890Smrg /* call new watcher on all currently registered fds */ 6851ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 6861ab64890Smrg (*callback) (dpy, client_data, info_list->fd, True, 6871ab64890Smrg info_list->watch_data + dpy->watcher_count - 1); 6881ab64890Smrg } 6891ab64890Smrg 6901ab64890Smrg UnlockDisplay(dpy); 6911ab64890Smrg return 1; 6921ab64890Smrg} 6931ab64890Smrg 6941ab64890Smrg/* XRemoveConnectionWatch 6951ab64890Smrg * Unregister a callback registered by XAddConnectionWatch. 6961ab64890Smrg * Both callback and client_data must match what was passed to 6971ab64890Smrg * XAddConnectionWatch. 69861b2299dSmrg */ 6991ab64890Smrgvoid 7001ab64890SmrgXRemoveConnectionWatch( 7011ab64890Smrg Display* dpy, 7021ab64890Smrg XConnectionWatchProc callback, 7031ab64890Smrg XPointer client_data 7041ab64890Smrg) 7051ab64890Smrg{ 7061ab64890Smrg struct _XConnWatchInfo *watch; 7071ab64890Smrg struct _XConnWatchInfo *previous = NULL; 7081ab64890Smrg struct _XConnectionInfo *conni; 7091ab64890Smrg int counter = 0; 7101ab64890Smrg 7111ab64890Smrg LockDisplay(dpy); 7121ab64890Smrg for (watch=dpy->conn_watchers; watch; watch=watch->next) { 7131ab64890Smrg if (watch->fn == callback && watch->client_data == client_data) { 7141ab64890Smrg if (previous) 7151ab64890Smrg previous->next = watch->next; 7161ab64890Smrg else 7171ab64890Smrg dpy->conn_watchers = watch->next; 7181ab64890Smrg Xfree (watch); 7191ab64890Smrg dpy->watcher_count--; 7201ab64890Smrg /* remove our watch_data for each connection */ 7211ab64890Smrg for (conni=dpy->im_fd_info; conni; conni=conni->next) { 7221ab64890Smrg /* don't bother realloc'ing; these arrays are small anyway */ 7231ab64890Smrg /* overlapping */ 7241ab64890Smrg memmove(conni->watch_data+counter, 7251ab64890Smrg conni->watch_data+counter+1, 7261ab64890Smrg dpy->watcher_count - counter); 7271ab64890Smrg } 7281ab64890Smrg break; 7291ab64890Smrg } 7301ab64890Smrg previous = watch; 7311ab64890Smrg counter++; 7321ab64890Smrg } 7331ab64890Smrg UnlockDisplay(dpy); 7341ab64890Smrg} 7351ab64890Smrg 7361ab64890Smrg/* end of internal connections support */ 7371ab64890Smrg 738b4ee4795Smrg/* Cookie jar implementation 739b4ee4795Smrg dpy->cookiejar is a linked list. _XEnq receives the events but leaves 740b4ee4795Smrg them in the normal EQ. _XStoreEvent returns the cookie event (minus 741b4ee4795Smrg data pointer) and adds it to the cookiejar. _XDeq just removes 742b4ee4795Smrg the entry like any other event but resets the data pointer for 743b4ee4795Smrg cookie events (to avoid double-free, the memory is re-used by Xlib). 744b4ee4795Smrg 745b4ee4795Smrg _XFetchEventCookie (called from XGetEventData) removes a cookie from the 746b4ee4795Smrg jar. _XFreeEventCookies removes all unclaimed cookies from the jar 747b4ee4795Smrg (called by XNextEvent). 748b4ee4795Smrg 749b4ee4795Smrg _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the 750b4ee4795Smrg normal EQ. 751b4ee4795Smrg */ 752b4ee4795Smrg 753b4ee4795Smrg#include "utlist.h" 754b4ee4795Smrgstruct stored_event { 755b4ee4795Smrg XGenericEventCookie ev; 756b4ee4795Smrg struct stored_event *prev; 757b4ee4795Smrg struct stored_event *next; 758b4ee4795Smrg}; 759b4ee4795Smrg 760b4ee4795SmrgBool 761b4ee4795Smrg_XIsEventCookie(Display *dpy, XEvent *ev) 762b4ee4795Smrg{ 763b4ee4795Smrg return (ev->xcookie.type == GenericEvent && 764b4ee4795Smrg dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL); 765b4ee4795Smrg} 766b4ee4795Smrg 767b4ee4795Smrg/** 768b4ee4795Smrg * Free all events in the event list. 769b4ee4795Smrg */ 770b4ee4795Smrgvoid 771b4ee4795Smrg_XFreeEventCookies(Display *dpy) 772b4ee4795Smrg{ 773b4ee4795Smrg struct stored_event **head, *e, *tmp; 774b4ee4795Smrg 775b4ee4795Smrg if (!dpy->cookiejar) 776b4ee4795Smrg return; 777b4ee4795Smrg 778b4ee4795Smrg head = (struct stored_event**)&dpy->cookiejar; 779b4ee4795Smrg 780b4ee4795Smrg DL_FOREACH_SAFE(*head, e, tmp) { 781b4ee4795Smrg if (dpy->cookiejar == e) 782b4ee4795Smrg dpy->cookiejar = NULL; 783c17aa6b1Smrg XFree(e->ev.data); 784c17aa6b1Smrg XFree(e); 785b4ee4795Smrg } 786b4ee4795Smrg} 787b4ee4795Smrg 788b4ee4795Smrg/** 789b4ee4795Smrg * Add an event to the display's event list. This event must be freed on the 790b4ee4795Smrg * next call to XNextEvent(). 791b4ee4795Smrg */ 792b4ee4795Smrgvoid 793b4ee4795Smrg_XStoreEventCookie(Display *dpy, XEvent *event) 794b4ee4795Smrg{ 795b4ee4795Smrg XGenericEventCookie* cookie = &event->xcookie; 796b4ee4795Smrg struct stored_event **head, *add; 797b4ee4795Smrg 798b4ee4795Smrg if (!_XIsEventCookie(dpy, event)) 799b4ee4795Smrg return; 800b4ee4795Smrg 801b4ee4795Smrg head = (struct stored_event**)(&dpy->cookiejar); 802b4ee4795Smrg 803b4ee4795Smrg add = Xmalloc(sizeof(struct stored_event)); 804b4ee4795Smrg if (!add) { 805b4ee4795Smrg ESET(ENOMEM); 806b4ee4795Smrg _XIOError(dpy); 807b4ee4795Smrg } 808b4ee4795Smrg add->ev = *cookie; 809b4ee4795Smrg DL_APPEND(*head, add); 810b4ee4795Smrg cookie->data = NULL; /* don't return data yet, must be claimed */ 811b4ee4795Smrg} 812b4ee4795Smrg 813b4ee4795Smrg/** 814b4ee4795Smrg * Return the event with the given cookie and remove it from the list. 815b4ee4795Smrg */ 816b4ee4795SmrgBool 817b4ee4795Smrg_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev) 818b4ee4795Smrg{ 819b4ee4795Smrg Bool ret = False; 820b4ee4795Smrg struct stored_event **head, *event; 821b4ee4795Smrg head = (struct stored_event**)&dpy->cookiejar; 822b4ee4795Smrg 823b4ee4795Smrg if (!_XIsEventCookie(dpy, (XEvent*)ev)) 824b4ee4795Smrg return ret; 825b4ee4795Smrg 826b4ee4795Smrg DL_FOREACH(*head, event) { 827b4ee4795Smrg if (event->ev.cookie == ev->cookie && 828b4ee4795Smrg event->ev.extension == ev->extension && 829b4ee4795Smrg event->ev.evtype == ev->evtype) { 830b4ee4795Smrg *ev = event->ev; 831b4ee4795Smrg DL_DELETE(*head, event); 832b4ee4795Smrg Xfree(event); 833b4ee4795Smrg ret = True; 834b4ee4795Smrg break; 835b4ee4795Smrg } 836b4ee4795Smrg } 837b4ee4795Smrg 838b4ee4795Smrg return ret; 839b4ee4795Smrg} 840b4ee4795Smrg 841b4ee4795SmrgBool 842b4ee4795Smrg_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out) 843b4ee4795Smrg{ 844b4ee4795Smrg Bool ret = False; 845b4ee4795Smrg int extension; 846b4ee4795Smrg 847b4ee4795Smrg if (!_XIsEventCookie(dpy, (XEvent*)in) || !out) 848b4ee4795Smrg return ret; 849b4ee4795Smrg 850b4ee4795Smrg extension = in->extension & 0x7F; 851b4ee4795Smrg 852b4ee4795Smrg if (!dpy->generic_event_copy_vec[extension]) 853b4ee4795Smrg return ret; 854b4ee4795Smrg 855b4ee4795Smrg ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out)); 856b4ee4795Smrg out->cookie = ret ? ++dpy->next_cookie : 0; 857b4ee4795Smrg return ret; 858b4ee4795Smrg} 859b4ee4795Smrg 8601ab64890Smrg 8611ab64890Smrg/* 8621ab64890Smrg * _XEnq - Place event packets on the display's queue. 8631ab64890Smrg * note that no squishing of move events in V11, since there 8641ab64890Smrg * is pointer motion hints.... 8651ab64890Smrg */ 8661ab64890Smrgvoid _XEnq( 8671ab64890Smrg register Display *dpy, 8681ab64890Smrg register xEvent *event) 8691ab64890Smrg{ 8701ab64890Smrg register _XQEvent *qelt; 871b4ee4795Smrg int type, extension; 8721ab64890Smrg 8731ab64890Smrg if ((qelt = dpy->qfree)) { 8741ab64890Smrg /* If dpy->qfree is non-NULL do this, else malloc a new one. */ 8751ab64890Smrg dpy->qfree = qelt->next; 8761ab64890Smrg } 87761b2299dSmrg else if ((qelt = 8781ab64890Smrg (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) { 8791ab64890Smrg /* Malloc call failed! */ 8801ab64890Smrg ESET(ENOMEM); 8811ab64890Smrg _XIOError(dpy); 8821ab64890Smrg } 8831ab64890Smrg qelt->next = NULL; 884b4ee4795Smrg 885b4ee4795Smrg type = event->u.u.type & 0177; 886b4ee4795Smrg extension = ((xGenericEvent*)event)->extension; 887295fb823Smrg 888295fb823Smrg qelt->event.type = type; 889b4ee4795Smrg /* If an extension has registerd a generic_event_vec handler, then 890b4ee4795Smrg * it can handle event cookies. Otherwise, proceed with the normal 891b4ee4795Smrg * event handlers. 892b4ee4795Smrg * 893b4ee4795Smrg * If the generic_event_vec is called, qelt->event is a event cookie 894b4ee4795Smrg * with the data pointer and the "free" pointer set. Data pointer is 895b4ee4795Smrg * some memory allocated by the extension. 896b4ee4795Smrg */ 897b4ee4795Smrg if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) { 898b4ee4795Smrg XGenericEventCookie *cookie = &qelt->event.xcookie; 899b4ee4795Smrg (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event); 900b4ee4795Smrg cookie->cookie = ++dpy->next_cookie; 901b4ee4795Smrg 902b4ee4795Smrg qelt->qserial_num = dpy->next_event_serial_num++; 903b4ee4795Smrg if (dpy->tail) dpy->tail->next = qelt; 904b4ee4795Smrg else dpy->head = qelt; 905b4ee4795Smrg 906b4ee4795Smrg dpy->tail = qelt; 907b4ee4795Smrg dpy->qlen++; 908b4ee4795Smrg } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) { 9091ab64890Smrg qelt->qserial_num = dpy->next_event_serial_num++; 9101ab64890Smrg if (dpy->tail) dpy->tail->next = qelt; 9111ab64890Smrg else dpy->head = qelt; 91261b2299dSmrg 9131ab64890Smrg dpy->tail = qelt; 9141ab64890Smrg dpy->qlen++; 9151ab64890Smrg } else { 9161ab64890Smrg /* ignored, or stashed away for many-to-one compression */ 9171ab64890Smrg qelt->next = dpy->qfree; 9181ab64890Smrg dpy->qfree = qelt; 9191ab64890Smrg } 9201ab64890Smrg} 9211ab64890Smrg 9221ab64890Smrg/* 9231ab64890Smrg * _XDeq - Remove event packet from the display's queue. 9241ab64890Smrg */ 9251ab64890Smrgvoid _XDeq( 9261ab64890Smrg register Display *dpy, 9271ab64890Smrg register _XQEvent *prev, /* element before qelt */ 9281ab64890Smrg register _XQEvent *qelt) /* element to be unlinked */ 9291ab64890Smrg{ 9301ab64890Smrg if (prev) { 9311ab64890Smrg if ((prev->next = qelt->next) == NULL) 9321ab64890Smrg dpy->tail = prev; 9331ab64890Smrg } else { 9341ab64890Smrg /* no prev, so removing first elt */ 9351ab64890Smrg if ((dpy->head = qelt->next) == NULL) 9361ab64890Smrg dpy->tail = NULL; 9371ab64890Smrg } 9381ab64890Smrg qelt->qserial_num = 0; 9391ab64890Smrg qelt->next = dpy->qfree; 9401ab64890Smrg dpy->qfree = qelt; 9411ab64890Smrg dpy->qlen--; 942b4ee4795Smrg 943b4ee4795Smrg if (_XIsEventCookie(dpy, &qelt->event)) { 944b4ee4795Smrg XGenericEventCookie* cookie = &qelt->event.xcookie; 945b4ee4795Smrg /* dpy->qfree is re-used, reset memory to avoid double free on 946b4ee4795Smrg * _XFreeDisplayStructure */ 947b4ee4795Smrg cookie->data = NULL; 948b4ee4795Smrg } 9491ab64890Smrg} 9501ab64890Smrg 9511ab64890Smrg/* 9521ab64890Smrg * EventToWire in separate file in that often not needed. 9531ab64890Smrg */ 9541ab64890Smrg 9551ab64890Smrg/*ARGSUSED*/ 9561ab64890SmrgBool 9571ab64890Smrg_XUnknownWireEvent( 9581ab64890Smrg register Display *dpy, /* pointer to display structure */ 9591ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 9601ab64890Smrg register xEvent *event) /* wire protocol event */ 9611ab64890Smrg{ 9621ab64890Smrg#ifdef notdef 96361b2299dSmrg (void) fprintf(stderr, 9641ab64890Smrg "Xlib: unhandled wire event! event number = %d, display = %x\n.", 9651ab64890Smrg event->u.u.type, dpy); 9661ab64890Smrg#endif 9671ab64890Smrg return(False); 9681ab64890Smrg} 9691ab64890Smrg 970b4ee4795SmrgBool 971b4ee4795Smrg_XUnknownWireEventCookie( 972b4ee4795Smrg Display *dpy, /* pointer to display structure */ 973b4ee4795Smrg XGenericEventCookie *re, /* pointer to where event should be reformatted */ 974b4ee4795Smrg xEvent *event) /* wire protocol event */ 975b4ee4795Smrg{ 976b4ee4795Smrg#ifdef notdef 977b4ee4795Smrg fprintf(stderr, 978b4ee4795Smrg "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.", 979b4ee4795Smrg ((xGenericEvent*)event)->extension, dpy); 980b4ee4795Smrg#endif 981b4ee4795Smrg return(False); 982b4ee4795Smrg} 983b4ee4795Smrg 984b4ee4795SmrgBool 985b4ee4795Smrg_XUnknownCopyEventCookie( 986b4ee4795Smrg Display *dpy, /* pointer to display structure */ 987b4ee4795Smrg XGenericEventCookie *in, /* source */ 988b4ee4795Smrg XGenericEventCookie *out) /* destination */ 989b4ee4795Smrg{ 990b4ee4795Smrg#ifdef notdef 991b4ee4795Smrg fprintf(stderr, 992b4ee4795Smrg "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.", 993b4ee4795Smrg in->extension, dpy); 994b4ee4795Smrg#endif 995b4ee4795Smrg return(False); 996b4ee4795Smrg} 997b4ee4795Smrg 9981ab64890Smrg/*ARGSUSED*/ 9991ab64890SmrgStatus 10001ab64890Smrg_XUnknownNativeEvent( 10011ab64890Smrg register Display *dpy, /* pointer to display structure */ 10021ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 10031ab64890Smrg register xEvent *event) /* wire protocol event */ 10041ab64890Smrg{ 10051ab64890Smrg#ifdef notdef 100661b2299dSmrg (void) fprintf(stderr, 10071ab64890Smrg "Xlib: unhandled native event! event number = %d, display = %x\n.", 10081ab64890Smrg re->type, dpy); 10091ab64890Smrg#endif 10101ab64890Smrg return(0); 10111ab64890Smrg} 10121ab64890Smrg/* 10131ab64890Smrg * reformat a wire event into an XEvent structure of the right type. 10141ab64890Smrg */ 10151ab64890SmrgBool 10161ab64890Smrg_XWireToEvent( 10171ab64890Smrg register Display *dpy, /* pointer to display structure */ 10181ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 10191ab64890Smrg register xEvent *event) /* wire protocol event */ 10201ab64890Smrg{ 10211ab64890Smrg 10221ab64890Smrg re->type = event->u.u.type & 0x7f; 10231ab64890Smrg ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy, 10241ab64890Smrg (xGenericReply *)event); 10251ab64890Smrg ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0); 10261ab64890Smrg ((XAnyEvent *)re)->display = dpy; 102761b2299dSmrg 10281ab64890Smrg /* Ignore the leading bit of the event type since it is set when a 10291ab64890Smrg client sends an event rather than the server. */ 10301ab64890Smrg 10311ab64890Smrg switch (event-> u.u.type & 0177) { 10321ab64890Smrg case KeyPress: 10331ab64890Smrg case KeyRelease: 10341ab64890Smrg { 10351ab64890Smrg register XKeyEvent *ev = (XKeyEvent*) re; 10361ab64890Smrg ev->root = event->u.keyButtonPointer.root; 10371ab64890Smrg ev->window = event->u.keyButtonPointer.event; 10381ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 10391ab64890Smrg ev->time = event->u.keyButtonPointer.time; 10401ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 10411ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 10421ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 10431ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 10441ab64890Smrg ev->state = event->u.keyButtonPointer.state; 10451ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 10461ab64890Smrg ev->keycode = event->u.u.detail; 10471ab64890Smrg } 10481ab64890Smrg break; 10491ab64890Smrg case ButtonPress: 10501ab64890Smrg case ButtonRelease: 10511ab64890Smrg { 10521ab64890Smrg register XButtonEvent *ev = (XButtonEvent *) re; 10531ab64890Smrg ev->root = event->u.keyButtonPointer.root; 10541ab64890Smrg ev->window = event->u.keyButtonPointer.event; 10551ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 10561ab64890Smrg ev->time = event->u.keyButtonPointer.time; 10571ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 10581ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 10591ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 10601ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 10611ab64890Smrg ev->state = event->u.keyButtonPointer.state; 10621ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 10631ab64890Smrg ev->button = event->u.u.detail; 10641ab64890Smrg } 10651ab64890Smrg break; 10661ab64890Smrg case MotionNotify: 10671ab64890Smrg { 10681ab64890Smrg register XMotionEvent *ev = (XMotionEvent *)re; 10691ab64890Smrg ev->root = event->u.keyButtonPointer.root; 10701ab64890Smrg ev->window = event->u.keyButtonPointer.event; 10711ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 10721ab64890Smrg ev->time = event->u.keyButtonPointer.time; 10731ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 10741ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 10751ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 10761ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 10771ab64890Smrg ev->state = event->u.keyButtonPointer.state; 10781ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 10791ab64890Smrg ev->is_hint = event->u.u.detail; 10801ab64890Smrg } 10811ab64890Smrg break; 10821ab64890Smrg case EnterNotify: 10831ab64890Smrg case LeaveNotify: 10841ab64890Smrg { 10851ab64890Smrg register XCrossingEvent *ev = (XCrossingEvent *) re; 10861ab64890Smrg ev->root = event->u.enterLeave.root; 10871ab64890Smrg ev->window = event->u.enterLeave.event; 10881ab64890Smrg ev->subwindow = event->u.enterLeave.child; 10891ab64890Smrg ev->time = event->u.enterLeave.time; 10901ab64890Smrg ev->x = cvtINT16toInt(event->u.enterLeave.eventX); 10911ab64890Smrg ev->y = cvtINT16toInt(event->u.enterLeave.eventY); 10921ab64890Smrg ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX); 10931ab64890Smrg ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY); 10941ab64890Smrg ev->state = event->u.enterLeave.state; 10951ab64890Smrg ev->mode = event->u.enterLeave.mode; 109661b2299dSmrg ev->same_screen = (event->u.enterLeave.flags & 10971ab64890Smrg ELFlagSameScreen) && True; 10981ab64890Smrg ev->focus = (event->u.enterLeave.flags & 10991ab64890Smrg ELFlagFocus) && True; 11001ab64890Smrg ev->detail = event->u.u.detail; 11011ab64890Smrg } 11021ab64890Smrg break; 11031ab64890Smrg case FocusIn: 11041ab64890Smrg case FocusOut: 11051ab64890Smrg { 11061ab64890Smrg register XFocusChangeEvent *ev = (XFocusChangeEvent *) re; 11071ab64890Smrg ev->window = event->u.focus.window; 11081ab64890Smrg ev->mode = event->u.focus.mode; 11091ab64890Smrg ev->detail = event->u.u.detail; 11101ab64890Smrg } 11111ab64890Smrg break; 11121ab64890Smrg case KeymapNotify: 11131ab64890Smrg { 11141ab64890Smrg register XKeymapEvent *ev = (XKeymapEvent *) re; 11151ab64890Smrg ev->window = None; 11161ab64890Smrg memcpy(&ev->key_vector[1], 11171ab64890Smrg (char *)((xKeymapEvent *) event)->map, 11181ab64890Smrg sizeof (((xKeymapEvent *) event)->map)); 11191ab64890Smrg } 11201ab64890Smrg break; 11211ab64890Smrg case Expose: 11221ab64890Smrg { 11231ab64890Smrg register XExposeEvent *ev = (XExposeEvent *) re; 11241ab64890Smrg ev->window = event->u.expose.window; 11251ab64890Smrg ev->x = event->u.expose.x; 11261ab64890Smrg ev->y = event->u.expose.y; 11271ab64890Smrg ev->width = event->u.expose.width; 11281ab64890Smrg ev->height = event->u.expose.height; 11291ab64890Smrg ev->count = event->u.expose.count; 11301ab64890Smrg } 11311ab64890Smrg break; 11321ab64890Smrg case GraphicsExpose: 11331ab64890Smrg { 11341ab64890Smrg register XGraphicsExposeEvent *ev = 11351ab64890Smrg (XGraphicsExposeEvent *) re; 11361ab64890Smrg ev->drawable = event->u.graphicsExposure.drawable; 11371ab64890Smrg ev->x = event->u.graphicsExposure.x; 11381ab64890Smrg ev->y = event->u.graphicsExposure.y; 11391ab64890Smrg ev->width = event->u.graphicsExposure.width; 11401ab64890Smrg ev->height = event->u.graphicsExposure.height; 11411ab64890Smrg ev->count = event->u.graphicsExposure.count; 11421ab64890Smrg ev->major_code = event->u.graphicsExposure.majorEvent; 11431ab64890Smrg ev->minor_code = event->u.graphicsExposure.minorEvent; 11441ab64890Smrg } 11451ab64890Smrg break; 11461ab64890Smrg case NoExpose: 11471ab64890Smrg { 11481ab64890Smrg register XNoExposeEvent *ev = (XNoExposeEvent *) re; 11491ab64890Smrg ev->drawable = event->u.noExposure.drawable; 11501ab64890Smrg ev->major_code = event->u.noExposure.majorEvent; 11511ab64890Smrg ev->minor_code = event->u.noExposure.minorEvent; 11521ab64890Smrg } 11531ab64890Smrg break; 11541ab64890Smrg case VisibilityNotify: 11551ab64890Smrg { 11561ab64890Smrg register XVisibilityEvent *ev = (XVisibilityEvent *) re; 11571ab64890Smrg ev->window = event->u.visibility.window; 11581ab64890Smrg ev->state = event->u.visibility.state; 11591ab64890Smrg } 11601ab64890Smrg break; 11611ab64890Smrg case CreateNotify: 11621ab64890Smrg { 11631ab64890Smrg register XCreateWindowEvent *ev = 11641ab64890Smrg (XCreateWindowEvent *) re; 11651ab64890Smrg ev->window = event->u.createNotify.window; 11661ab64890Smrg ev->parent = event->u.createNotify.parent; 11671ab64890Smrg ev->x = cvtINT16toInt(event->u.createNotify.x); 11681ab64890Smrg ev->y = cvtINT16toInt(event->u.createNotify.y); 11691ab64890Smrg ev->width = event->u.createNotify.width; 11701ab64890Smrg ev->height = event->u.createNotify.height; 11711ab64890Smrg ev->border_width = event->u.createNotify.borderWidth; 11721ab64890Smrg ev->override_redirect = event->u.createNotify.override; 11731ab64890Smrg } 11741ab64890Smrg break; 11751ab64890Smrg case DestroyNotify: 11761ab64890Smrg { 11771ab64890Smrg register XDestroyWindowEvent *ev = 11781ab64890Smrg (XDestroyWindowEvent *) re; 11791ab64890Smrg ev->window = event->u.destroyNotify.window; 11801ab64890Smrg ev->event = event->u.destroyNotify.event; 11811ab64890Smrg } 11821ab64890Smrg break; 11831ab64890Smrg case UnmapNotify: 11841ab64890Smrg { 11851ab64890Smrg register XUnmapEvent *ev = (XUnmapEvent *) re; 11861ab64890Smrg ev->window = event->u.unmapNotify.window; 11871ab64890Smrg ev->event = event->u.unmapNotify.event; 11881ab64890Smrg ev->from_configure = event->u.unmapNotify.fromConfigure; 11891ab64890Smrg } 11901ab64890Smrg break; 11911ab64890Smrg case MapNotify: 11921ab64890Smrg { 11931ab64890Smrg register XMapEvent *ev = (XMapEvent *) re; 11941ab64890Smrg ev->window = event->u.mapNotify.window; 11951ab64890Smrg ev->event = event->u.mapNotify.event; 11961ab64890Smrg ev->override_redirect = event->u.mapNotify.override; 11971ab64890Smrg } 11981ab64890Smrg break; 11991ab64890Smrg case MapRequest: 12001ab64890Smrg { 12011ab64890Smrg register XMapRequestEvent *ev = (XMapRequestEvent *) re; 12021ab64890Smrg ev->window = event->u.mapRequest.window; 12031ab64890Smrg ev->parent = event->u.mapRequest.parent; 12041ab64890Smrg } 12051ab64890Smrg break; 12061ab64890Smrg case ReparentNotify: 12071ab64890Smrg { 12081ab64890Smrg register XReparentEvent *ev = (XReparentEvent *) re; 12091ab64890Smrg ev->event = event->u.reparent.event; 12101ab64890Smrg ev->window = event->u.reparent.window; 12111ab64890Smrg ev->parent = event->u.reparent.parent; 12121ab64890Smrg ev->x = cvtINT16toInt(event->u.reparent.x); 12131ab64890Smrg ev->y = cvtINT16toInt(event->u.reparent.y); 12141ab64890Smrg ev->override_redirect = event->u.reparent.override; 12151ab64890Smrg } 12161ab64890Smrg break; 12171ab64890Smrg case ConfigureNotify: 12181ab64890Smrg { 12191ab64890Smrg register XConfigureEvent *ev = (XConfigureEvent *) re; 12201ab64890Smrg ev->event = event->u.configureNotify.event; 12211ab64890Smrg ev->window = event->u.configureNotify.window; 12221ab64890Smrg ev->above = event->u.configureNotify.aboveSibling; 12231ab64890Smrg ev->x = cvtINT16toInt(event->u.configureNotify.x); 12241ab64890Smrg ev->y = cvtINT16toInt(event->u.configureNotify.y); 12251ab64890Smrg ev->width = event->u.configureNotify.width; 12261ab64890Smrg ev->height = event->u.configureNotify.height; 12271ab64890Smrg ev->border_width = event->u.configureNotify.borderWidth; 12281ab64890Smrg ev->override_redirect = event->u.configureNotify.override; 12291ab64890Smrg } 12301ab64890Smrg break; 12311ab64890Smrg case ConfigureRequest: 12321ab64890Smrg { 12331ab64890Smrg register XConfigureRequestEvent *ev = 12341ab64890Smrg (XConfigureRequestEvent *) re; 12351ab64890Smrg ev->window = event->u.configureRequest.window; 12361ab64890Smrg ev->parent = event->u.configureRequest.parent; 12371ab64890Smrg ev->above = event->u.configureRequest.sibling; 12381ab64890Smrg ev->x = cvtINT16toInt(event->u.configureRequest.x); 12391ab64890Smrg ev->y = cvtINT16toInt(event->u.configureRequest.y); 12401ab64890Smrg ev->width = event->u.configureRequest.width; 12411ab64890Smrg ev->height = event->u.configureRequest.height; 12421ab64890Smrg ev->border_width = event->u.configureRequest.borderWidth; 12431ab64890Smrg ev->value_mask = event->u.configureRequest.valueMask; 12441ab64890Smrg ev->detail = event->u.u.detail; 12451ab64890Smrg } 12461ab64890Smrg break; 12471ab64890Smrg case GravityNotify: 12481ab64890Smrg { 12491ab64890Smrg register XGravityEvent *ev = (XGravityEvent *) re; 12501ab64890Smrg ev->window = event->u.gravity.window; 12511ab64890Smrg ev->event = event->u.gravity.event; 12521ab64890Smrg ev->x = cvtINT16toInt(event->u.gravity.x); 12531ab64890Smrg ev->y = cvtINT16toInt(event->u.gravity.y); 12541ab64890Smrg } 12551ab64890Smrg break; 12561ab64890Smrg case ResizeRequest: 12571ab64890Smrg { 12581ab64890Smrg register XResizeRequestEvent *ev = 12591ab64890Smrg (XResizeRequestEvent *) re; 12601ab64890Smrg ev->window = event->u.resizeRequest.window; 12611ab64890Smrg ev->width = event->u.resizeRequest.width; 12621ab64890Smrg ev->height = event->u.resizeRequest.height; 12631ab64890Smrg } 12641ab64890Smrg break; 12651ab64890Smrg case CirculateNotify: 12661ab64890Smrg { 12671ab64890Smrg register XCirculateEvent *ev = (XCirculateEvent *) re; 12681ab64890Smrg ev->window = event->u.circulate.window; 12691ab64890Smrg ev->event = event->u.circulate.event; 12701ab64890Smrg ev->place = event->u.circulate.place; 12711ab64890Smrg } 12721ab64890Smrg break; 12731ab64890Smrg case CirculateRequest: 12741ab64890Smrg { 12751ab64890Smrg register XCirculateRequestEvent *ev = 12761ab64890Smrg (XCirculateRequestEvent *) re; 12771ab64890Smrg ev->window = event->u.circulate.window; 12781ab64890Smrg ev->parent = event->u.circulate.event; 12791ab64890Smrg ev->place = event->u.circulate.place; 12801ab64890Smrg } 12811ab64890Smrg break; 12821ab64890Smrg case PropertyNotify: 12831ab64890Smrg { 12841ab64890Smrg register XPropertyEvent *ev = (XPropertyEvent *) re; 12851ab64890Smrg ev->window = event->u.property.window; 12861ab64890Smrg ev->atom = event->u.property.atom; 12871ab64890Smrg ev->time = event->u.property.time; 12881ab64890Smrg ev->state = event->u.property.state; 12891ab64890Smrg } 12901ab64890Smrg break; 12911ab64890Smrg case SelectionClear: 12921ab64890Smrg { 12931ab64890Smrg register XSelectionClearEvent *ev = 12941ab64890Smrg (XSelectionClearEvent *) re; 12951ab64890Smrg ev->window = event->u.selectionClear.window; 12961ab64890Smrg ev->selection = event->u.selectionClear.atom; 12971ab64890Smrg ev->time = event->u.selectionClear.time; 12981ab64890Smrg } 12991ab64890Smrg break; 13001ab64890Smrg case SelectionRequest: 13011ab64890Smrg { 13021ab64890Smrg register XSelectionRequestEvent *ev = 13031ab64890Smrg (XSelectionRequestEvent *) re; 13041ab64890Smrg ev->owner = event->u.selectionRequest.owner; 13051ab64890Smrg ev->requestor = event->u.selectionRequest.requestor; 13061ab64890Smrg ev->selection = event->u.selectionRequest.selection; 13071ab64890Smrg ev->target = event->u.selectionRequest.target; 13081ab64890Smrg ev->property = event->u.selectionRequest.property; 13091ab64890Smrg ev->time = event->u.selectionRequest.time; 13101ab64890Smrg } 13111ab64890Smrg break; 13121ab64890Smrg case SelectionNotify: 13131ab64890Smrg { 13141ab64890Smrg register XSelectionEvent *ev = (XSelectionEvent *) re; 13151ab64890Smrg ev->requestor = event->u.selectionNotify.requestor; 13161ab64890Smrg ev->selection = event->u.selectionNotify.selection; 13171ab64890Smrg ev->target = event->u.selectionNotify.target; 13181ab64890Smrg ev->property = event->u.selectionNotify.property; 13191ab64890Smrg ev->time = event->u.selectionNotify.time; 13201ab64890Smrg } 13211ab64890Smrg break; 13221ab64890Smrg case ColormapNotify: 13231ab64890Smrg { 13241ab64890Smrg register XColormapEvent *ev = (XColormapEvent *) re; 13251ab64890Smrg ev->window = event->u.colormap.window; 13261ab64890Smrg ev->colormap = event->u.colormap.colormap; 13271ab64890Smrg ev->new = event->u.colormap.new; 13281ab64890Smrg ev->state = event->u.colormap.state; 13291ab64890Smrg } 13301ab64890Smrg break; 13311ab64890Smrg case ClientMessage: 13321ab64890Smrg { 13331ab64890Smrg register int i; 133461b2299dSmrg register XClientMessageEvent *ev 13351ab64890Smrg = (XClientMessageEvent *) re; 13361ab64890Smrg ev->window = event->u.clientMessage.window; 13371ab64890Smrg ev->format = event->u.u.detail; 13381ab64890Smrg switch (ev->format) { 133961b2299dSmrg case 8: 13401ab64890Smrg ev->message_type = event->u.clientMessage.u.b.type; 134161b2299dSmrg for (i = 0; i < 20; i++) 13421ab64890Smrg ev->data.b[i] = event->u.clientMessage.u.b.bytes[i]; 13431ab64890Smrg break; 13441ab64890Smrg case 16: 13451ab64890Smrg ev->message_type = event->u.clientMessage.u.s.type; 13461ab64890Smrg ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0); 13471ab64890Smrg ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1); 13481ab64890Smrg ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2); 13491ab64890Smrg ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3); 13501ab64890Smrg ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4); 13511ab64890Smrg ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5); 13521ab64890Smrg ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6); 13531ab64890Smrg ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7); 13541ab64890Smrg ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8); 13551ab64890Smrg ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9); 13561ab64890Smrg break; 13571ab64890Smrg case 32: 13581ab64890Smrg ev->message_type = event->u.clientMessage.u.l.type; 13591ab64890Smrg ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0); 13601ab64890Smrg ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1); 13611ab64890Smrg ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2); 13621ab64890Smrg ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3); 13631ab64890Smrg ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4); 13641ab64890Smrg break; 13651ab64890Smrg default: /* XXX should never occur */ 13661ab64890Smrg break; 13671ab64890Smrg } 13681ab64890Smrg } 13691ab64890Smrg break; 13701ab64890Smrg case MappingNotify: 13711ab64890Smrg { 13721ab64890Smrg register XMappingEvent *ev = (XMappingEvent *)re; 13731ab64890Smrg ev->window = 0; 13741ab64890Smrg ev->first_keycode = event->u.mappingNotify.firstKeyCode; 13751ab64890Smrg ev->request = event->u.mappingNotify.request; 13761ab64890Smrg ev->count = event->u.mappingNotify.count; 13771ab64890Smrg } 13781ab64890Smrg break; 13791ab64890Smrg default: 13801ab64890Smrg return(_XUnknownWireEvent(dpy, re, event)); 13811ab64890Smrg } 13821ab64890Smrg return(True); 13831ab64890Smrg} 13841ab64890Smrg 13851ab64890Smrg 13861ab64890Smrg/* 138761b2299dSmrg * _XDefaultIOError - Default fatal system error reporting routine. Called 13881ab64890Smrg * when an X internal system error is encountered. 13891ab64890Smrg */ 13901ab64890Smrgint _XDefaultIOError( 13911ab64890Smrg Display *dpy) 13921ab64890Smrg{ 13931ab64890Smrg if (ECHECK(EPIPE)) { 13941ab64890Smrg (void) fprintf (stderr, 13951ab64890Smrg "X connection to %s broken (explicit kill or server shutdown).\r\n", 13961ab64890Smrg DisplayString (dpy)); 13971ab64890Smrg } else { 139861b2299dSmrg (void) fprintf (stderr, 13991ab64890Smrg "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n", 14001ab64890Smrg#ifdef WIN32 14011ab64890Smrg WSAGetLastError(), strerror(WSAGetLastError()), 14021ab64890Smrg#else 14031ab64890Smrg errno, strerror (errno), 14041ab64890Smrg#endif 14051ab64890Smrg DisplayString (dpy)); 140661b2299dSmrg (void) fprintf (stderr, 14071ab64890Smrg " after %lu requests (%lu known processed) with %d events remaining.\r\n", 14081ab64890Smrg NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy), 14091ab64890Smrg QLength(dpy)); 14101ab64890Smrg 14111ab64890Smrg } 14121ab64890Smrg exit(1); 14131ab64890Smrg return(0); /* dummy - function should never return */ 14141ab64890Smrg} 14151ab64890Smrg 14161ab64890Smrg 14171ab64890Smrgstatic int _XPrintDefaultError( 14181ab64890Smrg Display *dpy, 14191ab64890Smrg XErrorEvent *event, 14201ab64890Smrg FILE *fp) 14211ab64890Smrg{ 14221ab64890Smrg char buffer[BUFSIZ]; 14231ab64890Smrg char mesg[BUFSIZ]; 14241ab64890Smrg char number[32]; 14251ab64890Smrg const char *mtype = "XlibMessage"; 14261ab64890Smrg register _XExtension *ext = (_XExtension *)NULL; 14271ab64890Smrg _XExtension *bext = (_XExtension *)NULL; 14281ab64890Smrg XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); 14291ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); 14301ab64890Smrg (void) fprintf(fp, "%s: %s\n ", mesg, buffer); 143161b2299dSmrg XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", 14321ab64890Smrg mesg, BUFSIZ); 14331ab64890Smrg (void) fprintf(fp, mesg, event->request_code); 14341ab64890Smrg if (event->request_code < 128) { 14351ab64890Smrg sprintf(number, "%d", event->request_code); 14361ab64890Smrg XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); 14371ab64890Smrg } else { 14381ab64890Smrg for (ext = dpy->ext_procs; 14391ab64890Smrg ext && (ext->codes.major_opcode != event->request_code); 14401ab64890Smrg ext = ext->next) 14411ab64890Smrg ; 1442c17aa6b1Smrg if (ext) { 1443c17aa6b1Smrg strncpy(buffer, ext->name, BUFSIZ); 1444c17aa6b1Smrg buffer[BUFSIZ - 1] = '\0'; 1445c17aa6b1Smrg } else 14461ab64890Smrg buffer[0] = '\0'; 14471ab64890Smrg } 14481ab64890Smrg (void) fprintf(fp, " (%s)\n", buffer); 14491ab64890Smrg if (event->request_code >= 128) { 14501ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", 14511ab64890Smrg mesg, BUFSIZ); 14521ab64890Smrg fputs(" ", fp); 14531ab64890Smrg (void) fprintf(fp, mesg, event->minor_code); 14541ab64890Smrg if (ext) { 14551ab64890Smrg sprintf(mesg, "%s.%d", ext->name, event->minor_code); 14561ab64890Smrg XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); 14571ab64890Smrg (void) fprintf(fp, " (%s)", buffer); 14581ab64890Smrg } 14591ab64890Smrg fputs("\n", fp); 14601ab64890Smrg } 14611ab64890Smrg if (event->error_code >= 128) { 14621ab64890Smrg /* kludge, try to find the extension that caused it */ 14631ab64890Smrg buffer[0] = '\0'; 14641ab64890Smrg for (ext = dpy->ext_procs; ext; ext = ext->next) { 146561b2299dSmrg if (ext->error_string) 14661ab64890Smrg (*ext->error_string)(dpy, event->error_code, &ext->codes, 14671ab64890Smrg buffer, BUFSIZ); 14681ab64890Smrg if (buffer[0]) { 14691ab64890Smrg bext = ext; 14701ab64890Smrg break; 14711ab64890Smrg } 14721ab64890Smrg if (ext->codes.first_error && 14731ab64890Smrg ext->codes.first_error < (int)event->error_code && 14741ab64890Smrg (!bext || ext->codes.first_error > bext->codes.first_error)) 14751ab64890Smrg bext = ext; 147661b2299dSmrg } 14771ab64890Smrg if (bext) 14781ab64890Smrg sprintf(buffer, "%s.%d", bext->name, 14791ab64890Smrg event->error_code - bext->codes.first_error); 14801ab64890Smrg else 14811ab64890Smrg strcpy(buffer, "Value"); 14821ab64890Smrg XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); 14831ab64890Smrg if (mesg[0]) { 14841ab64890Smrg fputs(" ", fp); 14851ab64890Smrg (void) fprintf(fp, mesg, event->resourceid); 14861ab64890Smrg fputs("\n", fp); 14871ab64890Smrg } 14881ab64890Smrg /* let extensions try to print the values */ 14891ab64890Smrg for (ext = dpy->ext_procs; ext; ext = ext->next) { 14901ab64890Smrg if (ext->error_values) 14911ab64890Smrg (*ext->error_values)(dpy, event, fp); 14921ab64890Smrg } 14931ab64890Smrg } else if ((event->error_code == BadWindow) || 14941ab64890Smrg (event->error_code == BadPixmap) || 14951ab64890Smrg (event->error_code == BadCursor) || 14961ab64890Smrg (event->error_code == BadFont) || 14971ab64890Smrg (event->error_code == BadDrawable) || 14981ab64890Smrg (event->error_code == BadColor) || 14991ab64890Smrg (event->error_code == BadGC) || 15001ab64890Smrg (event->error_code == BadIDChoice) || 15011ab64890Smrg (event->error_code == BadValue) || 15021ab64890Smrg (event->error_code == BadAtom)) { 15031ab64890Smrg if (event->error_code == BadValue) 15041ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", 15051ab64890Smrg mesg, BUFSIZ); 15061ab64890Smrg else if (event->error_code == BadAtom) 15071ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", 15081ab64890Smrg mesg, BUFSIZ); 15091ab64890Smrg else 15101ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", 15111ab64890Smrg mesg, BUFSIZ); 15121ab64890Smrg fputs(" ", fp); 15131ab64890Smrg (void) fprintf(fp, mesg, event->resourceid); 15141ab64890Smrg fputs("\n", fp); 15151ab64890Smrg } 151661b2299dSmrg XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", 15171ab64890Smrg mesg, BUFSIZ); 15181ab64890Smrg fputs(" ", fp); 15191ab64890Smrg (void) fprintf(fp, mesg, event->serial); 15201ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", 15211ab64890Smrg mesg, BUFSIZ); 15221ab64890Smrg fputs("\n ", fp); 15231ab64890Smrg (void) fprintf(fp, mesg, dpy->request); 15241ab64890Smrg fputs("\n", fp); 15251ab64890Smrg if (event->error_code == BadImplementation) return 0; 15261ab64890Smrg return 1; 15271ab64890Smrg} 15281ab64890Smrg 15291ab64890Smrgint _XDefaultError( 15301ab64890Smrg Display *dpy, 15311ab64890Smrg XErrorEvent *event) 15321ab64890Smrg{ 15331ab64890Smrg if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0; 15341ab64890Smrg exit(1); 15351ab64890Smrg /*NOTREACHED*/ 15361ab64890Smrg} 15371ab64890Smrg 15381ab64890Smrg/*ARGSUSED*/ 153961b2299dSmrgBool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we) 15401ab64890Smrg{ 15411ab64890Smrg return True; 15421ab64890Smrg} 15431ab64890Smrg 15441ab64890Smrg/* 15451ab64890Smrg * _XError - upcall internal or user protocol error handler 15461ab64890Smrg */ 15471ab64890Smrgint _XError ( 15481ab64890Smrg Display *dpy, 15491ab64890Smrg register xError *rep) 15501ab64890Smrg{ 155161b2299dSmrg /* 15521ab64890Smrg * X_Error packet encountered! We need to unpack the error before 15531ab64890Smrg * giving it to the user. 15541ab64890Smrg */ 15551ab64890Smrg XEvent event; /* make it a large event */ 15561ab64890Smrg register _XAsyncHandler *async, *next; 15571ab64890Smrg 15581ab64890Smrg event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep); 15591ab64890Smrg 15601ab64890Smrg for (async = dpy->async_handlers; async; async = next) { 15611ab64890Smrg next = async->next; 15621ab64890Smrg if ((*async->handler)(dpy, (xReply *)rep, 15631ab64890Smrg (char *)rep, SIZEOF(xError), async->data)) 15641ab64890Smrg return 0; 15651ab64890Smrg } 15661ab64890Smrg 15671ab64890Smrg event.xerror.display = dpy; 15681ab64890Smrg event.xerror.type = X_Error; 15691ab64890Smrg event.xerror.resourceid = rep->resourceID; 15701ab64890Smrg event.xerror.error_code = rep->errorCode; 15711ab64890Smrg event.xerror.request_code = rep->majorCode; 15721ab64890Smrg event.xerror.minor_code = rep->minorCode; 15731ab64890Smrg if (dpy->error_vec && 15741ab64890Smrg !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep)) 15751ab64890Smrg return 0; 15761ab64890Smrg if (_XErrorFunction != NULL) { 1577c17aa6b1Smrg int rtn_val; 1578c17aa6b1Smrg#ifdef XTHREADS 1579c17aa6b1Smrg if (dpy->lock) 1580c17aa6b1Smrg (*dpy->lock->user_lock_display)(dpy); 1581c17aa6b1Smrg UnlockDisplay(dpy); 1582c17aa6b1Smrg#endif 1583c17aa6b1Smrg rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ 1584c17aa6b1Smrg#ifdef XTHREADS 1585c17aa6b1Smrg LockDisplay(dpy); 1586c17aa6b1Smrg if (dpy->lock) 1587c17aa6b1Smrg (*dpy->lock->user_unlock_display)(dpy); 1588c17aa6b1Smrg#endif 1589c17aa6b1Smrg return rtn_val; 15901ab64890Smrg } else { 15911ab64890Smrg return _XDefaultError(dpy, (XErrorEvent *)&event); 15921ab64890Smrg } 15931ab64890Smrg} 159461b2299dSmrg 15951ab64890Smrg/* 15961ab64890Smrg * _XIOError - call user connection error handler and exit 15971ab64890Smrg */ 15981ab64890Smrgint 15991ab64890Smrg_XIOError ( 16001ab64890Smrg Display *dpy) 16011ab64890Smrg{ 16021ab64890Smrg dpy->flags |= XlibDisplayIOError; 16031ab64890Smrg#ifdef WIN32 16041ab64890Smrg errno = WSAGetLastError(); 16051ab64890Smrg#endif 16061ab64890Smrg 16071ab64890Smrg /* This assumes that the thread calling exit will call any atexit handlers. 16081ab64890Smrg * If this does not hold, then an alternate solution would involve 16091ab64890Smrg * registering an atexit handler to take over the lock, which would only 16101ab64890Smrg * assume that the same thread calls all the atexit handlers. */ 16111ab64890Smrg#ifdef XTHREADS 16121ab64890Smrg if (dpy->lock) 16131ab64890Smrg (*dpy->lock->user_lock_display)(dpy); 16141ab64890Smrg#endif 16151ab64890Smrg UnlockDisplay(dpy); 16161ab64890Smrg 16171ab64890Smrg if (_XIOErrorFunction != NULL) 16181ab64890Smrg (*_XIOErrorFunction)(dpy); 16191ab64890Smrg else 16201ab64890Smrg _XDefaultIOError(dpy); 16211ab64890Smrg exit (1); 16221ab64890Smrg return 0; 16231ab64890Smrg} 16241ab64890Smrg 16251ab64890Smrg 16261ab64890Smrg/* 16271ab64890Smrg * This routine can be used to (cheaply) get some memory within a single 16281ab64890Smrg * Xlib routine for scratch space. A single buffer is reused each time 16291ab64890Smrg * if possible. To be MT safe, you can only call this between a call to 16301ab64890Smrg * GetReq* and a call to Data* or _XSend*, or in a context when the thread 16311ab64890Smrg * is guaranteed to not unlock the display. 16321ab64890Smrg */ 16331ab64890Smrgchar *_XAllocScratch( 16341ab64890Smrg register Display *dpy, 16351ab64890Smrg unsigned long nbytes) 16361ab64890Smrg{ 16371ab64890Smrg if (nbytes > dpy->scratch_length) { 16381ab64890Smrg if (dpy->scratch_buffer) Xfree (dpy->scratch_buffer); 16391ab64890Smrg if ((dpy->scratch_buffer = Xmalloc((unsigned) nbytes))) 16401ab64890Smrg dpy->scratch_length = nbytes; 16411ab64890Smrg else dpy->scratch_length = 0; 16421ab64890Smrg } 16431ab64890Smrg return (dpy->scratch_buffer); 16441ab64890Smrg} 16451ab64890Smrg 16461ab64890Smrg/* 16471ab64890Smrg * Scratch space allocator you can call any time, multiple times, and be 16481ab64890Smrg * MT safe, but you must hand the buffer back with _XFreeTemp. 16491ab64890Smrg */ 16501ab64890Smrgchar *_XAllocTemp( 16511ab64890Smrg register Display *dpy, 16521ab64890Smrg unsigned long nbytes) 16531ab64890Smrg{ 16541ab64890Smrg char *buf; 16551ab64890Smrg 16561ab64890Smrg buf = _XAllocScratch(dpy, nbytes); 16571ab64890Smrg dpy->scratch_buffer = NULL; 16581ab64890Smrg dpy->scratch_length = 0; 16591ab64890Smrg return buf; 16601ab64890Smrg} 16611ab64890Smrg 16621ab64890Smrgvoid _XFreeTemp( 16631ab64890Smrg register Display *dpy, 16641ab64890Smrg char *buf, 16651ab64890Smrg unsigned long nbytes) 16661ab64890Smrg{ 16671ab64890Smrg if (dpy->scratch_buffer) 16681ab64890Smrg Xfree(dpy->scratch_buffer); 16691ab64890Smrg dpy->scratch_buffer = buf; 16701ab64890Smrg dpy->scratch_length = nbytes; 16711ab64890Smrg} 16721ab64890Smrg 16731ab64890Smrg/* 16741ab64890Smrg * Given a visual id, find the visual structure for this id on this display. 16751ab64890Smrg */ 16761ab64890SmrgVisual *_XVIDtoVisual( 16771ab64890Smrg Display *dpy, 16781ab64890Smrg VisualID id) 16791ab64890Smrg{ 16801ab64890Smrg register int i, j, k; 16811ab64890Smrg register Screen *sp; 16821ab64890Smrg register Depth *dp; 16831ab64890Smrg register Visual *vp; 16841ab64890Smrg for (i = 0; i < dpy->nscreens; i++) { 16851ab64890Smrg sp = &dpy->screens[i]; 16861ab64890Smrg for (j = 0; j < sp->ndepths; j++) { 16871ab64890Smrg dp = &sp->depths[j]; 16881ab64890Smrg /* if nvisuals == 0 then visuals will be NULL */ 16891ab64890Smrg for (k = 0; k < dp->nvisuals; k++) { 16901ab64890Smrg vp = &dp->visuals[k]; 16911ab64890Smrg if (vp->visualid == id) return (vp); 16921ab64890Smrg } 16931ab64890Smrg } 16941ab64890Smrg } 16951ab64890Smrg return (NULL); 16961ab64890Smrg} 16971ab64890Smrg 16981ab64890Smrgint 16991ab64890SmrgXFree (void *data) 17001ab64890Smrg{ 17011ab64890Smrg Xfree (data); 17021ab64890Smrg return 1; 17031ab64890Smrg} 17041ab64890Smrg 17051ab64890Smrg#ifdef _XNEEDBCOPYFUNC 17061ab64890Smrgvoid _Xbcopy(b1, b2, length) 17071ab64890Smrg register char *b1, *b2; 17081ab64890Smrg register length; 17091ab64890Smrg{ 17101ab64890Smrg if (b1 < b2) { 17111ab64890Smrg b2 += length; 17121ab64890Smrg b1 += length; 17131ab64890Smrg while (length--) 17141ab64890Smrg *--b2 = *--b1; 17151ab64890Smrg } else { 17161ab64890Smrg while (length--) 17171ab64890Smrg *b2++ = *b1++; 17181ab64890Smrg } 17191ab64890Smrg} 17201ab64890Smrg#endif 17211ab64890Smrg 17221ab64890Smrg#ifdef DataRoutineIsProcedure 17231ab64890Smrgvoid Data( 17241ab64890Smrg Display *dpy, 17251ab64890Smrg char *data, 17261ab64890Smrg long len) 17271ab64890Smrg{ 17281ab64890Smrg if (dpy->bufptr + (len) <= dpy->bufmax) { 17291ab64890Smrg memcpy(dpy->bufptr, data, (int)len); 17301ab64890Smrg dpy->bufptr += ((len) + 3) & ~3; 17311ab64890Smrg } else { 17321ab64890Smrg _XSend(dpy, data, len); 17331ab64890Smrg } 17341ab64890Smrg} 17351ab64890Smrg#endif /* DataRoutineIsProcedure */ 17361ab64890Smrg 17371ab64890Smrg 17381ab64890Smrg#ifdef LONG64 17391ab64890Smrgint 17401ab64890Smrg_XData32( 17411ab64890Smrg Display *dpy, 17421ab64890Smrg register long *data, 17431ab64890Smrg unsigned len) 17441ab64890Smrg{ 17451ab64890Smrg register int *buf; 17461ab64890Smrg register long i; 17471ab64890Smrg 17481ab64890Smrg while (len) { 17491ab64890Smrg buf = (int *)dpy->bufptr; 17501ab64890Smrg i = dpy->bufmax - (char *)buf; 17511ab64890Smrg if (!i) { 17521ab64890Smrg _XFlush(dpy); 17531ab64890Smrg continue; 17541ab64890Smrg } 17551ab64890Smrg if (len < i) 17561ab64890Smrg i = len; 17571ab64890Smrg dpy->bufptr = (char *)buf + i; 17581ab64890Smrg len -= i; 17591ab64890Smrg i >>= 2; 17601ab64890Smrg while (--i >= 0) 17611ab64890Smrg *buf++ = *data++; 17621ab64890Smrg } 17631ab64890Smrg return 0; 17641ab64890Smrg} 17651ab64890Smrg#endif /* LONG64 */ 17661ab64890Smrg 17671ab64890Smrg#ifdef WORD64 17681ab64890Smrg 17691ab64890Smrg/* 177061b2299dSmrg * XXX This is a *really* stupid way of doing this. It should just use 17711ab64890Smrg * dpy->bufptr directly, taking into account where in the word it is. 17721ab64890Smrg */ 17731ab64890Smrg 17741ab64890Smrg/* 17751ab64890Smrg * Data16 - Place 16 bit data in the buffer. 17761ab64890Smrg * 17771ab64890Smrg * "dpy" is a pointer to a Display. 17781ab64890Smrg * "data" is a pointer to the data. 17791ab64890Smrg * "len" is the length in bytes of the data. 17801ab64890Smrg */ 17811ab64890Smrg 17821ab64890Smrgstatic doData16( 17831ab64890Smrg register Display *dpy, 17841ab64890Smrg short *data, 17851ab64890Smrg unsigned len, 17861ab64890Smrg char *packbuffer) 17871ab64890Smrg{ 17881ab64890Smrg long *lp,*lpack; 17891ab64890Smrg long i, nwords,bits; 17901ab64890Smrg long mask16 = 0x000000000000ffff; 17911ab64890Smrg 17921ab64890Smrg lp = (long *)data; 17931ab64890Smrg lpack = (long *)packbuffer; 17941ab64890Smrg 17951ab64890Smrg/* nwords is the number of 16 bit values to be packed, 17961ab64890Smrg * the low order 16 bits of each word will be packed 17971ab64890Smrg * into 64 bit words 17981ab64890Smrg */ 17991ab64890Smrg nwords = len >> 1; 18001ab64890Smrg bits = 48; 18011ab64890Smrg 18021ab64890Smrg for(i=0;i<nwords;i++){ 18031ab64890Smrg if (bits == 48) *lpack = 0; 18041ab64890Smrg *lpack ^= (*lp & mask16) << bits; 18051ab64890Smrg bits -= 16 ; 18061ab64890Smrg lp++; 18071ab64890Smrg if(bits < 0){ 18081ab64890Smrg lpack++; 18091ab64890Smrg bits = 48; 18101ab64890Smrg } 18111ab64890Smrg } 18121ab64890Smrg Data(dpy, packbuffer, len); 18131ab64890Smrg} 18141ab64890Smrg 18151ab64890Smrg_XData16 ( 18161ab64890Smrg Display *dpy, 18171ab64890Smrg short *data, 18181ab64890Smrg unsigned len) 18191ab64890Smrg{ 18201ab64890Smrg char packbuffer[PACKBUFFERSIZE]; 18211ab64890Smrg unsigned nunits = PACKBUFFERSIZE >> 1; 18221ab64890Smrg 18231ab64890Smrg for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { 18241ab64890Smrg doData16 (dpy, data, PACKBUFFERSIZE, packbuffer); 18251ab64890Smrg } 18261ab64890Smrg if (len) doData16 (dpy, data, len, packbuffer); 18271ab64890Smrg} 18281ab64890Smrg 18291ab64890Smrg/* 18301ab64890Smrg * Data32 - Place 32 bit data in the buffer. 18311ab64890Smrg * 18321ab64890Smrg * "dpy" is a pointer to a Display. 18331ab64890Smrg * "data" is a pointer to the data. 18341ab64890Smrg * "len" is the length in bytes of the data. 18351ab64890Smrg */ 18361ab64890Smrg 18371ab64890Smrgstatic doData32( 18381ab64890Smrg register Display *dpy 18391ab64890Smrg long *data, 18401ab64890Smrg unsigned len, 18411ab64890Smrg char *packbuffer) 18421ab64890Smrg{ 18431ab64890Smrg long *lp,*lpack; 18441ab64890Smrg long i,bits,nwords; 18451ab64890Smrg long mask32 = 0x00000000ffffffff; 18461ab64890Smrg 18471ab64890Smrg lpack = (long *) packbuffer; 18481ab64890Smrg lp = data; 18491ab64890Smrg 18501ab64890Smrg/* nwords is the number of 32 bit values to be packed 18511ab64890Smrg * the low order 32 bits of each word will be packed 18521ab64890Smrg * into 64 bit words 18531ab64890Smrg */ 18541ab64890Smrg nwords = len >> 2; 18551ab64890Smrg bits = 32; 18561ab64890Smrg 18571ab64890Smrg for(i=0;i<nwords;i++){ 18581ab64890Smrg if (bits == 32) *lpack = 0; 18591ab64890Smrg *lpack ^= (*lp & mask32) << bits; 18601ab64890Smrg bits = bits ^32; 18611ab64890Smrg lp++; 18621ab64890Smrg if(bits) 18631ab64890Smrg lpack++; 18641ab64890Smrg } 18651ab64890Smrg Data(dpy, packbuffer, len); 18661ab64890Smrg} 18671ab64890Smrg 18681ab64890Smrgvoid _XData32( 18691ab64890Smrg Display *dpy, 18701ab64890Smrg long *data, 187161b2299dSmrg unsigned len) 18721ab64890Smrg{ 18731ab64890Smrg char packbuffer[PACKBUFFERSIZE]; 18741ab64890Smrg unsigned nunits = PACKBUFFERSIZE >> 2; 18751ab64890Smrg 18761ab64890Smrg for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { 18771ab64890Smrg doData32 (dpy, data, PACKBUFFERSIZE, packbuffer); 18781ab64890Smrg } 18791ab64890Smrg if (len) doData32 (dpy, data, len, packbuffer); 18801ab64890Smrg} 18811ab64890Smrg 18821ab64890Smrg#endif /* WORD64 */ 18831ab64890Smrg 18841ab64890Smrg 18851ab64890Smrg/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm. 18861ab64890Smrg * Otherwise, Xau will not be able to find your cookies in the Xauthority file. 18871ab64890Smrg * 18881ab64890Smrg * Note: POSIX says that the ``nodename'' member of utsname does _not_ have 18891ab64890Smrg * to have sufficient information for interfacing to the network, 18901ab64890Smrg * and so, you may be better off using gethostname (if it exists). 18911ab64890Smrg */ 18921ab64890Smrg 18932e9c7c8cSmrg#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4) 18941ab64890Smrg#define NEED_UTSNAME 18951ab64890Smrg#include <sys/utsname.h> 189688de56ccSmrg#else 189788de56ccSmrg#ifdef HAVE_UNISTD_H 189888de56ccSmrg#include <unistd.h> 189988de56ccSmrg#endif 19001ab64890Smrg#endif 19011ab64890Smrg 19021ab64890Smrg/* 19031ab64890Smrg * _XGetHostname - similar to gethostname but allows special processing. 19041ab64890Smrg */ 19051ab64890Smrgint _XGetHostname ( 19061ab64890Smrg char *buf, 19071ab64890Smrg int maxlen) 19081ab64890Smrg{ 19091ab64890Smrg int len; 19101ab64890Smrg 19111ab64890Smrg#ifdef NEED_UTSNAME 19121ab64890Smrg struct utsname name; 19131ab64890Smrg 19141ab64890Smrg if (maxlen <= 0 || buf == NULL) 19151ab64890Smrg return 0; 19161ab64890Smrg 19171ab64890Smrg uname (&name); 19181ab64890Smrg len = strlen (name.nodename); 19191ab64890Smrg if (len >= maxlen) len = maxlen - 1; 19201ab64890Smrg strncpy (buf, name.nodename, len); 19211ab64890Smrg buf[len] = '\0'; 19221ab64890Smrg#else 19231ab64890Smrg if (maxlen <= 0 || buf == NULL) 19241ab64890Smrg return 0; 19251ab64890Smrg 19261ab64890Smrg buf[0] = '\0'; 19271ab64890Smrg (void) gethostname (buf, maxlen); 19281ab64890Smrg buf [maxlen - 1] = '\0'; 19291ab64890Smrg len = strlen(buf); 19301ab64890Smrg#endif /* NEED_UTSNAME */ 19311ab64890Smrg return len; 19321ab64890Smrg} 19331ab64890Smrg 19341ab64890Smrg 19351ab64890Smrg/* 19361ab64890Smrg * _XScreenOfWindow - get the Screen of a given window 19371ab64890Smrg */ 19381ab64890Smrg 193961b2299dSmrgScreen *_XScreenOfWindow(Display *dpy, Window w) 19401ab64890Smrg{ 19411ab64890Smrg register int i; 19421ab64890Smrg Window root; 19431ab64890Smrg int x, y; /* dummy variables */ 19441ab64890Smrg unsigned int width, height, bw, depth; /* dummy variables */ 19451ab64890Smrg 19461ab64890Smrg if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height, 19471ab64890Smrg &bw, &depth) == False) { 19482e9c7c8cSmrg return NULL; 19491ab64890Smrg } 19501ab64890Smrg for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */ 19511ab64890Smrg if (root == RootWindow (dpy, i)) { 19521ab64890Smrg return ScreenOfDisplay (dpy, i); 19531ab64890Smrg } 19541ab64890Smrg } 19551ab64890Smrg return NULL; 19561ab64890Smrg} 19571ab64890Smrg 19581ab64890Smrg 19591ab64890Smrg#if defined(WIN32) 19601ab64890Smrg 19611ab64890Smrg/* 19621ab64890Smrg * These functions are intended to be used internally to Xlib only. 19631ab64890Smrg * These functions will always prefix the path with a DOS drive in the 19641ab64890Smrg * form "<drive-letter>:". As such, these functions are only suitable 19651ab64890Smrg * for use by Xlib function that supply a root-based path to some 19661ab64890Smrg * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will 19671ab64890Smrg * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir". 19681ab64890Smrg */ 19691ab64890Smrg 19701ab64890Smrgstatic int access_file (path, pathbuf, len_pathbuf, pathret) 19711ab64890Smrg char* path; 19721ab64890Smrg char* pathbuf; 19731ab64890Smrg int len_pathbuf; 19741ab64890Smrg char** pathret; 19751ab64890Smrg{ 19761ab64890Smrg if (access (path, F_OK) == 0) { 19771ab64890Smrg if (strlen (path) < len_pathbuf) 19781ab64890Smrg *pathret = pathbuf; 19791ab64890Smrg else 19801ab64890Smrg *pathret = Xmalloc (strlen (path) + 1); 19811ab64890Smrg if (*pathret) { 19821ab64890Smrg strcpy (*pathret, path); 19831ab64890Smrg return 1; 19841ab64890Smrg } 19851ab64890Smrg } 19861ab64890Smrg return 0; 19871ab64890Smrg} 19881ab64890Smrg 19891ab64890Smrgstatic int AccessFile (path, pathbuf, len_pathbuf, pathret) 19901ab64890Smrg char* path; 19911ab64890Smrg char* pathbuf; 19921ab64890Smrg int len_pathbuf; 19931ab64890Smrg char** pathret; 19941ab64890Smrg{ 19951ab64890Smrg unsigned long drives; 19961ab64890Smrg int i, len; 19971ab64890Smrg char* drive; 19981ab64890Smrg char buf[MAX_PATH]; 19991ab64890Smrg char* bufp; 20001ab64890Smrg 20011ab64890Smrg /* just try the "raw" name first and see if it works */ 20021ab64890Smrg if (access_file (path, pathbuf, len_pathbuf, pathret)) 20031ab64890Smrg return 1; 20041ab64890Smrg 20051ab64890Smrg /* try the places set in the environment */ 20061ab64890Smrg drive = getenv ("_XBASEDRIVE"); 20071ab64890Smrg#ifdef __UNIXOS2__ 20081ab64890Smrg if (!drive) 20091ab64890Smrg drive = getenv ("X11ROOT"); 20101ab64890Smrg#endif 20111ab64890Smrg if (!drive) 20121ab64890Smrg drive = "C:"; 20131ab64890Smrg len = strlen (drive) + strlen (path); 20141ab64890Smrg if (len < MAX_PATH) bufp = buf; 20151ab64890Smrg else bufp = Xmalloc (len + 1); 20161ab64890Smrg strcpy (bufp, drive); 20171ab64890Smrg strcat (bufp, path); 20181ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 20191ab64890Smrg if (bufp != buf) Xfree (bufp); 20201ab64890Smrg return 1; 20211ab64890Smrg } 20221ab64890Smrg 202361b2299dSmrg#ifndef __UNIXOS2__ 20241ab64890Smrg /* one last place to look */ 20251ab64890Smrg drive = getenv ("HOMEDRIVE"); 20261ab64890Smrg if (drive) { 20271ab64890Smrg len = strlen (drive) + strlen (path); 20281ab64890Smrg if (len < MAX_PATH) bufp = buf; 20291ab64890Smrg else bufp = Xmalloc (len + 1); 20301ab64890Smrg strcpy (bufp, drive); 20311ab64890Smrg strcat (bufp, path); 20321ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 20331ab64890Smrg if (bufp != buf) Xfree (bufp); 20341ab64890Smrg return 1; 20351ab64890Smrg } 20361ab64890Smrg } 20371ab64890Smrg 20381ab64890Smrg /* tried everywhere else, go fishing */ 20391ab64890Smrg#define C_DRIVE ('C' - 'A') 20401ab64890Smrg#define Z_DRIVE ('Z' - 'A') 20411ab64890Smrg /* does OS/2 (with or with gcc-emx) have getdrives? */ 20421ab64890Smrg drives = _getdrives (); 20431ab64890Smrg for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */ 20441ab64890Smrg if ((1 << i) & drives) { 20451ab64890Smrg len = 2 + strlen (path); 20461ab64890Smrg if (len < MAX_PATH) bufp = buf; 20471ab64890Smrg else bufp = Xmalloc (len + 1); 20481ab64890Smrg *bufp = 'A' + i; 20491ab64890Smrg *(bufp + 1) = ':'; 20501ab64890Smrg *(bufp + 2) = '\0'; 20511ab64890Smrg strcat (bufp, path); 20521ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 20531ab64890Smrg if (bufp != buf) Xfree (bufp); 20541ab64890Smrg return 1; 20551ab64890Smrg } 20561ab64890Smrg } 20571ab64890Smrg } 20581ab64890Smrg#endif 20591ab64890Smrg return 0; 20601ab64890Smrg} 20611ab64890Smrg 20621ab64890Smrgint _XOpenFile(path, flags) 20631ab64890Smrg _Xconst char* path; 20641ab64890Smrg int flags; 20651ab64890Smrg{ 20661ab64890Smrg char buf[MAX_PATH]; 20671ab64890Smrg char* bufp = NULL; 20681ab64890Smrg int ret = -1; 20691ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 20701ab64890Smrg 20711ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 20721ab64890Smrg ret = open (bufp, flags); 20731ab64890Smrg 20741ab64890Smrg (void) SetErrorMode (olderror); 20751ab64890Smrg 20761ab64890Smrg if (bufp != buf) Xfree (bufp); 20771ab64890Smrg 20781ab64890Smrg return ret; 20791ab64890Smrg} 20801ab64890Smrg 20811ab64890Smrgint _XOpenFileMode(path, flags, mode) 20821ab64890Smrg _Xconst char* path; 20831ab64890Smrg int flags; 20841ab64890Smrg mode_t mode; 20851ab64890Smrg{ 20861ab64890Smrg char buf[MAX_PATH]; 20871ab64890Smrg char* bufp = NULL; 20881ab64890Smrg int ret = -1; 20891ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 20901ab64890Smrg 20911ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 20921ab64890Smrg ret = open (bufp, flags, mode); 20931ab64890Smrg 20941ab64890Smrg (void) SetErrorMode (olderror); 20951ab64890Smrg 20961ab64890Smrg if (bufp != buf) Xfree (bufp); 20971ab64890Smrg 20981ab64890Smrg return ret; 20991ab64890Smrg} 21001ab64890Smrg 21011ab64890Smrgvoid* _XFopenFile(path, mode) 21021ab64890Smrg _Xconst char* path; 21031ab64890Smrg _Xconst char* mode; 21041ab64890Smrg{ 21051ab64890Smrg char buf[MAX_PATH]; 21061ab64890Smrg char* bufp = NULL; 21071ab64890Smrg void* ret = NULL; 21081ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 21091ab64890Smrg 21101ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 21111ab64890Smrg ret = fopen (bufp, mode); 21121ab64890Smrg 21131ab64890Smrg (void) SetErrorMode (olderror); 21141ab64890Smrg 21151ab64890Smrg if (bufp != buf) Xfree (bufp); 21161ab64890Smrg 21171ab64890Smrg return ret; 21181ab64890Smrg} 21191ab64890Smrg 21201ab64890Smrgint _XAccessFile(path) 21211ab64890Smrg _Xconst char* path; 21221ab64890Smrg{ 21231ab64890Smrg char buf[MAX_PATH]; 21241ab64890Smrg char* bufp; 21251ab64890Smrg int ret = -1; 21261ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 21271ab64890Smrg 21281ab64890Smrg ret = AccessFile (path, buf, MAX_PATH, &bufp); 21291ab64890Smrg 21301ab64890Smrg (void) SetErrorMode (olderror); 21311ab64890Smrg 21321ab64890Smrg if (bufp != buf) Xfree (bufp); 21331ab64890Smrg 21341ab64890Smrg return ret; 21351ab64890Smrg} 21361ab64890Smrg 21371ab64890Smrg#endif 21381ab64890Smrg 21391ab64890Smrg#ifdef WIN32 21401ab64890Smrg#undef _Xdebug 21411ab64890Smrgint _Xdebug = 0; 21421ab64890Smrgint *_Xdebug_p = &_Xdebug; 21431ab64890Smrgvoid (**_XCreateMutex_fn_p)(LockInfoPtr) = &_XCreateMutex_fn; 21441ab64890Smrgvoid (**_XFreeMutex_fn_p)(LockInfoPtr) = &_XFreeMutex_fn; 21451ab64890Smrgvoid (**_XLockMutex_fn_p)(LockInfoPtr 21461ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 21471ab64890Smrg , char * /* file */ 21481ab64890Smrg , int /* line */ 21491ab64890Smrg#endif 21501ab64890Smrg ) = &_XLockMutex_fn; 21511ab64890Smrgvoid (**_XUnlockMutex_fn_p)(LockInfoPtr 21521ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 21531ab64890Smrg , char * /* file */ 21541ab64890Smrg , int /* line */ 21551ab64890Smrg#endif 21561ab64890Smrg ) = &_XUnlockMutex_fn; 21571ab64890SmrgLockInfoPtr *_Xglobal_lock_p = &_Xglobal_lock; 21581ab64890Smrg#endif 2159