XlibInt.c revision 295fb823
11.1.1.2Sjmcneill/* 21.1Sjmcneill 31.1SjmcneillCopyright 1985, 1986, 1987, 1998 The Open Group 41.1Sjmcneill 51.1.1.2SjmcneillPermission to use, copy, modify, distribute, and sell this software and its 61.1Sjmcneilldocumentation for any purpose is hereby granted without fee, provided that 71.1Sjmcneillthe above copyright notice appear in all copies and that both that 81.1Sjmcneillcopyright notice and this permission notice appear in supporting 91.1Sjmcneilldocumentation. 101.1Sjmcneill 111.1SjmcneillThe above copyright notice and this permission notice shall be included 121.1Sjmcneillin all copies or substantial portions of the Software. 131.1Sjmcneill 141.1SjmcneillTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 151.1SjmcneillOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 161.1SjmcneillMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 171.1SjmcneillIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 181.1SjmcneillOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 191.1SjmcneillARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 201.1SjmcneillOTHER DEALINGS IN THE SOFTWARE. 211.1Sjmcneill 221.1SjmcneillExcept as contained in this notice, the name of The Open Group shall 231.1Sjmcneillnot be used in advertising or otherwise to promote the sale, use or 241.1Sjmcneillother dealings in this Software without prior written authorization 251.1Sjmcneillfrom The Open Group. 261.1Sjmcneill 271.1Sjmcneill*/ 281.1Sjmcneill 291.1Sjmcneill/* 301.1Sjmcneill * XlibInt.c - Internal support routines for the C subroutine 311.1Sjmcneill * interface library (Xlib) to the X Window System Protocol V11.0. 321.1Sjmcneill */ 331.1Sjmcneill 341.1Sjmcneill#ifdef WIN32 351.1Sjmcneill#define _XLIBINT_ 361.1Sjmcneill#endif 371.1Sjmcneill#ifdef HAVE_CONFIG_H 381.1Sjmcneill#include <config.h> 391.1Sjmcneill#endif 401.1Sjmcneill#include "Xlibint.h" 411.1Sjmcneill#include "Xprivate.h" 421.1Sjmcneill#include <X11/Xpoll.h> 431.1Sjmcneill#include <assert.h> 441.1Sjmcneill#include <stdio.h> 451.1Sjmcneill#ifdef WIN32 461.1Sjmcneill#include <direct.h> 471.1Sjmcneill#endif 481.1Sjmcneill 491.1Sjmcneill#ifdef XTHREADS 501.1Sjmcneill#include "locking.h" 511.1.1.2Sjmcneill 521.1Sjmcneill/* these pointers get initialized by XInitThreads */ 531.1SjmcneillLockInfoPtr _Xglobal_lock = NULL; 541.1Sjmcneillvoid (*_XCreateMutex_fn)(LockInfoPtr) = NULL; 551.1Sjmcneill/* struct _XCVList *(*_XCreateCVL_fn)() = NULL; */ 561.1Sjmcneillvoid (*_XFreeMutex_fn)(LockInfoPtr) = NULL; 571.1Sjmcneillvoid (*_XLockMutex_fn)( 581.1Sjmcneill LockInfoPtr /* lock */ 591.1Sjmcneill#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 601.1Sjmcneill , char * /* file */ 611.1Sjmcneill , int /* line */ 621.1Sjmcneill#endif 631.1Sjmcneill ) = NULL; 641.1Sjmcneillvoid (*_XUnlockMutex_fn)( 651.1Sjmcneill LockInfoPtr /* lock */ 661.1Sjmcneill#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 671.1Sjmcneill , char * /* file */ 681.1Sjmcneill , int /* line */ 691.1Sjmcneill#endif 701.1Sjmcneill ) = NULL; 711.1Sjmcneillxthread_t (*_Xthread_self_fn)(void) = NULL; 721.1Sjmcneill 731.1Sjmcneill#define XThread_Self() ((*_Xthread_self_fn)()) 741.1Sjmcneill 751.1Sjmcneill#endif /* XTHREADS */ 761.1Sjmcneill 771.1Sjmcneill/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX 781.1Sjmcneill * systems are broken and return EWOULDBLOCK when they should return EAGAIN 791.1Sjmcneill */ 801.1Sjmcneill#ifdef WIN32 811.1Sjmcneill#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK) 821.1Sjmcneill#else 831.1Sjmcneill#ifdef __CYGWIN__ /* Cygwin uses ENOBUFS to signal socket is full */ 841.1Sjmcneill#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) 851.1Sjmcneill#else 861.1Sjmcneill#if defined(EAGAIN) && defined(EWOULDBLOCK) 871.1Sjmcneill#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK) 881.1Sjmcneill#else 891.1Sjmcneill#ifdef EAGAIN 901.1Sjmcneill#define ETEST() (errno == EAGAIN) 911.1Sjmcneill#else 921.1Sjmcneill#define ETEST() (errno == EWOULDBLOCK) 931.1Sjmcneill#endif /* EAGAIN */ 941.1Sjmcneill#endif /* EAGAIN && EWOULDBLOCK */ 951.1Sjmcneill#endif /* __CYGWIN__ */ 961.1Sjmcneill#endif /* WIN32 */ 971.1Sjmcneill 981.1Sjmcneill#ifdef WIN32 991.1Sjmcneill#define ECHECK(err) (WSAGetLastError() == err) 1001.1Sjmcneill#define ESET(val) WSASetLastError(val) 1011.1Sjmcneill#else 1021.1Sjmcneill#ifdef __UNIXOS2__ 1031.1Sjmcneill#define ECHECK(err) (errno == err) 1041.1Sjmcneill#define ESET(val) 1051.1Sjmcneill#else 1061.1Sjmcneill#define ECHECK(err) (errno == err) 1071.1Sjmcneill#define ESET(val) errno = val 1081.1Sjmcneill#endif 1091.1Sjmcneill#endif 1101.1Sjmcneill 1111.1Sjmcneill#if defined(LOCALCONN) || defined(LACHMAN) 1121.1Sjmcneill#ifdef EMSGSIZE 1131.1Sjmcneill#define ESZTEST() (ECHECK(EMSGSIZE) || ECHECK(ERANGE)) 1141.1Sjmcneill#else 1151.1Sjmcneill#define ESZTEST() ECHECK(ERANGE) 1161.1Sjmcneill#endif 1171.1Sjmcneill#else 1181.1Sjmcneill#ifdef EMSGSIZE 1191.1Sjmcneill#define ESZTEST() ECHECK(EMSGSIZE) 1201.1Sjmcneill#endif 1211.1Sjmcneill#endif 1221.1Sjmcneill 1231.1Sjmcneill#ifdef __UNIXOS2__ 1241.1Sjmcneill#include <limits.h> 1251.1Sjmcneill#define MAX_PATH _POSIX_PATH_MAX 1261.1Sjmcneill#endif 1271.1Sjmcneill 1281.1Sjmcneill/* 1291.1Sjmcneill * The following routines are internal routines used by Xlib for protocol 1301.1Sjmcneill * packet transmission and reception. 1311.1Sjmcneill * 1321.1Sjmcneill * _XIOError(Display *) will be called if any sort of system call error occurs. 1331.1Sjmcneill * This is assumed to be a fatal condition, i.e., XIOError should not return. 1341.1Sjmcneill * 1351.1Sjmcneill * _XError(Display *, xError *) will be called whenever an X_Error event is 1361.1Sjmcneill * received. This is not assumed to be a fatal condition, i.e., it is 1371.1Sjmcneill * acceptable for this procedure to return. However, XError should NOT 1381.1Sjmcneill * perform any operations (directly or indirectly) on the DISPLAY. 1391.1Sjmcneill * 1401.1Sjmcneill * Routines declared with a return type of 'Status' return 0 on failure, 1411.1Sjmcneill * and non 0 on success. Routines with no declared return type don't 1421.1Sjmcneill * return anything. Whenever possible routines that create objects return 1431.1Sjmcneill * the object they have created. 1441.1Sjmcneill */ 1451.1Sjmcneill 1461.1Sjmcneill#define POLLFD_CACHE_SIZE 5 1471.1Sjmcneill 1481.1Sjmcneill/* initialize the struct array passed to poll() below */ 1491.1SjmcneillBool _XPollfdCacheInit( 1501.1Sjmcneill Display *dpy) 1511.1Sjmcneill{ 1521.1Sjmcneill#ifdef USE_POLL 1531.1Sjmcneill struct pollfd *pfp; 1541.1Sjmcneill 1551.1Sjmcneill pfp = (struct pollfd *)Xmalloc(POLLFD_CACHE_SIZE * sizeof(struct pollfd)); 1561.1Sjmcneill if (!pfp) 1571.1Sjmcneill return False; 1581.1Sjmcneill pfp[0].fd = dpy->fd; 1591.1Sjmcneill pfp[0].events = POLLIN; 1601.1.1.2Sjmcneill 1611.1Sjmcneill dpy->filedes = (XPointer)pfp; 1621.1Sjmcneill#endif 1631.1Sjmcneill return True; 1641.1Sjmcneill} 1651.1Sjmcneill 1661.1Sjmcneillvoid _XPollfdCacheAdd( 1671.1Sjmcneill Display *dpy, 1681.1Sjmcneill int fd) 1691.1Sjmcneill{ 1701.1Sjmcneill#ifdef USE_POLL 1711.1.1.2Sjmcneill struct pollfd *pfp = (struct pollfd *)dpy->filedes; 1721.1Sjmcneill 1731.1Sjmcneill if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { 1741.1Sjmcneill pfp[dpy->im_fd_length].fd = fd; 1751.1Sjmcneill pfp[dpy->im_fd_length].events = POLLIN; 1761.1Sjmcneill } 1771.1Sjmcneill#endif 1781.1Sjmcneill} 1791.1Sjmcneill 1801.1Sjmcneill/* ARGSUSED */ 1811.1.1.2Sjmcneillvoid _XPollfdCacheDel( 1821.1Sjmcneill Display *dpy, 1831.1Sjmcneill int fd) /* not used */ 1841.1Sjmcneill{ 1851.1Sjmcneill#ifdef USE_POLL 1861.1Sjmcneill struct pollfd *pfp = (struct pollfd *)dpy->filedes; 1871.1Sjmcneill struct _XConnectionInfo *conni; 1881.1Sjmcneill 1891.1Sjmcneill /* just recalculate whole list */ 1901.1Sjmcneill if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { 1911.1Sjmcneill int loc = 1; 1921.1.1.2Sjmcneill for (conni = dpy->im_fd_info; conni; conni=conni->next) { 1931.1Sjmcneill pfp[loc].fd = conni->fd; 1941.1Sjmcneill pfp[loc].events = POLLIN; 1951.1Sjmcneill loc++; 1961.1Sjmcneill } 1971.1Sjmcneill } 1981.1Sjmcneill#endif 1991.1Sjmcneill} 2001.1Sjmcneill 2011.1Sjmcneillstatic int sync_hazard(Display *dpy) 2021.1.1.2Sjmcneill{ 2031.1Sjmcneill unsigned long span = dpy->request - dpy->last_request_read; 2041.1Sjmcneill unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10); 2051.1Sjmcneill return span >= 65535 - hazard - 10; 2061.1Sjmcneill} 2071.1Sjmcneill 2081.1Sjmcneillstatic 2091.1Sjmcneillvoid sync_while_locked(Display *dpy) 2101.1Sjmcneill{ 2111.1Sjmcneill#ifdef XTHREADS 2121.1.1.2Sjmcneill if (dpy->lock) 2131.1Sjmcneill (*dpy->lock->user_lock_display)(dpy); 2141.1Sjmcneill#endif 2151.1Sjmcneill UnlockDisplay(dpy); 2161.1Sjmcneill SyncHandle(); 2171.1Sjmcneill InternalLockDisplay(dpy, /* don't skip user locks */ 0); 2181.1Sjmcneill#ifdef XTHREADS 2191.1Sjmcneill if (dpy->lock) 2201.1Sjmcneill (*dpy->lock->user_unlock_display)(dpy); 2211.1Sjmcneill#endif 2221.1.1.2Sjmcneill} 2231.1Sjmcneill 2241.1Sjmcneillvoid _XSeqSyncFunction( 2251.1Sjmcneill register Display *dpy) 2261.1Sjmcneill{ 2271.1Sjmcneill xGetInputFocusReply rep; 2281.1Sjmcneill register xReq *req; 2291.1Sjmcneill 2301.1Sjmcneill if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) { 2311.1Sjmcneill GetEmptyReq(GetInputFocus, req); 2321.1.1.2Sjmcneill (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); 2331.1Sjmcneill sync_while_locked(dpy); 2341.1Sjmcneill } else if (sync_hazard(dpy)) 2351.1Sjmcneill _XSetPrivSyncFunction(dpy); 2361.1Sjmcneill} 2371.1Sjmcneill 2381.1Sjmcneill/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */ 2391.1Sjmcneillstatic int 2401.1Sjmcneill_XPrivSyncFunction (Display *dpy) 2411.1Sjmcneill{ 2421.1.1.2Sjmcneill#ifdef XTHREADS 2431.1Sjmcneill assert(!dpy->lock_fns); 2441.1Sjmcneill#endif 2451.1Sjmcneill assert(dpy->synchandler == _XPrivSyncFunction); 2461.1Sjmcneill assert((dpy->flags & XlibDisplayPrivSync) != 0); 2471.1Sjmcneill dpy->synchandler = dpy->savedsynchandler; 2481.1Sjmcneill dpy->savedsynchandler = NULL; 2491.1Sjmcneill dpy->flags &= ~XlibDisplayPrivSync; 2501.1Sjmcneill if(dpy->synchandler) 2511.1Sjmcneill dpy->synchandler(dpy); 2521.1.1.2Sjmcneill _XIDHandler(dpy); 2531.1Sjmcneill _XSeqSyncFunction(dpy); 2541.1Sjmcneill return 0; 2551.1Sjmcneill} 2561.1Sjmcneill 2571.1Sjmcneillvoid _XSetPrivSyncFunction(Display *dpy) 2581.1Sjmcneill{ 2591.1Sjmcneill#ifdef XTHREADS 2601.1Sjmcneill if (dpy->lock_fns) 2611.1Sjmcneill return; 2621.1.1.2Sjmcneill#endif 2631.1Sjmcneill if (!(dpy->flags & XlibDisplayPrivSync)) { 2641.1Sjmcneill dpy->savedsynchandler = dpy->synchandler; 2651.1Sjmcneill dpy->synchandler = _XPrivSyncFunction; 2661.1Sjmcneill dpy->flags |= XlibDisplayPrivSync; 2671.1Sjmcneill } 2681.1Sjmcneill} 2691.1Sjmcneill 2701.1Sjmcneillvoid _XSetSeqSyncFunction(Display *dpy) 2711.1Sjmcneill{ 2721.1.1.2Sjmcneill if (sync_hazard(dpy)) 2731.1Sjmcneill _XSetPrivSyncFunction (dpy); 2741.1Sjmcneill} 2751.1Sjmcneill 2761.1Sjmcneill#ifdef LONG64 2771.1Sjmcneillvoid _XRead32( 2781.1Sjmcneill Display *dpy, 2791.1Sjmcneill register long *data, 2801.1Sjmcneill long len) 2811.1Sjmcneill{ 2821.1.1.2Sjmcneill register int *buf; 2831.1Sjmcneill register long i; 2841.1Sjmcneill 2851.1Sjmcneill if (len) { 2861.1Sjmcneill (void) _XRead(dpy, (char *)data, len); 2871.1Sjmcneill i = len >> 2; 2881.1Sjmcneill buf = (int *)data + i; 2891.1Sjmcneill data += i; 2901.1Sjmcneill while (--i >= 0) 2911.1Sjmcneill *--data = *--buf; 2921.1.1.2Sjmcneill } 2931.1Sjmcneill} 2941.1Sjmcneill#endif /* LONG64 */ 2951.1Sjmcneill 2961.1Sjmcneill#ifdef WORD64 2971.1Sjmcneill 2981.1Sjmcneill/* 2991.1Sjmcneill * XXX This is a *really* stupid way of doing this.... 3001.1Sjmcneill * PACKBUFFERSIZE must be a multiple of 4. 3011.1Sjmcneill */ 3021.1.1.2Sjmcneill 3031.1Sjmcneill#define PACKBUFFERSIZE 4096 3041.1Sjmcneill 3051.1Sjmcneill 3061.1Sjmcneill/* 3071.1Sjmcneill * _XRead32 - Read bytes from the socket unpacking each 32 bits 3081.1Sjmcneill * into a long (64 bits on a CRAY computer). 3091.1Sjmcneill * 3101.1Sjmcneill */ 3111.1Sjmcneillstatic void _doXRead32( 3121.1.1.2Sjmcneill register Display *dpy, 3131.1Sjmcneill register long *data 3141.1Sjmcneill register long size, 3151.1Sjmcneill register char *packbuffer) 3161.1Sjmcneill{ 3171.1Sjmcneill long *lpack,*lp; 3181.1Sjmcneill long mask32 = 0x00000000ffffffff; 3191.1Sjmcneill long maskw, nwords, i, bits; 3201.1Sjmcneill 3211.1Sjmcneill _XReadPad (dpy, packbuffer, size); 3221.1.1.2Sjmcneill 3231.1Sjmcneill lp = data; 3241.1Sjmcneill lpack = (long *) packbuffer; 3251.1Sjmcneill nwords = size >> 2; 3261.1Sjmcneill bits = 32; 3271.1Sjmcneill 3281.1Sjmcneill for(i=0;i<nwords;i++){ 3291.1Sjmcneill maskw = mask32 << bits; 3301.1Sjmcneill *lp++ = ( *lpack & maskw ) >> bits; 3311.1Sjmcneill bits = bits ^32; 3321.1.1.2Sjmcneill if(bits){ 3331.1Sjmcneill lpack++; 3341.1Sjmcneill } 3351.1Sjmcneill } 3361.1Sjmcneill} 3371.1Sjmcneill 3381.1Sjmcneillvoid _XRead32( 3391.1Sjmcneill Display *dpy, 3401.1Sjmcneill long *data, 3411.1Sjmcneill long len) 3421.1.1.2Sjmcneill{ 3431.1Sjmcneill char packbuffer[PACKBUFFERSIZE]; 3441.1Sjmcneill unsigned nunits = PACKBUFFERSIZE >> 2; 3451.1Sjmcneill 3461.1Sjmcneill for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { 3471.1Sjmcneill _doXRead32 (dpy, data, PACKBUFFERSIZE, packbuffer); 3481.1Sjmcneill } 3491.1Sjmcneill if (len) _doXRead32 (dpy, data, len, packbuffer); 3501.1Sjmcneill} 3511.1Sjmcneill 3521.1.1.2Sjmcneill 3531.1Sjmcneill 3541.1Sjmcneill/* 3551.1Sjmcneill * _XRead16 - Read bytes from the socket unpacking each 16 bits 3561.1Sjmcneill * into a long (64 bits on a CRAY computer). 3571.1Sjmcneill * 3581.1Sjmcneill */ 3591.1Sjmcneillstatic _doXRead16( 3601.1Sjmcneill register Display *dpy, 3611.1Sjmcneill register short *data, 3621.1.1.2Sjmcneill register long size, 3631.1Sjmcneill char *packbuffer) 3641.1Sjmcneill{ 3651.1Sjmcneill long *lpack,*lp; 3661.1Sjmcneill long mask16 = 0x000000000000ffff; 3671.1Sjmcneill long maskw, nwords, i, bits; 3681.1Sjmcneill 3691.1Sjmcneill (void) _XRead(dpy,packbuffer,size); /* don't do a padded read... */ 3701.1Sjmcneill 3711.1Sjmcneill lp = (long *) data; 3721.1.1.2Sjmcneill lpack = (long *) packbuffer; 3731.1Sjmcneill nwords = size >> 1; /* number of 16 bit words to be unpacked */ 3741.1Sjmcneill bits = 48; 3751.1Sjmcneill for(i=0;i<nwords;i++){ 3761.1Sjmcneill maskw = mask16 << bits; 3771.1Sjmcneill *lp++ = ( *lpack & maskw ) >> bits; 3781.1Sjmcneill bits -= 16; 3791.1Sjmcneill if(bits < 0){ 3801.1Sjmcneill lpack++; 3811.1Sjmcneill bits = 48; 3821.1.1.2Sjmcneill } 3831.1Sjmcneill } 3841.1Sjmcneill} 3851.1Sjmcneill 3861.1Sjmcneillvoid _XRead16( 3871.1Sjmcneill Display *dpy, 3881.1Sjmcneill short *data, 3891.1Sjmcneill long len) 3901.1Sjmcneill{ 3911.1Sjmcneill char packbuffer[PACKBUFFERSIZE]; 3921.1.1.2Sjmcneill unsigned nunits = PACKBUFFERSIZE >> 1; 3931.1Sjmcneill 3941.1Sjmcneill for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { 3951.1Sjmcneill _doXRead16 (dpy, data, PACKBUFFERSIZE, packbuffer); 3961.1Sjmcneill } 3971.1Sjmcneill if (len) _doXRead16 (dpy, data, len, packbuffer); 3981.1Sjmcneill} 3991.1Sjmcneill 4001.1Sjmcneillvoid _XRead16Pad( 4011.1Sjmcneill Display *dpy, 4021.1.1.2Sjmcneill short *data, 4031.1Sjmcneill long size) 4041.1Sjmcneill{ 4051.1Sjmcneill int slop = (size & 3); 4061.1Sjmcneill short slopbuf[3]; 4071.1Sjmcneill 4081.1Sjmcneill _XRead16 (dpy, data, size); 4091.1Sjmcneill if (slop > 0) { 4101.1Sjmcneill _XRead16 (dpy, slopbuf, 4 - slop); 4111.1.1.3Sskrll } 4121.1.1.3Sskrll} 4131.1.1.3Sskrll#endif /* WORD64 */ 4141.1.1.3Sskrll 4151.1.1.3Sskrll/* 4161.1.1.3Sskrll * The hard part about this is that we only get 16 bits from a reply. 4171.1.1.3Sskrll * We have three values that will march along, with the following invariant: 4181.1.1.3Sskrll * dpy->last_request_read <= rep->sequenceNumber <= dpy->request 4191.1.1.3Sskrll * We have to keep 4201.1.1.3Sskrll * dpy->request - dpy->last_request_read < 2^16 4211.1.1.3Sskrll * or else we won't know for sure what value to use in events. We do this 4221.1.1.3Sskrll * by forcing syncs when we get close. 4231.1.1.3Sskrll */ 4241.1.1.3Sskrll 4251.1.1.3Sskrllunsigned long 4261.1.1.3Sskrll_XSetLastRequestRead( 4271.1.1.3Sskrll register Display *dpy, 4281.1.1.3Sskrll register xGenericReply *rep) 4291.1.1.3Sskrll{ 4301.1.1.3Sskrll register unsigned long newseq, lastseq; 4311.1.1.3Sskrll 4321.1.1.3Sskrll lastseq = dpy->last_request_read; 4331.1.1.3Sskrll /* 4341.1.1.3Sskrll * KeymapNotify has no sequence number, but is always guaranteed 4351.1.1.3Sskrll * to immediately follow another event, except when generated via 4361.1.1.3Sskrll * SendEvent (hmmm). 4371.1.1.3Sskrll */ 4381.1Sjmcneill if ((rep->type & 0x7f) == KeymapNotify) 439 return(lastseq); 440 441 newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber; 442 443 if (newseq < lastseq) { 444 newseq += 0x10000; 445 if (newseq > dpy->request) { 446 (void) fprintf (stderr, 447 "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n", 448 newseq, dpy->request, 449 (unsigned int) rep->type); 450 newseq -= 0x10000; 451 } 452 } 453 454 dpy->last_request_read = newseq; 455 return(newseq); 456} 457 458/* 459 * Support for internal connections, such as an IM might use. 460 * By Stephen Gildea, X Consortium, September 1993 461 */ 462 463/* _XRegisterInternalConnection 464 * Each IM (or Xlib extension) that opens a file descriptor that Xlib should 465 * include in its select/poll mask must call this function to register the 466 * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch 467 * will also be called. 468 * 469 * Whenever Xlib detects input available on fd, it will call callback 470 * with call_data to process it. If non-Xlib code calls select/poll 471 * and detects input available, it must call XProcessInternalConnection, 472 * which will call the associated callback. 473 * 474 * Non-Xlib code can learn about these additional fds by calling 475 * XInternalConnectionNumbers or, more typically, by registering 476 * a XConnectionWatchProc with XAddConnectionWatch 477 * to be called when fds are registered or unregistered. 478 * 479 * Returns True if registration succeeded, False if not, typically 480 * because could not allocate memory. 481 * Assumes Display locked when called. 482 */ 483Status 484_XRegisterInternalConnection( 485 Display* dpy, 486 int fd, 487 _XInternalConnectionProc callback, 488 XPointer call_data 489) 490{ 491 struct _XConnectionInfo *new_conni, **iptr; 492 struct _XConnWatchInfo *watchers; 493 XPointer *wd; 494 495 new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo)); 496 if (!new_conni) 497 return 0; 498 new_conni->watch_data = (XPointer *)Xmalloc(dpy->watcher_count * sizeof(XPointer)); 499 if (!new_conni->watch_data) { 500 Xfree(new_conni); 501 return 0; 502 } 503 new_conni->fd = fd; 504 new_conni->read_callback = callback; 505 new_conni->call_data = call_data; 506 new_conni->next = NULL; 507 /* link new structure onto end of list */ 508 for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next) 509 ; 510 *iptr = new_conni; 511 dpy->im_fd_length++; 512 _XPollfdCacheAdd(dpy, fd); 513 514 for (watchers=dpy->conn_watchers, wd=new_conni->watch_data; 515 watchers; 516 watchers=watchers->next, wd++) { 517 *wd = NULL; /* for cleanliness */ 518 (*watchers->fn) (dpy, watchers->client_data, fd, True, wd); 519 } 520 521 return 1; 522} 523 524/* _XUnregisterInternalConnection 525 * Each IM (or Xlib extension) that closes a file descriptor previously 526 * registered with _XRegisterInternalConnection must call this function. 527 * Any XConnectionWatchProc registered by XAddConnectionWatch 528 * will also be called. 529 * 530 * Assumes Display locked when called. 531 */ 532void 533_XUnregisterInternalConnection( 534 Display* dpy, 535 int fd 536) 537{ 538 struct _XConnectionInfo *info_list, **prev; 539 struct _XConnWatchInfo *watch; 540 XPointer *wd; 541 542 for (prev = &dpy->im_fd_info; (info_list = *prev); 543 prev = &info_list->next) { 544 if (info_list->fd == fd) { 545 *prev = info_list->next; 546 dpy->im_fd_length--; 547 for (watch=dpy->conn_watchers, wd=info_list->watch_data; 548 watch; 549 watch=watch->next, wd++) { 550 (*watch->fn) (dpy, watch->client_data, fd, False, wd); 551 } 552 if (info_list->watch_data) 553 Xfree (info_list->watch_data); 554 Xfree (info_list); 555 break; 556 } 557 } 558 _XPollfdCacheDel(dpy, fd); 559} 560 561/* XInternalConnectionNumbers 562 * Returns an array of fds and an array of corresponding call data. 563 * Typically a XConnectionWatchProc registered with XAddConnectionWatch 564 * will be used instead of this function to discover 565 * additional fds to include in the select/poll mask. 566 * 567 * The list is allocated with Xmalloc and should be freed by the caller 568 * with Xfree; 569 */ 570Status 571XInternalConnectionNumbers( 572 Display *dpy, 573 int **fd_return, 574 int *count_return 575) 576{ 577 int count; 578 struct _XConnectionInfo *info_list; 579 int *fd_list; 580 581 LockDisplay(dpy); 582 count = 0; 583 for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) 584 count++; 585 fd_list = (int*) Xmalloc (count * sizeof(int)); 586 if (!fd_list) { 587 UnlockDisplay(dpy); 588 return 0; 589 } 590 count = 0; 591 for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 592 fd_list[count] = info_list->fd; 593 count++; 594 } 595 UnlockDisplay(dpy); 596 597 *fd_return = fd_list; 598 *count_return = count; 599 return 1; 600} 601 602void _XProcessInternalConnection( 603 Display *dpy, 604 struct _XConnectionInfo *conn_info) 605{ 606 dpy->flags |= XlibDisplayProcConni; 607 UnlockDisplay(dpy); 608 (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data); 609 LockDisplay(dpy); 610 dpy->flags &= ~XlibDisplayProcConni; 611} 612 613/* XProcessInternalConnection 614 * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection 615 * for this fd. 616 * The Display is NOT locked during the call. 617 */ 618void 619XProcessInternalConnection( 620 Display* dpy, 621 int fd 622) 623{ 624 struct _XConnectionInfo *info_list; 625 626 LockDisplay(dpy); 627 for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 628 if (info_list->fd == fd) { 629 _XProcessInternalConnection(dpy, info_list); 630 break; 631 } 632 } 633 UnlockDisplay(dpy); 634} 635 636/* XAddConnectionWatch 637 * Register a callback to be called whenever _XRegisterInternalConnection 638 * or _XUnregisterInternalConnection is called. 639 * Callbacks are called with the Display locked. 640 * If any connections are already registered, the callback is immediately 641 * called for each of them. 642 */ 643Status 644XAddConnectionWatch( 645 Display* dpy, 646 XConnectionWatchProc callback, 647 XPointer client_data 648) 649{ 650 struct _XConnWatchInfo *new_watcher, **wptr; 651 struct _XConnectionInfo *info_list; 652 XPointer *wd_array; 653 654 LockDisplay(dpy); 655 656 /* allocate new watch data */ 657 for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 658 wd_array = (XPointer *)Xrealloc((char *)info_list->watch_data, 659 (dpy->watcher_count + 1) * 660 sizeof(XPointer)); 661 if (!wd_array) { 662 UnlockDisplay(dpy); 663 return 0; 664 } 665 wd_array[dpy->watcher_count] = NULL; /* for cleanliness */ 666 } 667 668 new_watcher = (struct _XConnWatchInfo*)Xmalloc(sizeof(struct _XConnWatchInfo)); 669 if (!new_watcher) { 670 UnlockDisplay(dpy); 671 return 0; 672 } 673 new_watcher->fn = callback; 674 new_watcher->client_data = client_data; 675 new_watcher->next = NULL; 676 677 /* link new structure onto end of list */ 678 for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next) 679 ; 680 *wptr = new_watcher; 681 dpy->watcher_count++; 682 683 /* call new watcher on all currently registered fds */ 684 for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 685 (*callback) (dpy, client_data, info_list->fd, True, 686 info_list->watch_data + dpy->watcher_count - 1); 687 } 688 689 UnlockDisplay(dpy); 690 return 1; 691} 692 693/* XRemoveConnectionWatch 694 * Unregister a callback registered by XAddConnectionWatch. 695 * Both callback and client_data must match what was passed to 696 * XAddConnectionWatch. 697 */ 698void 699XRemoveConnectionWatch( 700 Display* dpy, 701 XConnectionWatchProc callback, 702 XPointer client_data 703) 704{ 705 struct _XConnWatchInfo *watch; 706 struct _XConnWatchInfo *previous = NULL; 707 struct _XConnectionInfo *conni; 708 int counter = 0; 709 710 LockDisplay(dpy); 711 for (watch=dpy->conn_watchers; watch; watch=watch->next) { 712 if (watch->fn == callback && watch->client_data == client_data) { 713 if (previous) 714 previous->next = watch->next; 715 else 716 dpy->conn_watchers = watch->next; 717 Xfree (watch); 718 dpy->watcher_count--; 719 /* remove our watch_data for each connection */ 720 for (conni=dpy->im_fd_info; conni; conni=conni->next) { 721 /* don't bother realloc'ing; these arrays are small anyway */ 722 /* overlapping */ 723 memmove(conni->watch_data+counter, 724 conni->watch_data+counter+1, 725 dpy->watcher_count - counter); 726 } 727 break; 728 } 729 previous = watch; 730 counter++; 731 } 732 UnlockDisplay(dpy); 733} 734 735/* end of internal connections support */ 736 737/* Cookie jar implementation 738 dpy->cookiejar is a linked list. _XEnq receives the events but leaves 739 them in the normal EQ. _XStoreEvent returns the cookie event (minus 740 data pointer) and adds it to the cookiejar. _XDeq just removes 741 the entry like any other event but resets the data pointer for 742 cookie events (to avoid double-free, the memory is re-used by Xlib). 743 744 _XFetchEventCookie (called from XGetEventData) removes a cookie from the 745 jar. _XFreeEventCookies removes all unclaimed cookies from the jar 746 (called by XNextEvent). 747 748 _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the 749 normal EQ. 750 */ 751 752#include "utlist.h" 753struct stored_event { 754 XGenericEventCookie ev; 755 struct stored_event *prev; 756 struct stored_event *next; 757}; 758 759Bool 760_XIsEventCookie(Display *dpy, XEvent *ev) 761{ 762 return (ev->xcookie.type == GenericEvent && 763 dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL); 764} 765 766/** 767 * Free all events in the event list. 768 */ 769void 770_XFreeEventCookies(Display *dpy) 771{ 772 struct stored_event **head, *e, *tmp; 773 774 if (!dpy->cookiejar) 775 return; 776 777 head = (struct stored_event**)&dpy->cookiejar; 778 779 DL_FOREACH_SAFE(*head, e, tmp) { 780 XFree(e->ev.data); 781 XFree(e); 782 if (dpy->cookiejar == e) 783 dpy->cookiejar = NULL; 784 } 785} 786 787/** 788 * Add an event to the display's event list. This event must be freed on the 789 * next call to XNextEvent(). 790 */ 791void 792_XStoreEventCookie(Display *dpy, XEvent *event) 793{ 794 XGenericEventCookie* cookie = &event->xcookie; 795 struct stored_event **head, *add; 796 797 if (!_XIsEventCookie(dpy, event)) 798 return; 799 800 head = (struct stored_event**)(&dpy->cookiejar); 801 802 add = Xmalloc(sizeof(struct stored_event)); 803 if (!add) { 804 ESET(ENOMEM); 805 _XIOError(dpy); 806 } 807 add->ev = *cookie; 808 DL_APPEND(*head, add); 809 cookie->data = NULL; /* don't return data yet, must be claimed */ 810} 811 812/** 813 * Return the event with the given cookie and remove it from the list. 814 */ 815Bool 816_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev) 817{ 818 Bool ret = False; 819 struct stored_event **head, *event; 820 head = (struct stored_event**)&dpy->cookiejar; 821 822 if (!_XIsEventCookie(dpy, (XEvent*)ev)) 823 return ret; 824 825 DL_FOREACH(*head, event) { 826 if (event->ev.cookie == ev->cookie && 827 event->ev.extension == ev->extension && 828 event->ev.evtype == ev->evtype) { 829 *ev = event->ev; 830 DL_DELETE(*head, event); 831 Xfree(event); 832 ret = True; 833 break; 834 } 835 } 836 837 return ret; 838} 839 840Bool 841_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out) 842{ 843 Bool ret = False; 844 int extension; 845 846 if (!_XIsEventCookie(dpy, (XEvent*)in) || !out) 847 return ret; 848 849 extension = in->extension & 0x7F; 850 851 if (!dpy->generic_event_copy_vec[extension]) 852 return ret; 853 854 ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out)); 855 out->cookie = ret ? ++dpy->next_cookie : 0; 856 return ret; 857} 858 859 860/* 861 * _XEnq - Place event packets on the display's queue. 862 * note that no squishing of move events in V11, since there 863 * is pointer motion hints.... 864 */ 865void _XEnq( 866 register Display *dpy, 867 register xEvent *event) 868{ 869 register _XQEvent *qelt; 870 int type, extension; 871 872 if ((qelt = dpy->qfree)) { 873 /* If dpy->qfree is non-NULL do this, else malloc a new one. */ 874 dpy->qfree = qelt->next; 875 } 876 else if ((qelt = 877 (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) { 878 /* Malloc call failed! */ 879 ESET(ENOMEM); 880 _XIOError(dpy); 881 } 882 qelt->next = NULL; 883 884 type = event->u.u.type & 0177; 885 extension = ((xGenericEvent*)event)->extension; 886 887 qelt->event.type = type; 888 /* If an extension has registerd a generic_event_vec handler, then 889 * it can handle event cookies. Otherwise, proceed with the normal 890 * event handlers. 891 * 892 * If the generic_event_vec is called, qelt->event is a event cookie 893 * with the data pointer and the "free" pointer set. Data pointer is 894 * some memory allocated by the extension. 895 */ 896 if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) { 897 XGenericEventCookie *cookie = &qelt->event.xcookie; 898 (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event); 899 cookie->cookie = ++dpy->next_cookie; 900 901 qelt->qserial_num = dpy->next_event_serial_num++; 902 if (dpy->tail) dpy->tail->next = qelt; 903 else dpy->head = qelt; 904 905 dpy->tail = qelt; 906 dpy->qlen++; 907 } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) { 908 qelt->qserial_num = dpy->next_event_serial_num++; 909 if (dpy->tail) dpy->tail->next = qelt; 910 else dpy->head = qelt; 911 912 dpy->tail = qelt; 913 dpy->qlen++; 914 } else { 915 /* ignored, or stashed away for many-to-one compression */ 916 qelt->next = dpy->qfree; 917 dpy->qfree = qelt; 918 } 919} 920 921/* 922 * _XDeq - Remove event packet from the display's queue. 923 */ 924void _XDeq( 925 register Display *dpy, 926 register _XQEvent *prev, /* element before qelt */ 927 register _XQEvent *qelt) /* element to be unlinked */ 928{ 929 if (prev) { 930 if ((prev->next = qelt->next) == NULL) 931 dpy->tail = prev; 932 } else { 933 /* no prev, so removing first elt */ 934 if ((dpy->head = qelt->next) == NULL) 935 dpy->tail = NULL; 936 } 937 qelt->qserial_num = 0; 938 qelt->next = dpy->qfree; 939 dpy->qfree = qelt; 940 dpy->qlen--; 941 942 if (_XIsEventCookie(dpy, &qelt->event)) { 943 XGenericEventCookie* cookie = &qelt->event.xcookie; 944 /* dpy->qfree is re-used, reset memory to avoid double free on 945 * _XFreeDisplayStructure */ 946 cookie->data = NULL; 947 } 948} 949 950/* 951 * EventToWire in separate file in that often not needed. 952 */ 953 954/*ARGSUSED*/ 955Bool 956_XUnknownWireEvent( 957 register Display *dpy, /* pointer to display structure */ 958 register XEvent *re, /* pointer to where event should be reformatted */ 959 register xEvent *event) /* wire protocol event */ 960{ 961#ifdef notdef 962 (void) fprintf(stderr, 963 "Xlib: unhandled wire event! event number = %d, display = %x\n.", 964 event->u.u.type, dpy); 965#endif 966 return(False); 967} 968 969Bool 970_XUnknownWireEventCookie( 971 Display *dpy, /* pointer to display structure */ 972 XGenericEventCookie *re, /* pointer to where event should be reformatted */ 973 xEvent *event) /* wire protocol event */ 974{ 975#ifdef notdef 976 fprintf(stderr, 977 "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.", 978 ((xGenericEvent*)event)->extension, dpy); 979#endif 980 return(False); 981} 982 983Bool 984_XUnknownCopyEventCookie( 985 Display *dpy, /* pointer to display structure */ 986 XGenericEventCookie *in, /* source */ 987 XGenericEventCookie *out) /* destination */ 988{ 989#ifdef notdef 990 fprintf(stderr, 991 "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.", 992 in->extension, dpy); 993#endif 994 return(False); 995} 996 997/*ARGSUSED*/ 998Status 999_XUnknownNativeEvent( 1000 register Display *dpy, /* pointer to display structure */ 1001 register XEvent *re, /* pointer to where event should be reformatted */ 1002 register xEvent *event) /* wire protocol event */ 1003{ 1004#ifdef notdef 1005 (void) fprintf(stderr, 1006 "Xlib: unhandled native event! event number = %d, display = %x\n.", 1007 re->type, dpy); 1008#endif 1009 return(0); 1010} 1011/* 1012 * reformat a wire event into an XEvent structure of the right type. 1013 */ 1014Bool 1015_XWireToEvent( 1016 register Display *dpy, /* pointer to display structure */ 1017 register XEvent *re, /* pointer to where event should be reformatted */ 1018 register xEvent *event) /* wire protocol event */ 1019{ 1020 1021 re->type = event->u.u.type & 0x7f; 1022 ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy, 1023 (xGenericReply *)event); 1024 ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0); 1025 ((XAnyEvent *)re)->display = dpy; 1026 1027 /* Ignore the leading bit of the event type since it is set when a 1028 client sends an event rather than the server. */ 1029 1030 switch (event-> u.u.type & 0177) { 1031 case KeyPress: 1032 case KeyRelease: 1033 { 1034 register XKeyEvent *ev = (XKeyEvent*) re; 1035 ev->root = event->u.keyButtonPointer.root; 1036 ev->window = event->u.keyButtonPointer.event; 1037 ev->subwindow = event->u.keyButtonPointer.child; 1038 ev->time = event->u.keyButtonPointer.time; 1039 ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 1040 ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 1041 ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 1042 ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 1043 ev->state = event->u.keyButtonPointer.state; 1044 ev->same_screen = event->u.keyButtonPointer.sameScreen; 1045 ev->keycode = event->u.u.detail; 1046 } 1047 break; 1048 case ButtonPress: 1049 case ButtonRelease: 1050 { 1051 register XButtonEvent *ev = (XButtonEvent *) re; 1052 ev->root = event->u.keyButtonPointer.root; 1053 ev->window = event->u.keyButtonPointer.event; 1054 ev->subwindow = event->u.keyButtonPointer.child; 1055 ev->time = event->u.keyButtonPointer.time; 1056 ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 1057 ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 1058 ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 1059 ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 1060 ev->state = event->u.keyButtonPointer.state; 1061 ev->same_screen = event->u.keyButtonPointer.sameScreen; 1062 ev->button = event->u.u.detail; 1063 } 1064 break; 1065 case MotionNotify: 1066 { 1067 register XMotionEvent *ev = (XMotionEvent *)re; 1068 ev->root = event->u.keyButtonPointer.root; 1069 ev->window = event->u.keyButtonPointer.event; 1070 ev->subwindow = event->u.keyButtonPointer.child; 1071 ev->time = event->u.keyButtonPointer.time; 1072 ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 1073 ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 1074 ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 1075 ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 1076 ev->state = event->u.keyButtonPointer.state; 1077 ev->same_screen = event->u.keyButtonPointer.sameScreen; 1078 ev->is_hint = event->u.u.detail; 1079 } 1080 break; 1081 case EnterNotify: 1082 case LeaveNotify: 1083 { 1084 register XCrossingEvent *ev = (XCrossingEvent *) re; 1085 ev->root = event->u.enterLeave.root; 1086 ev->window = event->u.enterLeave.event; 1087 ev->subwindow = event->u.enterLeave.child; 1088 ev->time = event->u.enterLeave.time; 1089 ev->x = cvtINT16toInt(event->u.enterLeave.eventX); 1090 ev->y = cvtINT16toInt(event->u.enterLeave.eventY); 1091 ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX); 1092 ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY); 1093 ev->state = event->u.enterLeave.state; 1094 ev->mode = event->u.enterLeave.mode; 1095 ev->same_screen = (event->u.enterLeave.flags & 1096 ELFlagSameScreen) && True; 1097 ev->focus = (event->u.enterLeave.flags & 1098 ELFlagFocus) && True; 1099 ev->detail = event->u.u.detail; 1100 } 1101 break; 1102 case FocusIn: 1103 case FocusOut: 1104 { 1105 register XFocusChangeEvent *ev = (XFocusChangeEvent *) re; 1106 ev->window = event->u.focus.window; 1107 ev->mode = event->u.focus.mode; 1108 ev->detail = event->u.u.detail; 1109 } 1110 break; 1111 case KeymapNotify: 1112 { 1113 register XKeymapEvent *ev = (XKeymapEvent *) re; 1114 ev->window = None; 1115 memcpy(&ev->key_vector[1], 1116 (char *)((xKeymapEvent *) event)->map, 1117 sizeof (((xKeymapEvent *) event)->map)); 1118 } 1119 break; 1120 case Expose: 1121 { 1122 register XExposeEvent *ev = (XExposeEvent *) re; 1123 ev->window = event->u.expose.window; 1124 ev->x = event->u.expose.x; 1125 ev->y = event->u.expose.y; 1126 ev->width = event->u.expose.width; 1127 ev->height = event->u.expose.height; 1128 ev->count = event->u.expose.count; 1129 } 1130 break; 1131 case GraphicsExpose: 1132 { 1133 register XGraphicsExposeEvent *ev = 1134 (XGraphicsExposeEvent *) re; 1135 ev->drawable = event->u.graphicsExposure.drawable; 1136 ev->x = event->u.graphicsExposure.x; 1137 ev->y = event->u.graphicsExposure.y; 1138 ev->width = event->u.graphicsExposure.width; 1139 ev->height = event->u.graphicsExposure.height; 1140 ev->count = event->u.graphicsExposure.count; 1141 ev->major_code = event->u.graphicsExposure.majorEvent; 1142 ev->minor_code = event->u.graphicsExposure.minorEvent; 1143 } 1144 break; 1145 case NoExpose: 1146 { 1147 register XNoExposeEvent *ev = (XNoExposeEvent *) re; 1148 ev->drawable = event->u.noExposure.drawable; 1149 ev->major_code = event->u.noExposure.majorEvent; 1150 ev->minor_code = event->u.noExposure.minorEvent; 1151 } 1152 break; 1153 case VisibilityNotify: 1154 { 1155 register XVisibilityEvent *ev = (XVisibilityEvent *) re; 1156 ev->window = event->u.visibility.window; 1157 ev->state = event->u.visibility.state; 1158 } 1159 break; 1160 case CreateNotify: 1161 { 1162 register XCreateWindowEvent *ev = 1163 (XCreateWindowEvent *) re; 1164 ev->window = event->u.createNotify.window; 1165 ev->parent = event->u.createNotify.parent; 1166 ev->x = cvtINT16toInt(event->u.createNotify.x); 1167 ev->y = cvtINT16toInt(event->u.createNotify.y); 1168 ev->width = event->u.createNotify.width; 1169 ev->height = event->u.createNotify.height; 1170 ev->border_width = event->u.createNotify.borderWidth; 1171 ev->override_redirect = event->u.createNotify.override; 1172 } 1173 break; 1174 case DestroyNotify: 1175 { 1176 register XDestroyWindowEvent *ev = 1177 (XDestroyWindowEvent *) re; 1178 ev->window = event->u.destroyNotify.window; 1179 ev->event = event->u.destroyNotify.event; 1180 } 1181 break; 1182 case UnmapNotify: 1183 { 1184 register XUnmapEvent *ev = (XUnmapEvent *) re; 1185 ev->window = event->u.unmapNotify.window; 1186 ev->event = event->u.unmapNotify.event; 1187 ev->from_configure = event->u.unmapNotify.fromConfigure; 1188 } 1189 break; 1190 case MapNotify: 1191 { 1192 register XMapEvent *ev = (XMapEvent *) re; 1193 ev->window = event->u.mapNotify.window; 1194 ev->event = event->u.mapNotify.event; 1195 ev->override_redirect = event->u.mapNotify.override; 1196 } 1197 break; 1198 case MapRequest: 1199 { 1200 register XMapRequestEvent *ev = (XMapRequestEvent *) re; 1201 ev->window = event->u.mapRequest.window; 1202 ev->parent = event->u.mapRequest.parent; 1203 } 1204 break; 1205 case ReparentNotify: 1206 { 1207 register XReparentEvent *ev = (XReparentEvent *) re; 1208 ev->event = event->u.reparent.event; 1209 ev->window = event->u.reparent.window; 1210 ev->parent = event->u.reparent.parent; 1211 ev->x = cvtINT16toInt(event->u.reparent.x); 1212 ev->y = cvtINT16toInt(event->u.reparent.y); 1213 ev->override_redirect = event->u.reparent.override; 1214 } 1215 break; 1216 case ConfigureNotify: 1217 { 1218 register XConfigureEvent *ev = (XConfigureEvent *) re; 1219 ev->event = event->u.configureNotify.event; 1220 ev->window = event->u.configureNotify.window; 1221 ev->above = event->u.configureNotify.aboveSibling; 1222 ev->x = cvtINT16toInt(event->u.configureNotify.x); 1223 ev->y = cvtINT16toInt(event->u.configureNotify.y); 1224 ev->width = event->u.configureNotify.width; 1225 ev->height = event->u.configureNotify.height; 1226 ev->border_width = event->u.configureNotify.borderWidth; 1227 ev->override_redirect = event->u.configureNotify.override; 1228 } 1229 break; 1230 case ConfigureRequest: 1231 { 1232 register XConfigureRequestEvent *ev = 1233 (XConfigureRequestEvent *) re; 1234 ev->window = event->u.configureRequest.window; 1235 ev->parent = event->u.configureRequest.parent; 1236 ev->above = event->u.configureRequest.sibling; 1237 ev->x = cvtINT16toInt(event->u.configureRequest.x); 1238 ev->y = cvtINT16toInt(event->u.configureRequest.y); 1239 ev->width = event->u.configureRequest.width; 1240 ev->height = event->u.configureRequest.height; 1241 ev->border_width = event->u.configureRequest.borderWidth; 1242 ev->value_mask = event->u.configureRequest.valueMask; 1243 ev->detail = event->u.u.detail; 1244 } 1245 break; 1246 case GravityNotify: 1247 { 1248 register XGravityEvent *ev = (XGravityEvent *) re; 1249 ev->window = event->u.gravity.window; 1250 ev->event = event->u.gravity.event; 1251 ev->x = cvtINT16toInt(event->u.gravity.x); 1252 ev->y = cvtINT16toInt(event->u.gravity.y); 1253 } 1254 break; 1255 case ResizeRequest: 1256 { 1257 register XResizeRequestEvent *ev = 1258 (XResizeRequestEvent *) re; 1259 ev->window = event->u.resizeRequest.window; 1260 ev->width = event->u.resizeRequest.width; 1261 ev->height = event->u.resizeRequest.height; 1262 } 1263 break; 1264 case CirculateNotify: 1265 { 1266 register XCirculateEvent *ev = (XCirculateEvent *) re; 1267 ev->window = event->u.circulate.window; 1268 ev->event = event->u.circulate.event; 1269 ev->place = event->u.circulate.place; 1270 } 1271 break; 1272 case CirculateRequest: 1273 { 1274 register XCirculateRequestEvent *ev = 1275 (XCirculateRequestEvent *) re; 1276 ev->window = event->u.circulate.window; 1277 ev->parent = event->u.circulate.event; 1278 ev->place = event->u.circulate.place; 1279 } 1280 break; 1281 case PropertyNotify: 1282 { 1283 register XPropertyEvent *ev = (XPropertyEvent *) re; 1284 ev->window = event->u.property.window; 1285 ev->atom = event->u.property.atom; 1286 ev->time = event->u.property.time; 1287 ev->state = event->u.property.state; 1288 } 1289 break; 1290 case SelectionClear: 1291 { 1292 register XSelectionClearEvent *ev = 1293 (XSelectionClearEvent *) re; 1294 ev->window = event->u.selectionClear.window; 1295 ev->selection = event->u.selectionClear.atom; 1296 ev->time = event->u.selectionClear.time; 1297 } 1298 break; 1299 case SelectionRequest: 1300 { 1301 register XSelectionRequestEvent *ev = 1302 (XSelectionRequestEvent *) re; 1303 ev->owner = event->u.selectionRequest.owner; 1304 ev->requestor = event->u.selectionRequest.requestor; 1305 ev->selection = event->u.selectionRequest.selection; 1306 ev->target = event->u.selectionRequest.target; 1307 ev->property = event->u.selectionRequest.property; 1308 ev->time = event->u.selectionRequest.time; 1309 } 1310 break; 1311 case SelectionNotify: 1312 { 1313 register XSelectionEvent *ev = (XSelectionEvent *) re; 1314 ev->requestor = event->u.selectionNotify.requestor; 1315 ev->selection = event->u.selectionNotify.selection; 1316 ev->target = event->u.selectionNotify.target; 1317 ev->property = event->u.selectionNotify.property; 1318 ev->time = event->u.selectionNotify.time; 1319 } 1320 break; 1321 case ColormapNotify: 1322 { 1323 register XColormapEvent *ev = (XColormapEvent *) re; 1324 ev->window = event->u.colormap.window; 1325 ev->colormap = event->u.colormap.colormap; 1326 ev->new = event->u.colormap.new; 1327 ev->state = event->u.colormap.state; 1328 } 1329 break; 1330 case ClientMessage: 1331 { 1332 register int i; 1333 register XClientMessageEvent *ev 1334 = (XClientMessageEvent *) re; 1335 ev->window = event->u.clientMessage.window; 1336 ev->format = event->u.u.detail; 1337 switch (ev->format) { 1338 case 8: 1339 ev->message_type = event->u.clientMessage.u.b.type; 1340 for (i = 0; i < 20; i++) 1341 ev->data.b[i] = event->u.clientMessage.u.b.bytes[i]; 1342 break; 1343 case 16: 1344 ev->message_type = event->u.clientMessage.u.s.type; 1345 ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0); 1346 ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1); 1347 ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2); 1348 ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3); 1349 ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4); 1350 ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5); 1351 ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6); 1352 ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7); 1353 ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8); 1354 ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9); 1355 break; 1356 case 32: 1357 ev->message_type = event->u.clientMessage.u.l.type; 1358 ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0); 1359 ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1); 1360 ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2); 1361 ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3); 1362 ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4); 1363 break; 1364 default: /* XXX should never occur */ 1365 break; 1366 } 1367 } 1368 break; 1369 case MappingNotify: 1370 { 1371 register XMappingEvent *ev = (XMappingEvent *)re; 1372 ev->window = 0; 1373 ev->first_keycode = event->u.mappingNotify.firstKeyCode; 1374 ev->request = event->u.mappingNotify.request; 1375 ev->count = event->u.mappingNotify.count; 1376 } 1377 break; 1378 default: 1379 return(_XUnknownWireEvent(dpy, re, event)); 1380 } 1381 return(True); 1382} 1383 1384 1385/* 1386 * _XDefaultIOError - Default fatal system error reporting routine. Called 1387 * when an X internal system error is encountered. 1388 */ 1389int _XDefaultIOError( 1390 Display *dpy) 1391{ 1392 if (ECHECK(EPIPE)) { 1393 (void) fprintf (stderr, 1394 "X connection to %s broken (explicit kill or server shutdown).\r\n", 1395 DisplayString (dpy)); 1396 } else { 1397 (void) fprintf (stderr, 1398 "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n", 1399#ifdef WIN32 1400 WSAGetLastError(), strerror(WSAGetLastError()), 1401#else 1402 errno, strerror (errno), 1403#endif 1404 DisplayString (dpy)); 1405 (void) fprintf (stderr, 1406 " after %lu requests (%lu known processed) with %d events remaining.\r\n", 1407 NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy), 1408 QLength(dpy)); 1409 1410 } 1411 exit(1); 1412 return(0); /* dummy - function should never return */ 1413} 1414 1415 1416static int _XPrintDefaultError( 1417 Display *dpy, 1418 XErrorEvent *event, 1419 FILE *fp) 1420{ 1421 char buffer[BUFSIZ]; 1422 char mesg[BUFSIZ]; 1423 char number[32]; 1424 const char *mtype = "XlibMessage"; 1425 register _XExtension *ext = (_XExtension *)NULL; 1426 _XExtension *bext = (_XExtension *)NULL; 1427 XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); 1428 XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); 1429 (void) fprintf(fp, "%s: %s\n ", mesg, buffer); 1430 XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", 1431 mesg, BUFSIZ); 1432 (void) fprintf(fp, mesg, event->request_code); 1433 if (event->request_code < 128) { 1434 sprintf(number, "%d", event->request_code); 1435 XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); 1436 } else { 1437 for (ext = dpy->ext_procs; 1438 ext && (ext->codes.major_opcode != event->request_code); 1439 ext = ext->next) 1440 ; 1441 if (ext) 1442 strcpy(buffer, ext->name); 1443 else 1444 buffer[0] = '\0'; 1445 } 1446 (void) fprintf(fp, " (%s)\n", buffer); 1447 if (event->request_code >= 128) { 1448 XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", 1449 mesg, BUFSIZ); 1450 fputs(" ", fp); 1451 (void) fprintf(fp, mesg, event->minor_code); 1452 if (ext) { 1453 sprintf(mesg, "%s.%d", ext->name, event->minor_code); 1454 XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); 1455 (void) fprintf(fp, " (%s)", buffer); 1456 } 1457 fputs("\n", fp); 1458 } 1459 if (event->error_code >= 128) { 1460 /* kludge, try to find the extension that caused it */ 1461 buffer[0] = '\0'; 1462 for (ext = dpy->ext_procs; ext; ext = ext->next) { 1463 if (ext->error_string) 1464 (*ext->error_string)(dpy, event->error_code, &ext->codes, 1465 buffer, BUFSIZ); 1466 if (buffer[0]) { 1467 bext = ext; 1468 break; 1469 } 1470 if (ext->codes.first_error && 1471 ext->codes.first_error < (int)event->error_code && 1472 (!bext || ext->codes.first_error > bext->codes.first_error)) 1473 bext = ext; 1474 } 1475 if (bext) 1476 sprintf(buffer, "%s.%d", bext->name, 1477 event->error_code - bext->codes.first_error); 1478 else 1479 strcpy(buffer, "Value"); 1480 XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); 1481 if (mesg[0]) { 1482 fputs(" ", fp); 1483 (void) fprintf(fp, mesg, event->resourceid); 1484 fputs("\n", fp); 1485 } 1486 /* let extensions try to print the values */ 1487 for (ext = dpy->ext_procs; ext; ext = ext->next) { 1488 if (ext->error_values) 1489 (*ext->error_values)(dpy, event, fp); 1490 } 1491 } else if ((event->error_code == BadWindow) || 1492 (event->error_code == BadPixmap) || 1493 (event->error_code == BadCursor) || 1494 (event->error_code == BadFont) || 1495 (event->error_code == BadDrawable) || 1496 (event->error_code == BadColor) || 1497 (event->error_code == BadGC) || 1498 (event->error_code == BadIDChoice) || 1499 (event->error_code == BadValue) || 1500 (event->error_code == BadAtom)) { 1501 if (event->error_code == BadValue) 1502 XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", 1503 mesg, BUFSIZ); 1504 else if (event->error_code == BadAtom) 1505 XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", 1506 mesg, BUFSIZ); 1507 else 1508 XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", 1509 mesg, BUFSIZ); 1510 fputs(" ", fp); 1511 (void) fprintf(fp, mesg, event->resourceid); 1512 fputs("\n", fp); 1513 } 1514 XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", 1515 mesg, BUFSIZ); 1516 fputs(" ", fp); 1517 (void) fprintf(fp, mesg, event->serial); 1518 XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", 1519 mesg, BUFSIZ); 1520 fputs("\n ", fp); 1521 (void) fprintf(fp, mesg, dpy->request); 1522 fputs("\n", fp); 1523 if (event->error_code == BadImplementation) return 0; 1524 return 1; 1525} 1526 1527int _XDefaultError( 1528 Display *dpy, 1529 XErrorEvent *event) 1530{ 1531 if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0; 1532 exit(1); 1533 /*NOTREACHED*/ 1534} 1535 1536/*ARGSUSED*/ 1537Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we) 1538{ 1539 return True; 1540} 1541 1542/* 1543 * _XError - upcall internal or user protocol error handler 1544 */ 1545int _XError ( 1546 Display *dpy, 1547 register xError *rep) 1548{ 1549 /* 1550 * X_Error packet encountered! We need to unpack the error before 1551 * giving it to the user. 1552 */ 1553 XEvent event; /* make it a large event */ 1554 register _XAsyncHandler *async, *next; 1555 1556 event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep); 1557 1558 for (async = dpy->async_handlers; async; async = next) { 1559 next = async->next; 1560 if ((*async->handler)(dpy, (xReply *)rep, 1561 (char *)rep, SIZEOF(xError), async->data)) 1562 return 0; 1563 } 1564 1565 event.xerror.display = dpy; 1566 event.xerror.type = X_Error; 1567 event.xerror.resourceid = rep->resourceID; 1568 event.xerror.error_code = rep->errorCode; 1569 event.xerror.request_code = rep->majorCode; 1570 event.xerror.minor_code = rep->minorCode; 1571 if (dpy->error_vec && 1572 !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep)) 1573 return 0; 1574 if (_XErrorFunction != NULL) { 1575 return (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ 1576 } else { 1577 return _XDefaultError(dpy, (XErrorEvent *)&event); 1578 } 1579} 1580 1581/* 1582 * _XIOError - call user connection error handler and exit 1583 */ 1584int 1585_XIOError ( 1586 Display *dpy) 1587{ 1588 dpy->flags |= XlibDisplayIOError; 1589#ifdef WIN32 1590 errno = WSAGetLastError(); 1591#endif 1592 1593 /* This assumes that the thread calling exit will call any atexit handlers. 1594 * If this does not hold, then an alternate solution would involve 1595 * registering an atexit handler to take over the lock, which would only 1596 * assume that the same thread calls all the atexit handlers. */ 1597#ifdef XTHREADS 1598 if (dpy->lock) 1599 (*dpy->lock->user_lock_display)(dpy); 1600#endif 1601 UnlockDisplay(dpy); 1602 1603 if (_XIOErrorFunction != NULL) 1604 (*_XIOErrorFunction)(dpy); 1605 else 1606 _XDefaultIOError(dpy); 1607 exit (1); 1608 return 0; 1609} 1610 1611 1612/* 1613 * This routine can be used to (cheaply) get some memory within a single 1614 * Xlib routine for scratch space. A single buffer is reused each time 1615 * if possible. To be MT safe, you can only call this between a call to 1616 * GetReq* and a call to Data* or _XSend*, or in a context when the thread 1617 * is guaranteed to not unlock the display. 1618 */ 1619char *_XAllocScratch( 1620 register Display *dpy, 1621 unsigned long nbytes) 1622{ 1623 if (nbytes > dpy->scratch_length) { 1624 if (dpy->scratch_buffer) Xfree (dpy->scratch_buffer); 1625 if ((dpy->scratch_buffer = Xmalloc((unsigned) nbytes))) 1626 dpy->scratch_length = nbytes; 1627 else dpy->scratch_length = 0; 1628 } 1629 return (dpy->scratch_buffer); 1630} 1631 1632/* 1633 * Scratch space allocator you can call any time, multiple times, and be 1634 * MT safe, but you must hand the buffer back with _XFreeTemp. 1635 */ 1636char *_XAllocTemp( 1637 register Display *dpy, 1638 unsigned long nbytes) 1639{ 1640 char *buf; 1641 1642 buf = _XAllocScratch(dpy, nbytes); 1643 dpy->scratch_buffer = NULL; 1644 dpy->scratch_length = 0; 1645 return buf; 1646} 1647 1648void _XFreeTemp( 1649 register Display *dpy, 1650 char *buf, 1651 unsigned long nbytes) 1652{ 1653 if (dpy->scratch_buffer) 1654 Xfree(dpy->scratch_buffer); 1655 dpy->scratch_buffer = buf; 1656 dpy->scratch_length = nbytes; 1657} 1658 1659/* 1660 * Given a visual id, find the visual structure for this id on this display. 1661 */ 1662Visual *_XVIDtoVisual( 1663 Display *dpy, 1664 VisualID id) 1665{ 1666 register int i, j, k; 1667 register Screen *sp; 1668 register Depth *dp; 1669 register Visual *vp; 1670 for (i = 0; i < dpy->nscreens; i++) { 1671 sp = &dpy->screens[i]; 1672 for (j = 0; j < sp->ndepths; j++) { 1673 dp = &sp->depths[j]; 1674 /* if nvisuals == 0 then visuals will be NULL */ 1675 for (k = 0; k < dp->nvisuals; k++) { 1676 vp = &dp->visuals[k]; 1677 if (vp->visualid == id) return (vp); 1678 } 1679 } 1680 } 1681 return (NULL); 1682} 1683 1684int 1685XFree (void *data) 1686{ 1687 Xfree (data); 1688 return 1; 1689} 1690 1691#ifdef _XNEEDBCOPYFUNC 1692void _Xbcopy(b1, b2, length) 1693 register char *b1, *b2; 1694 register length; 1695{ 1696 if (b1 < b2) { 1697 b2 += length; 1698 b1 += length; 1699 while (length--) 1700 *--b2 = *--b1; 1701 } else { 1702 while (length--) 1703 *b2++ = *b1++; 1704 } 1705} 1706#endif 1707 1708#ifdef DataRoutineIsProcedure 1709void Data( 1710 Display *dpy, 1711 char *data, 1712 long len) 1713{ 1714 if (dpy->bufptr + (len) <= dpy->bufmax) { 1715 memcpy(dpy->bufptr, data, (int)len); 1716 dpy->bufptr += ((len) + 3) & ~3; 1717 } else { 1718 _XSend(dpy, data, len); 1719 } 1720} 1721#endif /* DataRoutineIsProcedure */ 1722 1723 1724#ifdef LONG64 1725int 1726_XData32( 1727 Display *dpy, 1728 register long *data, 1729 unsigned len) 1730{ 1731 register int *buf; 1732 register long i; 1733 1734 while (len) { 1735 buf = (int *)dpy->bufptr; 1736 i = dpy->bufmax - (char *)buf; 1737 if (!i) { 1738 _XFlush(dpy); 1739 continue; 1740 } 1741 if (len < i) 1742 i = len; 1743 dpy->bufptr = (char *)buf + i; 1744 len -= i; 1745 i >>= 2; 1746 while (--i >= 0) 1747 *buf++ = *data++; 1748 } 1749 return 0; 1750} 1751#endif /* LONG64 */ 1752 1753#ifdef WORD64 1754 1755/* 1756 * XXX This is a *really* stupid way of doing this. It should just use 1757 * dpy->bufptr directly, taking into account where in the word it is. 1758 */ 1759 1760/* 1761 * Data16 - Place 16 bit data in the buffer. 1762 * 1763 * "dpy" is a pointer to a Display. 1764 * "data" is a pointer to the data. 1765 * "len" is the length in bytes of the data. 1766 */ 1767 1768static doData16( 1769 register Display *dpy, 1770 short *data, 1771 unsigned len, 1772 char *packbuffer) 1773{ 1774 long *lp,*lpack; 1775 long i, nwords,bits; 1776 long mask16 = 0x000000000000ffff; 1777 1778 lp = (long *)data; 1779 lpack = (long *)packbuffer; 1780 1781/* nwords is the number of 16 bit values to be packed, 1782 * the low order 16 bits of each word will be packed 1783 * into 64 bit words 1784 */ 1785 nwords = len >> 1; 1786 bits = 48; 1787 1788 for(i=0;i<nwords;i++){ 1789 if (bits == 48) *lpack = 0; 1790 *lpack ^= (*lp & mask16) << bits; 1791 bits -= 16 ; 1792 lp++; 1793 if(bits < 0){ 1794 lpack++; 1795 bits = 48; 1796 } 1797 } 1798 Data(dpy, packbuffer, len); 1799} 1800 1801_XData16 ( 1802 Display *dpy, 1803 short *data, 1804 unsigned len) 1805{ 1806 char packbuffer[PACKBUFFERSIZE]; 1807 unsigned nunits = PACKBUFFERSIZE >> 1; 1808 1809 for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { 1810 doData16 (dpy, data, PACKBUFFERSIZE, packbuffer); 1811 } 1812 if (len) doData16 (dpy, data, len, packbuffer); 1813} 1814 1815/* 1816 * Data32 - Place 32 bit data in the buffer. 1817 * 1818 * "dpy" is a pointer to a Display. 1819 * "data" is a pointer to the data. 1820 * "len" is the length in bytes of the data. 1821 */ 1822 1823static doData32( 1824 register Display *dpy 1825 long *data, 1826 unsigned len, 1827 char *packbuffer) 1828{ 1829 long *lp,*lpack; 1830 long i,bits,nwords; 1831 long mask32 = 0x00000000ffffffff; 1832 1833 lpack = (long *) packbuffer; 1834 lp = data; 1835 1836/* nwords is the number of 32 bit values to be packed 1837 * the low order 32 bits of each word will be packed 1838 * into 64 bit words 1839 */ 1840 nwords = len >> 2; 1841 bits = 32; 1842 1843 for(i=0;i<nwords;i++){ 1844 if (bits == 32) *lpack = 0; 1845 *lpack ^= (*lp & mask32) << bits; 1846 bits = bits ^32; 1847 lp++; 1848 if(bits) 1849 lpack++; 1850 } 1851 Data(dpy, packbuffer, len); 1852} 1853 1854void _XData32( 1855 Display *dpy, 1856 long *data, 1857 unsigned len) 1858{ 1859 char packbuffer[PACKBUFFERSIZE]; 1860 unsigned nunits = PACKBUFFERSIZE >> 2; 1861 1862 for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { 1863 doData32 (dpy, data, PACKBUFFERSIZE, packbuffer); 1864 } 1865 if (len) doData32 (dpy, data, len, packbuffer); 1866} 1867 1868#endif /* WORD64 */ 1869 1870 1871/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm. 1872 * Otherwise, Xau will not be able to find your cookies in the Xauthority file. 1873 * 1874 * Note: POSIX says that the ``nodename'' member of utsname does _not_ have 1875 * to have sufficient information for interfacing to the network, 1876 * and so, you may be better off using gethostname (if it exists). 1877 */ 1878 1879#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4) 1880#define NEED_UTSNAME 1881#include <sys/utsname.h> 1882#else 1883#ifdef HAVE_UNISTD_H 1884#include <unistd.h> 1885#endif 1886#endif 1887 1888/* 1889 * _XGetHostname - similar to gethostname but allows special processing. 1890 */ 1891int _XGetHostname ( 1892 char *buf, 1893 int maxlen) 1894{ 1895 int len; 1896 1897#ifdef NEED_UTSNAME 1898 struct utsname name; 1899 1900 if (maxlen <= 0 || buf == NULL) 1901 return 0; 1902 1903 uname (&name); 1904 len = strlen (name.nodename); 1905 if (len >= maxlen) len = maxlen - 1; 1906 strncpy (buf, name.nodename, len); 1907 buf[len] = '\0'; 1908#else 1909 if (maxlen <= 0 || buf == NULL) 1910 return 0; 1911 1912 buf[0] = '\0'; 1913 (void) gethostname (buf, maxlen); 1914 buf [maxlen - 1] = '\0'; 1915 len = strlen(buf); 1916#endif /* NEED_UTSNAME */ 1917 return len; 1918} 1919 1920 1921/* 1922 * _XScreenOfWindow - get the Screen of a given window 1923 */ 1924 1925Screen *_XScreenOfWindow(Display *dpy, Window w) 1926{ 1927 register int i; 1928 Window root; 1929 int x, y; /* dummy variables */ 1930 unsigned int width, height, bw, depth; /* dummy variables */ 1931 1932 if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height, 1933 &bw, &depth) == False) { 1934 return NULL; 1935 } 1936 for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */ 1937 if (root == RootWindow (dpy, i)) { 1938 return ScreenOfDisplay (dpy, i); 1939 } 1940 } 1941 return NULL; 1942} 1943 1944 1945#if defined(WIN32) 1946 1947/* 1948 * These functions are intended to be used internally to Xlib only. 1949 * These functions will always prefix the path with a DOS drive in the 1950 * form "<drive-letter>:". As such, these functions are only suitable 1951 * for use by Xlib function that supply a root-based path to some 1952 * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will 1953 * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir". 1954 */ 1955 1956static int access_file (path, pathbuf, len_pathbuf, pathret) 1957 char* path; 1958 char* pathbuf; 1959 int len_pathbuf; 1960 char** pathret; 1961{ 1962 if (access (path, F_OK) == 0) { 1963 if (strlen (path) < len_pathbuf) 1964 *pathret = pathbuf; 1965 else 1966 *pathret = Xmalloc (strlen (path) + 1); 1967 if (*pathret) { 1968 strcpy (*pathret, path); 1969 return 1; 1970 } 1971 } 1972 return 0; 1973} 1974 1975static int AccessFile (path, pathbuf, len_pathbuf, pathret) 1976 char* path; 1977 char* pathbuf; 1978 int len_pathbuf; 1979 char** pathret; 1980{ 1981 unsigned long drives; 1982 int i, len; 1983 char* drive; 1984 char buf[MAX_PATH]; 1985 char* bufp; 1986 1987 /* just try the "raw" name first and see if it works */ 1988 if (access_file (path, pathbuf, len_pathbuf, pathret)) 1989 return 1; 1990 1991 /* try the places set in the environment */ 1992 drive = getenv ("_XBASEDRIVE"); 1993#ifdef __UNIXOS2__ 1994 if (!drive) 1995 drive = getenv ("X11ROOT"); 1996#endif 1997 if (!drive) 1998 drive = "C:"; 1999 len = strlen (drive) + strlen (path); 2000 if (len < MAX_PATH) bufp = buf; 2001 else bufp = Xmalloc (len + 1); 2002 strcpy (bufp, drive); 2003 strcat (bufp, path); 2004 if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 2005 if (bufp != buf) Xfree (bufp); 2006 return 1; 2007 } 2008 2009#ifndef __UNIXOS2__ 2010 /* one last place to look */ 2011 drive = getenv ("HOMEDRIVE"); 2012 if (drive) { 2013 len = strlen (drive) + strlen (path); 2014 if (len < MAX_PATH) bufp = buf; 2015 else bufp = Xmalloc (len + 1); 2016 strcpy (bufp, drive); 2017 strcat (bufp, path); 2018 if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 2019 if (bufp != buf) Xfree (bufp); 2020 return 1; 2021 } 2022 } 2023 2024 /* tried everywhere else, go fishing */ 2025#define C_DRIVE ('C' - 'A') 2026#define Z_DRIVE ('Z' - 'A') 2027 /* does OS/2 (with or with gcc-emx) have getdrives? */ 2028 drives = _getdrives (); 2029 for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */ 2030 if ((1 << i) & drives) { 2031 len = 2 + strlen (path); 2032 if (len < MAX_PATH) bufp = buf; 2033 else bufp = Xmalloc (len + 1); 2034 *bufp = 'A' + i; 2035 *(bufp + 1) = ':'; 2036 *(bufp + 2) = '\0'; 2037 strcat (bufp, path); 2038 if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 2039 if (bufp != buf) Xfree (bufp); 2040 return 1; 2041 } 2042 } 2043 } 2044#endif 2045 return 0; 2046} 2047 2048int _XOpenFile(path, flags) 2049 _Xconst char* path; 2050 int flags; 2051{ 2052 char buf[MAX_PATH]; 2053 char* bufp = NULL; 2054 int ret = -1; 2055 UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 2056 2057 if (AccessFile (path, buf, MAX_PATH, &bufp)) 2058 ret = open (bufp, flags); 2059 2060 (void) SetErrorMode (olderror); 2061 2062 if (bufp != buf) Xfree (bufp); 2063 2064 return ret; 2065} 2066 2067int _XOpenFileMode(path, flags, mode) 2068 _Xconst char* path; 2069 int flags; 2070 mode_t mode; 2071{ 2072 char buf[MAX_PATH]; 2073 char* bufp = NULL; 2074 int ret = -1; 2075 UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 2076 2077 if (AccessFile (path, buf, MAX_PATH, &bufp)) 2078 ret = open (bufp, flags, mode); 2079 2080 (void) SetErrorMode (olderror); 2081 2082 if (bufp != buf) Xfree (bufp); 2083 2084 return ret; 2085} 2086 2087void* _XFopenFile(path, mode) 2088 _Xconst char* path; 2089 _Xconst char* mode; 2090{ 2091 char buf[MAX_PATH]; 2092 char* bufp = NULL; 2093 void* ret = NULL; 2094 UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 2095 2096 if (AccessFile (path, buf, MAX_PATH, &bufp)) 2097 ret = fopen (bufp, mode); 2098 2099 (void) SetErrorMode (olderror); 2100 2101 if (bufp != buf) Xfree (bufp); 2102 2103 return ret; 2104} 2105 2106int _XAccessFile(path) 2107 _Xconst char* path; 2108{ 2109 char buf[MAX_PATH]; 2110 char* bufp; 2111 int ret = -1; 2112 UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 2113 2114 ret = AccessFile (path, buf, MAX_PATH, &bufp); 2115 2116 (void) SetErrorMode (olderror); 2117 2118 if (bufp != buf) Xfree (bufp); 2119 2120 return ret; 2121} 2122 2123#endif 2124 2125#ifdef WIN32 2126#undef _Xdebug 2127int _Xdebug = 0; 2128int *_Xdebug_p = &_Xdebug; 2129void (**_XCreateMutex_fn_p)(LockInfoPtr) = &_XCreateMutex_fn; 2130void (**_XFreeMutex_fn_p)(LockInfoPtr) = &_XFreeMutex_fn; 2131void (**_XLockMutex_fn_p)(LockInfoPtr 2132#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 2133 , char * /* file */ 2134 , int /* line */ 2135#endif 2136 ) = &_XLockMutex_fn; 2137void (**_XUnlockMutex_fn_p)(LockInfoPtr 2138#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 2139 , char * /* file */ 2140 , int /* line */ 2141#endif 2142 ) = &_XUnlockMutex_fn; 2143LockInfoPtr *_Xglobal_lock_p = &_Xglobal_lock; 2144#endif 2145