XlibInt.c revision 556b6652
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 155556b6652Smrg pfp = 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 2971ab64890Smrg/* 2981ab64890Smrg * The hard part about this is that we only get 16 bits from a reply. 2991ab64890Smrg * We have three values that will march along, with the following invariant: 3001ab64890Smrg * dpy->last_request_read <= rep->sequenceNumber <= dpy->request 3011ab64890Smrg * We have to keep 3021ab64890Smrg * dpy->request - dpy->last_request_read < 2^16 3031ab64890Smrg * or else we won't know for sure what value to use in events. We do this 3041ab64890Smrg * by forcing syncs when we get close. 3051ab64890Smrg */ 3061ab64890Smrg 3071ab64890Smrgunsigned long 3081ab64890Smrg_XSetLastRequestRead( 3091ab64890Smrg register Display *dpy, 3101ab64890Smrg register xGenericReply *rep) 3111ab64890Smrg{ 3121ab64890Smrg register unsigned long newseq, lastseq; 3131ab64890Smrg 3141ab64890Smrg lastseq = dpy->last_request_read; 3151ab64890Smrg /* 3161ab64890Smrg * KeymapNotify has no sequence number, but is always guaranteed 3171ab64890Smrg * to immediately follow another event, except when generated via 3181ab64890Smrg * SendEvent (hmmm). 3191ab64890Smrg */ 3201ab64890Smrg if ((rep->type & 0x7f) == KeymapNotify) 3211ab64890Smrg return(lastseq); 3221ab64890Smrg 3231ab64890Smrg newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber; 3241ab64890Smrg 3251ab64890Smrg if (newseq < lastseq) { 3261ab64890Smrg newseq += 0x10000; 3271ab64890Smrg if (newseq > dpy->request) { 32861b2299dSmrg (void) fprintf (stderr, 3291ab64890Smrg "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n", 33061b2299dSmrg newseq, dpy->request, 3311ab64890Smrg (unsigned int) rep->type); 3321ab64890Smrg newseq -= 0x10000; 3331ab64890Smrg } 3341ab64890Smrg } 3351ab64890Smrg 3361ab64890Smrg dpy->last_request_read = newseq; 3371ab64890Smrg return(newseq); 3381ab64890Smrg} 3391ab64890Smrg 3401ab64890Smrg/* 3411ab64890Smrg * Support for internal connections, such as an IM might use. 3421ab64890Smrg * By Stephen Gildea, X Consortium, September 1993 3431ab64890Smrg */ 3441ab64890Smrg 3451ab64890Smrg/* _XRegisterInternalConnection 3461ab64890Smrg * Each IM (or Xlib extension) that opens a file descriptor that Xlib should 3471ab64890Smrg * include in its select/poll mask must call this function to register the 3481ab64890Smrg * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch 3491ab64890Smrg * will also be called. 3501ab64890Smrg * 3511ab64890Smrg * Whenever Xlib detects input available on fd, it will call callback 3521ab64890Smrg * with call_data to process it. If non-Xlib code calls select/poll 3531ab64890Smrg * and detects input available, it must call XProcessInternalConnection, 3541ab64890Smrg * which will call the associated callback. 3551ab64890Smrg * 3561ab64890Smrg * Non-Xlib code can learn about these additional fds by calling 3571ab64890Smrg * XInternalConnectionNumbers or, more typically, by registering 3581ab64890Smrg * a XConnectionWatchProc with XAddConnectionWatch 3591ab64890Smrg * to be called when fds are registered or unregistered. 3601ab64890Smrg * 3611ab64890Smrg * Returns True if registration succeeded, False if not, typically 3621ab64890Smrg * because could not allocate memory. 3631ab64890Smrg * Assumes Display locked when called. 3641ab64890Smrg */ 3651ab64890SmrgStatus 3661ab64890Smrg_XRegisterInternalConnection( 3671ab64890Smrg Display* dpy, 3681ab64890Smrg int fd, 3691ab64890Smrg _XInternalConnectionProc callback, 3701ab64890Smrg XPointer call_data 3711ab64890Smrg) 3721ab64890Smrg{ 3731ab64890Smrg struct _XConnectionInfo *new_conni, **iptr; 3741ab64890Smrg struct _XConnWatchInfo *watchers; 3751ab64890Smrg XPointer *wd; 3761ab64890Smrg 377556b6652Smrg new_conni = Xmalloc(sizeof(struct _XConnectionInfo)); 3781ab64890Smrg if (!new_conni) 3791ab64890Smrg return 0; 380556b6652Smrg new_conni->watch_data = Xmalloc(dpy->watcher_count * sizeof(XPointer)); 3811ab64890Smrg if (!new_conni->watch_data) { 3821ab64890Smrg Xfree(new_conni); 3831ab64890Smrg return 0; 3841ab64890Smrg } 3851ab64890Smrg new_conni->fd = fd; 3861ab64890Smrg new_conni->read_callback = callback; 3871ab64890Smrg new_conni->call_data = call_data; 3881ab64890Smrg new_conni->next = NULL; 3891ab64890Smrg /* link new structure onto end of list */ 3901ab64890Smrg for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next) 3911ab64890Smrg ; 3921ab64890Smrg *iptr = new_conni; 3931ab64890Smrg dpy->im_fd_length++; 3941ab64890Smrg _XPollfdCacheAdd(dpy, fd); 3951ab64890Smrg 3961ab64890Smrg for (watchers=dpy->conn_watchers, wd=new_conni->watch_data; 3971ab64890Smrg watchers; 3981ab64890Smrg watchers=watchers->next, wd++) { 3991ab64890Smrg *wd = NULL; /* for cleanliness */ 4001ab64890Smrg (*watchers->fn) (dpy, watchers->client_data, fd, True, wd); 4011ab64890Smrg } 4021ab64890Smrg 4031ab64890Smrg return 1; 4041ab64890Smrg} 4051ab64890Smrg 4061ab64890Smrg/* _XUnregisterInternalConnection 4071ab64890Smrg * Each IM (or Xlib extension) that closes a file descriptor previously 4081ab64890Smrg * registered with _XRegisterInternalConnection must call this function. 4091ab64890Smrg * Any XConnectionWatchProc registered by XAddConnectionWatch 4101ab64890Smrg * will also be called. 4111ab64890Smrg * 4121ab64890Smrg * Assumes Display locked when called. 4131ab64890Smrg */ 4141ab64890Smrgvoid 4151ab64890Smrg_XUnregisterInternalConnection( 4161ab64890Smrg Display* dpy, 4171ab64890Smrg int fd 4181ab64890Smrg) 4191ab64890Smrg{ 4201ab64890Smrg struct _XConnectionInfo *info_list, **prev; 4211ab64890Smrg struct _XConnWatchInfo *watch; 4221ab64890Smrg XPointer *wd; 4231ab64890Smrg 4241ab64890Smrg for (prev = &dpy->im_fd_info; (info_list = *prev); 4251ab64890Smrg prev = &info_list->next) { 4261ab64890Smrg if (info_list->fd == fd) { 4271ab64890Smrg *prev = info_list->next; 4281ab64890Smrg dpy->im_fd_length--; 4291ab64890Smrg for (watch=dpy->conn_watchers, wd=info_list->watch_data; 4301ab64890Smrg watch; 4311ab64890Smrg watch=watch->next, wd++) { 4321ab64890Smrg (*watch->fn) (dpy, watch->client_data, fd, False, wd); 4331ab64890Smrg } 4341ab64890Smrg if (info_list->watch_data) 4351ab64890Smrg Xfree (info_list->watch_data); 4361ab64890Smrg Xfree (info_list); 4371ab64890Smrg break; 4381ab64890Smrg } 4391ab64890Smrg } 4401ab64890Smrg _XPollfdCacheDel(dpy, fd); 4411ab64890Smrg} 4421ab64890Smrg 4431ab64890Smrg/* XInternalConnectionNumbers 4441ab64890Smrg * Returns an array of fds and an array of corresponding call data. 4451ab64890Smrg * Typically a XConnectionWatchProc registered with XAddConnectionWatch 4461ab64890Smrg * will be used instead of this function to discover 4471ab64890Smrg * additional fds to include in the select/poll mask. 4481ab64890Smrg * 4491ab64890Smrg * The list is allocated with Xmalloc and should be freed by the caller 4501ab64890Smrg * with Xfree; 4511ab64890Smrg */ 4521ab64890SmrgStatus 4531ab64890SmrgXInternalConnectionNumbers( 4541ab64890Smrg Display *dpy, 4551ab64890Smrg int **fd_return, 4561ab64890Smrg int *count_return 4571ab64890Smrg) 4581ab64890Smrg{ 4591ab64890Smrg int count; 4601ab64890Smrg struct _XConnectionInfo *info_list; 4611ab64890Smrg int *fd_list; 4621ab64890Smrg 4631ab64890Smrg LockDisplay(dpy); 4641ab64890Smrg count = 0; 4651ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) 4661ab64890Smrg count++; 467556b6652Smrg fd_list = Xmalloc (count * sizeof(int)); 4681ab64890Smrg if (!fd_list) { 4691ab64890Smrg UnlockDisplay(dpy); 4701ab64890Smrg return 0; 4711ab64890Smrg } 4721ab64890Smrg count = 0; 4731ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 4741ab64890Smrg fd_list[count] = info_list->fd; 4751ab64890Smrg count++; 4761ab64890Smrg } 4771ab64890Smrg UnlockDisplay(dpy); 4781ab64890Smrg 4791ab64890Smrg *fd_return = fd_list; 4801ab64890Smrg *count_return = count; 4811ab64890Smrg return 1; 4821ab64890Smrg} 4831ab64890Smrg 4841ab64890Smrgvoid _XProcessInternalConnection( 4851ab64890Smrg Display *dpy, 4861ab64890Smrg struct _XConnectionInfo *conn_info) 4871ab64890Smrg{ 4881ab64890Smrg dpy->flags |= XlibDisplayProcConni; 4891ab64890Smrg UnlockDisplay(dpy); 4901ab64890Smrg (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data); 4911ab64890Smrg LockDisplay(dpy); 4921ab64890Smrg dpy->flags &= ~XlibDisplayProcConni; 4931ab64890Smrg} 4941ab64890Smrg 4951ab64890Smrg/* XProcessInternalConnection 4961ab64890Smrg * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection 4971ab64890Smrg * for this fd. 4981ab64890Smrg * The Display is NOT locked during the call. 4991ab64890Smrg */ 5001ab64890Smrgvoid 5011ab64890SmrgXProcessInternalConnection( 5021ab64890Smrg Display* dpy, 5031ab64890Smrg int fd 5041ab64890Smrg) 5051ab64890Smrg{ 5061ab64890Smrg struct _XConnectionInfo *info_list; 5071ab64890Smrg 5081ab64890Smrg LockDisplay(dpy); 5091ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 5101ab64890Smrg if (info_list->fd == fd) { 5111ab64890Smrg _XProcessInternalConnection(dpy, info_list); 5121ab64890Smrg break; 5131ab64890Smrg } 5141ab64890Smrg } 5151ab64890Smrg UnlockDisplay(dpy); 5161ab64890Smrg} 5171ab64890Smrg 5181ab64890Smrg/* XAddConnectionWatch 5191ab64890Smrg * Register a callback to be called whenever _XRegisterInternalConnection 5201ab64890Smrg * or _XUnregisterInternalConnection is called. 5211ab64890Smrg * Callbacks are called with the Display locked. 5221ab64890Smrg * If any connections are already registered, the callback is immediately 5231ab64890Smrg * called for each of them. 5241ab64890Smrg */ 5251ab64890SmrgStatus 5261ab64890SmrgXAddConnectionWatch( 5271ab64890Smrg Display* dpy, 5281ab64890Smrg XConnectionWatchProc callback, 5291ab64890Smrg XPointer client_data 5301ab64890Smrg) 5311ab64890Smrg{ 5321ab64890Smrg struct _XConnWatchInfo *new_watcher, **wptr; 5331ab64890Smrg struct _XConnectionInfo *info_list; 5341ab64890Smrg XPointer *wd_array; 5351ab64890Smrg 5361ab64890Smrg LockDisplay(dpy); 5371ab64890Smrg 5381ab64890Smrg /* allocate new watch data */ 5391ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 540556b6652Smrg wd_array = Xrealloc(info_list->watch_data, 541556b6652Smrg (dpy->watcher_count + 1) * sizeof(XPointer)); 5421ab64890Smrg if (!wd_array) { 5431ab64890Smrg UnlockDisplay(dpy); 5441ab64890Smrg return 0; 5451ab64890Smrg } 546c17aa6b1Smrg info_list->watch_data = wd_array; 5471ab64890Smrg wd_array[dpy->watcher_count] = NULL; /* for cleanliness */ 5481ab64890Smrg } 5491ab64890Smrg 550556b6652Smrg new_watcher = Xmalloc(sizeof(struct _XConnWatchInfo)); 5511ab64890Smrg if (!new_watcher) { 5521ab64890Smrg UnlockDisplay(dpy); 5531ab64890Smrg return 0; 5541ab64890Smrg } 5551ab64890Smrg new_watcher->fn = callback; 5561ab64890Smrg new_watcher->client_data = client_data; 5571ab64890Smrg new_watcher->next = NULL; 5581ab64890Smrg 5591ab64890Smrg /* link new structure onto end of list */ 5601ab64890Smrg for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next) 5611ab64890Smrg ; 5621ab64890Smrg *wptr = new_watcher; 5631ab64890Smrg dpy->watcher_count++; 5641ab64890Smrg 5651ab64890Smrg /* call new watcher on all currently registered fds */ 5661ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 5671ab64890Smrg (*callback) (dpy, client_data, info_list->fd, True, 5681ab64890Smrg info_list->watch_data + dpy->watcher_count - 1); 5691ab64890Smrg } 5701ab64890Smrg 5711ab64890Smrg UnlockDisplay(dpy); 5721ab64890Smrg return 1; 5731ab64890Smrg} 5741ab64890Smrg 5751ab64890Smrg/* XRemoveConnectionWatch 5761ab64890Smrg * Unregister a callback registered by XAddConnectionWatch. 5771ab64890Smrg * Both callback and client_data must match what was passed to 5781ab64890Smrg * XAddConnectionWatch. 57961b2299dSmrg */ 5801ab64890Smrgvoid 5811ab64890SmrgXRemoveConnectionWatch( 5821ab64890Smrg Display* dpy, 5831ab64890Smrg XConnectionWatchProc callback, 5841ab64890Smrg XPointer client_data 5851ab64890Smrg) 5861ab64890Smrg{ 5871ab64890Smrg struct _XConnWatchInfo *watch; 5881ab64890Smrg struct _XConnWatchInfo *previous = NULL; 5891ab64890Smrg struct _XConnectionInfo *conni; 5901ab64890Smrg int counter = 0; 5911ab64890Smrg 5921ab64890Smrg LockDisplay(dpy); 5931ab64890Smrg for (watch=dpy->conn_watchers; watch; watch=watch->next) { 5941ab64890Smrg if (watch->fn == callback && watch->client_data == client_data) { 5951ab64890Smrg if (previous) 5961ab64890Smrg previous->next = watch->next; 5971ab64890Smrg else 5981ab64890Smrg dpy->conn_watchers = watch->next; 5991ab64890Smrg Xfree (watch); 6001ab64890Smrg dpy->watcher_count--; 6011ab64890Smrg /* remove our watch_data for each connection */ 6021ab64890Smrg for (conni=dpy->im_fd_info; conni; conni=conni->next) { 6031ab64890Smrg /* don't bother realloc'ing; these arrays are small anyway */ 6041ab64890Smrg /* overlapping */ 6051ab64890Smrg memmove(conni->watch_data+counter, 6061ab64890Smrg conni->watch_data+counter+1, 6071ab64890Smrg dpy->watcher_count - counter); 6081ab64890Smrg } 6091ab64890Smrg break; 6101ab64890Smrg } 6111ab64890Smrg previous = watch; 6121ab64890Smrg counter++; 6131ab64890Smrg } 6141ab64890Smrg UnlockDisplay(dpy); 6151ab64890Smrg} 6161ab64890Smrg 6171ab64890Smrg/* end of internal connections support */ 6181ab64890Smrg 619b4ee4795Smrg/* Cookie jar implementation 620b4ee4795Smrg dpy->cookiejar is a linked list. _XEnq receives the events but leaves 621b4ee4795Smrg them in the normal EQ. _XStoreEvent returns the cookie event (minus 622b4ee4795Smrg data pointer) and adds it to the cookiejar. _XDeq just removes 623b4ee4795Smrg the entry like any other event but resets the data pointer for 624b4ee4795Smrg cookie events (to avoid double-free, the memory is re-used by Xlib). 625b4ee4795Smrg 626b4ee4795Smrg _XFetchEventCookie (called from XGetEventData) removes a cookie from the 627b4ee4795Smrg jar. _XFreeEventCookies removes all unclaimed cookies from the jar 628b4ee4795Smrg (called by XNextEvent). 629b4ee4795Smrg 630b4ee4795Smrg _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the 631b4ee4795Smrg normal EQ. 632b4ee4795Smrg */ 633b4ee4795Smrg 634b4ee4795Smrg#include "utlist.h" 635b4ee4795Smrgstruct stored_event { 636b4ee4795Smrg XGenericEventCookie ev; 637b4ee4795Smrg struct stored_event *prev; 638b4ee4795Smrg struct stored_event *next; 639b4ee4795Smrg}; 640b4ee4795Smrg 641b4ee4795SmrgBool 642b4ee4795Smrg_XIsEventCookie(Display *dpy, XEvent *ev) 643b4ee4795Smrg{ 644b4ee4795Smrg return (ev->xcookie.type == GenericEvent && 645b4ee4795Smrg dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL); 646b4ee4795Smrg} 647b4ee4795Smrg 648b4ee4795Smrg/** 649b4ee4795Smrg * Free all events in the event list. 650b4ee4795Smrg */ 651b4ee4795Smrgvoid 652b4ee4795Smrg_XFreeEventCookies(Display *dpy) 653b4ee4795Smrg{ 654b4ee4795Smrg struct stored_event **head, *e, *tmp; 655b4ee4795Smrg 656b4ee4795Smrg if (!dpy->cookiejar) 657b4ee4795Smrg return; 658b4ee4795Smrg 659b4ee4795Smrg head = (struct stored_event**)&dpy->cookiejar; 660b4ee4795Smrg 661b4ee4795Smrg DL_FOREACH_SAFE(*head, e, tmp) { 662b4ee4795Smrg if (dpy->cookiejar == e) 663b4ee4795Smrg dpy->cookiejar = NULL; 664c17aa6b1Smrg XFree(e->ev.data); 665c17aa6b1Smrg XFree(e); 666b4ee4795Smrg } 667b4ee4795Smrg} 668b4ee4795Smrg 669b4ee4795Smrg/** 670b4ee4795Smrg * Add an event to the display's event list. This event must be freed on the 671b4ee4795Smrg * next call to XNextEvent(). 672b4ee4795Smrg */ 673b4ee4795Smrgvoid 674b4ee4795Smrg_XStoreEventCookie(Display *dpy, XEvent *event) 675b4ee4795Smrg{ 676b4ee4795Smrg XGenericEventCookie* cookie = &event->xcookie; 677b4ee4795Smrg struct stored_event **head, *add; 678b4ee4795Smrg 679b4ee4795Smrg if (!_XIsEventCookie(dpy, event)) 680b4ee4795Smrg return; 681b4ee4795Smrg 682b4ee4795Smrg head = (struct stored_event**)(&dpy->cookiejar); 683b4ee4795Smrg 684b4ee4795Smrg add = Xmalloc(sizeof(struct stored_event)); 685b4ee4795Smrg if (!add) { 686b4ee4795Smrg ESET(ENOMEM); 687b4ee4795Smrg _XIOError(dpy); 688b4ee4795Smrg } 689b4ee4795Smrg add->ev = *cookie; 690b4ee4795Smrg DL_APPEND(*head, add); 691b4ee4795Smrg cookie->data = NULL; /* don't return data yet, must be claimed */ 692b4ee4795Smrg} 693b4ee4795Smrg 694b4ee4795Smrg/** 695b4ee4795Smrg * Return the event with the given cookie and remove it from the list. 696b4ee4795Smrg */ 697b4ee4795SmrgBool 698b4ee4795Smrg_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev) 699b4ee4795Smrg{ 700b4ee4795Smrg Bool ret = False; 701b4ee4795Smrg struct stored_event **head, *event; 702b4ee4795Smrg head = (struct stored_event**)&dpy->cookiejar; 703b4ee4795Smrg 704b4ee4795Smrg if (!_XIsEventCookie(dpy, (XEvent*)ev)) 705b4ee4795Smrg return ret; 706b4ee4795Smrg 707b4ee4795Smrg DL_FOREACH(*head, event) { 708b4ee4795Smrg if (event->ev.cookie == ev->cookie && 709b4ee4795Smrg event->ev.extension == ev->extension && 710b4ee4795Smrg event->ev.evtype == ev->evtype) { 711b4ee4795Smrg *ev = event->ev; 712b4ee4795Smrg DL_DELETE(*head, event); 713b4ee4795Smrg Xfree(event); 714b4ee4795Smrg ret = True; 715b4ee4795Smrg break; 716b4ee4795Smrg } 717b4ee4795Smrg } 718b4ee4795Smrg 719b4ee4795Smrg return ret; 720b4ee4795Smrg} 721b4ee4795Smrg 722b4ee4795SmrgBool 723b4ee4795Smrg_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out) 724b4ee4795Smrg{ 725b4ee4795Smrg Bool ret = False; 726b4ee4795Smrg int extension; 727b4ee4795Smrg 728b4ee4795Smrg if (!_XIsEventCookie(dpy, (XEvent*)in) || !out) 729b4ee4795Smrg return ret; 730b4ee4795Smrg 731b4ee4795Smrg extension = in->extension & 0x7F; 732b4ee4795Smrg 733b4ee4795Smrg if (!dpy->generic_event_copy_vec[extension]) 734b4ee4795Smrg return ret; 735b4ee4795Smrg 736b4ee4795Smrg ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out)); 737b4ee4795Smrg out->cookie = ret ? ++dpy->next_cookie : 0; 738b4ee4795Smrg return ret; 739b4ee4795Smrg} 740b4ee4795Smrg 7411ab64890Smrg 7421ab64890Smrg/* 7431ab64890Smrg * _XEnq - Place event packets on the display's queue. 7441ab64890Smrg * note that no squishing of move events in V11, since there 7451ab64890Smrg * is pointer motion hints.... 7461ab64890Smrg */ 7471ab64890Smrgvoid _XEnq( 7481ab64890Smrg register Display *dpy, 7491ab64890Smrg register xEvent *event) 7501ab64890Smrg{ 7511ab64890Smrg register _XQEvent *qelt; 752b4ee4795Smrg int type, extension; 7531ab64890Smrg 7541ab64890Smrg if ((qelt = dpy->qfree)) { 7551ab64890Smrg /* If dpy->qfree is non-NULL do this, else malloc a new one. */ 7561ab64890Smrg dpy->qfree = qelt->next; 7571ab64890Smrg } 758556b6652Smrg else if ((qelt = Xmalloc(sizeof(_XQEvent))) == NULL) { 7591ab64890Smrg /* Malloc call failed! */ 7601ab64890Smrg ESET(ENOMEM); 7611ab64890Smrg _XIOError(dpy); 7621ab64890Smrg } 7631ab64890Smrg qelt->next = NULL; 764b4ee4795Smrg 765b4ee4795Smrg type = event->u.u.type & 0177; 766b4ee4795Smrg extension = ((xGenericEvent*)event)->extension; 767295fb823Smrg 768295fb823Smrg qelt->event.type = type; 769556b6652Smrg /* If an extension has registered a generic_event_vec handler, then 770b4ee4795Smrg * it can handle event cookies. Otherwise, proceed with the normal 771b4ee4795Smrg * event handlers. 772b4ee4795Smrg * 773b4ee4795Smrg * If the generic_event_vec is called, qelt->event is a event cookie 774b4ee4795Smrg * with the data pointer and the "free" pointer set. Data pointer is 775b4ee4795Smrg * some memory allocated by the extension. 776b4ee4795Smrg */ 777b4ee4795Smrg if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) { 778b4ee4795Smrg XGenericEventCookie *cookie = &qelt->event.xcookie; 779b4ee4795Smrg (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event); 780b4ee4795Smrg cookie->cookie = ++dpy->next_cookie; 781b4ee4795Smrg 782b4ee4795Smrg qelt->qserial_num = dpy->next_event_serial_num++; 783b4ee4795Smrg if (dpy->tail) dpy->tail->next = qelt; 784b4ee4795Smrg else dpy->head = qelt; 785b4ee4795Smrg 786b4ee4795Smrg dpy->tail = qelt; 787b4ee4795Smrg dpy->qlen++; 788b4ee4795Smrg } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) { 7891ab64890Smrg qelt->qserial_num = dpy->next_event_serial_num++; 7901ab64890Smrg if (dpy->tail) dpy->tail->next = qelt; 7911ab64890Smrg else dpy->head = qelt; 79261b2299dSmrg 7931ab64890Smrg dpy->tail = qelt; 7941ab64890Smrg dpy->qlen++; 7951ab64890Smrg } else { 7961ab64890Smrg /* ignored, or stashed away for many-to-one compression */ 7971ab64890Smrg qelt->next = dpy->qfree; 7981ab64890Smrg dpy->qfree = qelt; 7991ab64890Smrg } 8001ab64890Smrg} 8011ab64890Smrg 8021ab64890Smrg/* 8031ab64890Smrg * _XDeq - Remove event packet from the display's queue. 8041ab64890Smrg */ 8051ab64890Smrgvoid _XDeq( 8061ab64890Smrg register Display *dpy, 8071ab64890Smrg register _XQEvent *prev, /* element before qelt */ 8081ab64890Smrg register _XQEvent *qelt) /* element to be unlinked */ 8091ab64890Smrg{ 8101ab64890Smrg if (prev) { 8111ab64890Smrg if ((prev->next = qelt->next) == NULL) 8121ab64890Smrg dpy->tail = prev; 8131ab64890Smrg } else { 8141ab64890Smrg /* no prev, so removing first elt */ 8151ab64890Smrg if ((dpy->head = qelt->next) == NULL) 8161ab64890Smrg dpy->tail = NULL; 8171ab64890Smrg } 8181ab64890Smrg qelt->qserial_num = 0; 8191ab64890Smrg qelt->next = dpy->qfree; 8201ab64890Smrg dpy->qfree = qelt; 8211ab64890Smrg dpy->qlen--; 822b4ee4795Smrg 823b4ee4795Smrg if (_XIsEventCookie(dpy, &qelt->event)) { 824b4ee4795Smrg XGenericEventCookie* cookie = &qelt->event.xcookie; 825b4ee4795Smrg /* dpy->qfree is re-used, reset memory to avoid double free on 826b4ee4795Smrg * _XFreeDisplayStructure */ 827b4ee4795Smrg cookie->data = NULL; 828b4ee4795Smrg } 8291ab64890Smrg} 8301ab64890Smrg 8311ab64890Smrg/* 8321ab64890Smrg * EventToWire in separate file in that often not needed. 8331ab64890Smrg */ 8341ab64890Smrg 8351ab64890Smrg/*ARGSUSED*/ 8361ab64890SmrgBool 8371ab64890Smrg_XUnknownWireEvent( 8381ab64890Smrg register Display *dpy, /* pointer to display structure */ 8391ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 8401ab64890Smrg register xEvent *event) /* wire protocol event */ 8411ab64890Smrg{ 8421ab64890Smrg#ifdef notdef 84361b2299dSmrg (void) fprintf(stderr, 8441ab64890Smrg "Xlib: unhandled wire event! event number = %d, display = %x\n.", 8451ab64890Smrg event->u.u.type, dpy); 8461ab64890Smrg#endif 8471ab64890Smrg return(False); 8481ab64890Smrg} 8491ab64890Smrg 850b4ee4795SmrgBool 851b4ee4795Smrg_XUnknownWireEventCookie( 852b4ee4795Smrg Display *dpy, /* pointer to display structure */ 853b4ee4795Smrg XGenericEventCookie *re, /* pointer to where event should be reformatted */ 854b4ee4795Smrg xEvent *event) /* wire protocol event */ 855b4ee4795Smrg{ 856b4ee4795Smrg#ifdef notdef 857b4ee4795Smrg fprintf(stderr, 858b4ee4795Smrg "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.", 859b4ee4795Smrg ((xGenericEvent*)event)->extension, dpy); 860b4ee4795Smrg#endif 861b4ee4795Smrg return(False); 862b4ee4795Smrg} 863b4ee4795Smrg 864b4ee4795SmrgBool 865b4ee4795Smrg_XUnknownCopyEventCookie( 866b4ee4795Smrg Display *dpy, /* pointer to display structure */ 867b4ee4795Smrg XGenericEventCookie *in, /* source */ 868b4ee4795Smrg XGenericEventCookie *out) /* destination */ 869b4ee4795Smrg{ 870b4ee4795Smrg#ifdef notdef 871b4ee4795Smrg fprintf(stderr, 872b4ee4795Smrg "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.", 873b4ee4795Smrg in->extension, dpy); 874b4ee4795Smrg#endif 875b4ee4795Smrg return(False); 876b4ee4795Smrg} 877b4ee4795Smrg 8781ab64890Smrg/*ARGSUSED*/ 8791ab64890SmrgStatus 8801ab64890Smrg_XUnknownNativeEvent( 8811ab64890Smrg register Display *dpy, /* pointer to display structure */ 8821ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 8831ab64890Smrg register xEvent *event) /* wire protocol event */ 8841ab64890Smrg{ 8851ab64890Smrg#ifdef notdef 88661b2299dSmrg (void) fprintf(stderr, 8871ab64890Smrg "Xlib: unhandled native event! event number = %d, display = %x\n.", 8881ab64890Smrg re->type, dpy); 8891ab64890Smrg#endif 8901ab64890Smrg return(0); 8911ab64890Smrg} 8921ab64890Smrg/* 8931ab64890Smrg * reformat a wire event into an XEvent structure of the right type. 8941ab64890Smrg */ 8951ab64890SmrgBool 8961ab64890Smrg_XWireToEvent( 8971ab64890Smrg register Display *dpy, /* pointer to display structure */ 8981ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 8991ab64890Smrg register xEvent *event) /* wire protocol event */ 9001ab64890Smrg{ 9011ab64890Smrg 9021ab64890Smrg re->type = event->u.u.type & 0x7f; 9031ab64890Smrg ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy, 9041ab64890Smrg (xGenericReply *)event); 9051ab64890Smrg ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0); 9061ab64890Smrg ((XAnyEvent *)re)->display = dpy; 90761b2299dSmrg 9081ab64890Smrg /* Ignore the leading bit of the event type since it is set when a 9091ab64890Smrg client sends an event rather than the server. */ 9101ab64890Smrg 9111ab64890Smrg switch (event-> u.u.type & 0177) { 9121ab64890Smrg case KeyPress: 9131ab64890Smrg case KeyRelease: 9141ab64890Smrg { 9151ab64890Smrg register XKeyEvent *ev = (XKeyEvent*) re; 9161ab64890Smrg ev->root = event->u.keyButtonPointer.root; 9171ab64890Smrg ev->window = event->u.keyButtonPointer.event; 9181ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 9191ab64890Smrg ev->time = event->u.keyButtonPointer.time; 9201ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 9211ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 9221ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 9231ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 9241ab64890Smrg ev->state = event->u.keyButtonPointer.state; 9251ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 9261ab64890Smrg ev->keycode = event->u.u.detail; 9271ab64890Smrg } 9281ab64890Smrg break; 9291ab64890Smrg case ButtonPress: 9301ab64890Smrg case ButtonRelease: 9311ab64890Smrg { 9321ab64890Smrg register XButtonEvent *ev = (XButtonEvent *) re; 9331ab64890Smrg ev->root = event->u.keyButtonPointer.root; 9341ab64890Smrg ev->window = event->u.keyButtonPointer.event; 9351ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 9361ab64890Smrg ev->time = event->u.keyButtonPointer.time; 9371ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 9381ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 9391ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 9401ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 9411ab64890Smrg ev->state = event->u.keyButtonPointer.state; 9421ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 9431ab64890Smrg ev->button = event->u.u.detail; 9441ab64890Smrg } 9451ab64890Smrg break; 9461ab64890Smrg case MotionNotify: 9471ab64890Smrg { 9481ab64890Smrg register XMotionEvent *ev = (XMotionEvent *)re; 9491ab64890Smrg ev->root = event->u.keyButtonPointer.root; 9501ab64890Smrg ev->window = event->u.keyButtonPointer.event; 9511ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 9521ab64890Smrg ev->time = event->u.keyButtonPointer.time; 9531ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 9541ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 9551ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 9561ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 9571ab64890Smrg ev->state = event->u.keyButtonPointer.state; 9581ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 9591ab64890Smrg ev->is_hint = event->u.u.detail; 9601ab64890Smrg } 9611ab64890Smrg break; 9621ab64890Smrg case EnterNotify: 9631ab64890Smrg case LeaveNotify: 9641ab64890Smrg { 9651ab64890Smrg register XCrossingEvent *ev = (XCrossingEvent *) re; 9661ab64890Smrg ev->root = event->u.enterLeave.root; 9671ab64890Smrg ev->window = event->u.enterLeave.event; 9681ab64890Smrg ev->subwindow = event->u.enterLeave.child; 9691ab64890Smrg ev->time = event->u.enterLeave.time; 9701ab64890Smrg ev->x = cvtINT16toInt(event->u.enterLeave.eventX); 9711ab64890Smrg ev->y = cvtINT16toInt(event->u.enterLeave.eventY); 9721ab64890Smrg ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX); 9731ab64890Smrg ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY); 9741ab64890Smrg ev->state = event->u.enterLeave.state; 9751ab64890Smrg ev->mode = event->u.enterLeave.mode; 97661b2299dSmrg ev->same_screen = (event->u.enterLeave.flags & 9771ab64890Smrg ELFlagSameScreen) && True; 9781ab64890Smrg ev->focus = (event->u.enterLeave.flags & 9791ab64890Smrg ELFlagFocus) && True; 9801ab64890Smrg ev->detail = event->u.u.detail; 9811ab64890Smrg } 9821ab64890Smrg break; 9831ab64890Smrg case FocusIn: 9841ab64890Smrg case FocusOut: 9851ab64890Smrg { 9861ab64890Smrg register XFocusChangeEvent *ev = (XFocusChangeEvent *) re; 9871ab64890Smrg ev->window = event->u.focus.window; 9881ab64890Smrg ev->mode = event->u.focus.mode; 9891ab64890Smrg ev->detail = event->u.u.detail; 9901ab64890Smrg } 9911ab64890Smrg break; 9921ab64890Smrg case KeymapNotify: 9931ab64890Smrg { 9941ab64890Smrg register XKeymapEvent *ev = (XKeymapEvent *) re; 9951ab64890Smrg ev->window = None; 9961ab64890Smrg memcpy(&ev->key_vector[1], 9971ab64890Smrg (char *)((xKeymapEvent *) event)->map, 9981ab64890Smrg sizeof (((xKeymapEvent *) event)->map)); 9991ab64890Smrg } 10001ab64890Smrg break; 10011ab64890Smrg case Expose: 10021ab64890Smrg { 10031ab64890Smrg register XExposeEvent *ev = (XExposeEvent *) re; 10041ab64890Smrg ev->window = event->u.expose.window; 10051ab64890Smrg ev->x = event->u.expose.x; 10061ab64890Smrg ev->y = event->u.expose.y; 10071ab64890Smrg ev->width = event->u.expose.width; 10081ab64890Smrg ev->height = event->u.expose.height; 10091ab64890Smrg ev->count = event->u.expose.count; 10101ab64890Smrg } 10111ab64890Smrg break; 10121ab64890Smrg case GraphicsExpose: 10131ab64890Smrg { 10141ab64890Smrg register XGraphicsExposeEvent *ev = 10151ab64890Smrg (XGraphicsExposeEvent *) re; 10161ab64890Smrg ev->drawable = event->u.graphicsExposure.drawable; 10171ab64890Smrg ev->x = event->u.graphicsExposure.x; 10181ab64890Smrg ev->y = event->u.graphicsExposure.y; 10191ab64890Smrg ev->width = event->u.graphicsExposure.width; 10201ab64890Smrg ev->height = event->u.graphicsExposure.height; 10211ab64890Smrg ev->count = event->u.graphicsExposure.count; 10221ab64890Smrg ev->major_code = event->u.graphicsExposure.majorEvent; 10231ab64890Smrg ev->minor_code = event->u.graphicsExposure.minorEvent; 10241ab64890Smrg } 10251ab64890Smrg break; 10261ab64890Smrg case NoExpose: 10271ab64890Smrg { 10281ab64890Smrg register XNoExposeEvent *ev = (XNoExposeEvent *) re; 10291ab64890Smrg ev->drawable = event->u.noExposure.drawable; 10301ab64890Smrg ev->major_code = event->u.noExposure.majorEvent; 10311ab64890Smrg ev->minor_code = event->u.noExposure.minorEvent; 10321ab64890Smrg } 10331ab64890Smrg break; 10341ab64890Smrg case VisibilityNotify: 10351ab64890Smrg { 10361ab64890Smrg register XVisibilityEvent *ev = (XVisibilityEvent *) re; 10371ab64890Smrg ev->window = event->u.visibility.window; 10381ab64890Smrg ev->state = event->u.visibility.state; 10391ab64890Smrg } 10401ab64890Smrg break; 10411ab64890Smrg case CreateNotify: 10421ab64890Smrg { 10431ab64890Smrg register XCreateWindowEvent *ev = 10441ab64890Smrg (XCreateWindowEvent *) re; 10451ab64890Smrg ev->window = event->u.createNotify.window; 10461ab64890Smrg ev->parent = event->u.createNotify.parent; 10471ab64890Smrg ev->x = cvtINT16toInt(event->u.createNotify.x); 10481ab64890Smrg ev->y = cvtINT16toInt(event->u.createNotify.y); 10491ab64890Smrg ev->width = event->u.createNotify.width; 10501ab64890Smrg ev->height = event->u.createNotify.height; 10511ab64890Smrg ev->border_width = event->u.createNotify.borderWidth; 10521ab64890Smrg ev->override_redirect = event->u.createNotify.override; 10531ab64890Smrg } 10541ab64890Smrg break; 10551ab64890Smrg case DestroyNotify: 10561ab64890Smrg { 10571ab64890Smrg register XDestroyWindowEvent *ev = 10581ab64890Smrg (XDestroyWindowEvent *) re; 10591ab64890Smrg ev->window = event->u.destroyNotify.window; 10601ab64890Smrg ev->event = event->u.destroyNotify.event; 10611ab64890Smrg } 10621ab64890Smrg break; 10631ab64890Smrg case UnmapNotify: 10641ab64890Smrg { 10651ab64890Smrg register XUnmapEvent *ev = (XUnmapEvent *) re; 10661ab64890Smrg ev->window = event->u.unmapNotify.window; 10671ab64890Smrg ev->event = event->u.unmapNotify.event; 10681ab64890Smrg ev->from_configure = event->u.unmapNotify.fromConfigure; 10691ab64890Smrg } 10701ab64890Smrg break; 10711ab64890Smrg case MapNotify: 10721ab64890Smrg { 10731ab64890Smrg register XMapEvent *ev = (XMapEvent *) re; 10741ab64890Smrg ev->window = event->u.mapNotify.window; 10751ab64890Smrg ev->event = event->u.mapNotify.event; 10761ab64890Smrg ev->override_redirect = event->u.mapNotify.override; 10771ab64890Smrg } 10781ab64890Smrg break; 10791ab64890Smrg case MapRequest: 10801ab64890Smrg { 10811ab64890Smrg register XMapRequestEvent *ev = (XMapRequestEvent *) re; 10821ab64890Smrg ev->window = event->u.mapRequest.window; 10831ab64890Smrg ev->parent = event->u.mapRequest.parent; 10841ab64890Smrg } 10851ab64890Smrg break; 10861ab64890Smrg case ReparentNotify: 10871ab64890Smrg { 10881ab64890Smrg register XReparentEvent *ev = (XReparentEvent *) re; 10891ab64890Smrg ev->event = event->u.reparent.event; 10901ab64890Smrg ev->window = event->u.reparent.window; 10911ab64890Smrg ev->parent = event->u.reparent.parent; 10921ab64890Smrg ev->x = cvtINT16toInt(event->u.reparent.x); 10931ab64890Smrg ev->y = cvtINT16toInt(event->u.reparent.y); 10941ab64890Smrg ev->override_redirect = event->u.reparent.override; 10951ab64890Smrg } 10961ab64890Smrg break; 10971ab64890Smrg case ConfigureNotify: 10981ab64890Smrg { 10991ab64890Smrg register XConfigureEvent *ev = (XConfigureEvent *) re; 11001ab64890Smrg ev->event = event->u.configureNotify.event; 11011ab64890Smrg ev->window = event->u.configureNotify.window; 11021ab64890Smrg ev->above = event->u.configureNotify.aboveSibling; 11031ab64890Smrg ev->x = cvtINT16toInt(event->u.configureNotify.x); 11041ab64890Smrg ev->y = cvtINT16toInt(event->u.configureNotify.y); 11051ab64890Smrg ev->width = event->u.configureNotify.width; 11061ab64890Smrg ev->height = event->u.configureNotify.height; 11071ab64890Smrg ev->border_width = event->u.configureNotify.borderWidth; 11081ab64890Smrg ev->override_redirect = event->u.configureNotify.override; 11091ab64890Smrg } 11101ab64890Smrg break; 11111ab64890Smrg case ConfigureRequest: 11121ab64890Smrg { 11131ab64890Smrg register XConfigureRequestEvent *ev = 11141ab64890Smrg (XConfigureRequestEvent *) re; 11151ab64890Smrg ev->window = event->u.configureRequest.window; 11161ab64890Smrg ev->parent = event->u.configureRequest.parent; 11171ab64890Smrg ev->above = event->u.configureRequest.sibling; 11181ab64890Smrg ev->x = cvtINT16toInt(event->u.configureRequest.x); 11191ab64890Smrg ev->y = cvtINT16toInt(event->u.configureRequest.y); 11201ab64890Smrg ev->width = event->u.configureRequest.width; 11211ab64890Smrg ev->height = event->u.configureRequest.height; 11221ab64890Smrg ev->border_width = event->u.configureRequest.borderWidth; 11231ab64890Smrg ev->value_mask = event->u.configureRequest.valueMask; 11241ab64890Smrg ev->detail = event->u.u.detail; 11251ab64890Smrg } 11261ab64890Smrg break; 11271ab64890Smrg case GravityNotify: 11281ab64890Smrg { 11291ab64890Smrg register XGravityEvent *ev = (XGravityEvent *) re; 11301ab64890Smrg ev->window = event->u.gravity.window; 11311ab64890Smrg ev->event = event->u.gravity.event; 11321ab64890Smrg ev->x = cvtINT16toInt(event->u.gravity.x); 11331ab64890Smrg ev->y = cvtINT16toInt(event->u.gravity.y); 11341ab64890Smrg } 11351ab64890Smrg break; 11361ab64890Smrg case ResizeRequest: 11371ab64890Smrg { 11381ab64890Smrg register XResizeRequestEvent *ev = 11391ab64890Smrg (XResizeRequestEvent *) re; 11401ab64890Smrg ev->window = event->u.resizeRequest.window; 11411ab64890Smrg ev->width = event->u.resizeRequest.width; 11421ab64890Smrg ev->height = event->u.resizeRequest.height; 11431ab64890Smrg } 11441ab64890Smrg break; 11451ab64890Smrg case CirculateNotify: 11461ab64890Smrg { 11471ab64890Smrg register XCirculateEvent *ev = (XCirculateEvent *) re; 11481ab64890Smrg ev->window = event->u.circulate.window; 11491ab64890Smrg ev->event = event->u.circulate.event; 11501ab64890Smrg ev->place = event->u.circulate.place; 11511ab64890Smrg } 11521ab64890Smrg break; 11531ab64890Smrg case CirculateRequest: 11541ab64890Smrg { 11551ab64890Smrg register XCirculateRequestEvent *ev = 11561ab64890Smrg (XCirculateRequestEvent *) re; 11571ab64890Smrg ev->window = event->u.circulate.window; 11581ab64890Smrg ev->parent = event->u.circulate.event; 11591ab64890Smrg ev->place = event->u.circulate.place; 11601ab64890Smrg } 11611ab64890Smrg break; 11621ab64890Smrg case PropertyNotify: 11631ab64890Smrg { 11641ab64890Smrg register XPropertyEvent *ev = (XPropertyEvent *) re; 11651ab64890Smrg ev->window = event->u.property.window; 11661ab64890Smrg ev->atom = event->u.property.atom; 11671ab64890Smrg ev->time = event->u.property.time; 11681ab64890Smrg ev->state = event->u.property.state; 11691ab64890Smrg } 11701ab64890Smrg break; 11711ab64890Smrg case SelectionClear: 11721ab64890Smrg { 11731ab64890Smrg register XSelectionClearEvent *ev = 11741ab64890Smrg (XSelectionClearEvent *) re; 11751ab64890Smrg ev->window = event->u.selectionClear.window; 11761ab64890Smrg ev->selection = event->u.selectionClear.atom; 11771ab64890Smrg ev->time = event->u.selectionClear.time; 11781ab64890Smrg } 11791ab64890Smrg break; 11801ab64890Smrg case SelectionRequest: 11811ab64890Smrg { 11821ab64890Smrg register XSelectionRequestEvent *ev = 11831ab64890Smrg (XSelectionRequestEvent *) re; 11841ab64890Smrg ev->owner = event->u.selectionRequest.owner; 11851ab64890Smrg ev->requestor = event->u.selectionRequest.requestor; 11861ab64890Smrg ev->selection = event->u.selectionRequest.selection; 11871ab64890Smrg ev->target = event->u.selectionRequest.target; 11881ab64890Smrg ev->property = event->u.selectionRequest.property; 11891ab64890Smrg ev->time = event->u.selectionRequest.time; 11901ab64890Smrg } 11911ab64890Smrg break; 11921ab64890Smrg case SelectionNotify: 11931ab64890Smrg { 11941ab64890Smrg register XSelectionEvent *ev = (XSelectionEvent *) re; 11951ab64890Smrg ev->requestor = event->u.selectionNotify.requestor; 11961ab64890Smrg ev->selection = event->u.selectionNotify.selection; 11971ab64890Smrg ev->target = event->u.selectionNotify.target; 11981ab64890Smrg ev->property = event->u.selectionNotify.property; 11991ab64890Smrg ev->time = event->u.selectionNotify.time; 12001ab64890Smrg } 12011ab64890Smrg break; 12021ab64890Smrg case ColormapNotify: 12031ab64890Smrg { 12041ab64890Smrg register XColormapEvent *ev = (XColormapEvent *) re; 12051ab64890Smrg ev->window = event->u.colormap.window; 12061ab64890Smrg ev->colormap = event->u.colormap.colormap; 12071ab64890Smrg ev->new = event->u.colormap.new; 12081ab64890Smrg ev->state = event->u.colormap.state; 12091ab64890Smrg } 12101ab64890Smrg break; 12111ab64890Smrg case ClientMessage: 12121ab64890Smrg { 12131ab64890Smrg register int i; 121461b2299dSmrg register XClientMessageEvent *ev 12151ab64890Smrg = (XClientMessageEvent *) re; 12161ab64890Smrg ev->window = event->u.clientMessage.window; 12171ab64890Smrg ev->format = event->u.u.detail; 12181ab64890Smrg switch (ev->format) { 121961b2299dSmrg case 8: 12201ab64890Smrg ev->message_type = event->u.clientMessage.u.b.type; 122161b2299dSmrg for (i = 0; i < 20; i++) 12221ab64890Smrg ev->data.b[i] = event->u.clientMessage.u.b.bytes[i]; 12231ab64890Smrg break; 12241ab64890Smrg case 16: 12251ab64890Smrg ev->message_type = event->u.clientMessage.u.s.type; 12261ab64890Smrg ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0); 12271ab64890Smrg ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1); 12281ab64890Smrg ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2); 12291ab64890Smrg ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3); 12301ab64890Smrg ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4); 12311ab64890Smrg ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5); 12321ab64890Smrg ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6); 12331ab64890Smrg ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7); 12341ab64890Smrg ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8); 12351ab64890Smrg ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9); 12361ab64890Smrg break; 12371ab64890Smrg case 32: 12381ab64890Smrg ev->message_type = event->u.clientMessage.u.l.type; 12391ab64890Smrg ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0); 12401ab64890Smrg ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1); 12411ab64890Smrg ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2); 12421ab64890Smrg ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3); 12431ab64890Smrg ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4); 12441ab64890Smrg break; 12451ab64890Smrg default: /* XXX should never occur */ 12461ab64890Smrg break; 12471ab64890Smrg } 12481ab64890Smrg } 12491ab64890Smrg break; 12501ab64890Smrg case MappingNotify: 12511ab64890Smrg { 12521ab64890Smrg register XMappingEvent *ev = (XMappingEvent *)re; 12531ab64890Smrg ev->window = 0; 12541ab64890Smrg ev->first_keycode = event->u.mappingNotify.firstKeyCode; 12551ab64890Smrg ev->request = event->u.mappingNotify.request; 12561ab64890Smrg ev->count = event->u.mappingNotify.count; 12571ab64890Smrg } 12581ab64890Smrg break; 12591ab64890Smrg default: 12601ab64890Smrg return(_XUnknownWireEvent(dpy, re, event)); 12611ab64890Smrg } 12621ab64890Smrg return(True); 12631ab64890Smrg} 12641ab64890Smrg 12651ab64890Smrg 12661ab64890Smrg/* 126761b2299dSmrg * _XDefaultIOError - Default fatal system error reporting routine. Called 12681ab64890Smrg * when an X internal system error is encountered. 12691ab64890Smrg */ 12701ab64890Smrgint _XDefaultIOError( 12711ab64890Smrg Display *dpy) 12721ab64890Smrg{ 12731ab64890Smrg if (ECHECK(EPIPE)) { 12741ab64890Smrg (void) fprintf (stderr, 12751ab64890Smrg "X connection to %s broken (explicit kill or server shutdown).\r\n", 12761ab64890Smrg DisplayString (dpy)); 12771ab64890Smrg } else { 127861b2299dSmrg (void) fprintf (stderr, 12791ab64890Smrg "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n", 12801ab64890Smrg#ifdef WIN32 12811ab64890Smrg WSAGetLastError(), strerror(WSAGetLastError()), 12821ab64890Smrg#else 12831ab64890Smrg errno, strerror (errno), 12841ab64890Smrg#endif 12851ab64890Smrg DisplayString (dpy)); 128661b2299dSmrg (void) fprintf (stderr, 12871ab64890Smrg " after %lu requests (%lu known processed) with %d events remaining.\r\n", 12881ab64890Smrg NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy), 12891ab64890Smrg QLength(dpy)); 12901ab64890Smrg 12911ab64890Smrg } 12921ab64890Smrg exit(1); 12931ab64890Smrg return(0); /* dummy - function should never return */ 12941ab64890Smrg} 12951ab64890Smrg 12961ab64890Smrg 12971ab64890Smrgstatic int _XPrintDefaultError( 12981ab64890Smrg Display *dpy, 12991ab64890Smrg XErrorEvent *event, 13001ab64890Smrg FILE *fp) 13011ab64890Smrg{ 13021ab64890Smrg char buffer[BUFSIZ]; 13031ab64890Smrg char mesg[BUFSIZ]; 13041ab64890Smrg char number[32]; 13051ab64890Smrg const char *mtype = "XlibMessage"; 13061ab64890Smrg register _XExtension *ext = (_XExtension *)NULL; 13071ab64890Smrg _XExtension *bext = (_XExtension *)NULL; 13081ab64890Smrg XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); 13091ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); 13101ab64890Smrg (void) fprintf(fp, "%s: %s\n ", mesg, buffer); 131161b2299dSmrg XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", 13121ab64890Smrg mesg, BUFSIZ); 13131ab64890Smrg (void) fprintf(fp, mesg, event->request_code); 13141ab64890Smrg if (event->request_code < 128) { 1315556b6652Smrg snprintf(number, sizeof(number), "%d", event->request_code); 13161ab64890Smrg XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); 13171ab64890Smrg } else { 13181ab64890Smrg for (ext = dpy->ext_procs; 13191ab64890Smrg ext && (ext->codes.major_opcode != event->request_code); 13201ab64890Smrg ext = ext->next) 13211ab64890Smrg ; 1322c17aa6b1Smrg if (ext) { 1323c17aa6b1Smrg strncpy(buffer, ext->name, BUFSIZ); 1324c17aa6b1Smrg buffer[BUFSIZ - 1] = '\0'; 1325c17aa6b1Smrg } else 13261ab64890Smrg buffer[0] = '\0'; 13271ab64890Smrg } 13281ab64890Smrg (void) fprintf(fp, " (%s)\n", buffer); 13291ab64890Smrg if (event->request_code >= 128) { 13301ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", 13311ab64890Smrg mesg, BUFSIZ); 13321ab64890Smrg fputs(" ", fp); 13331ab64890Smrg (void) fprintf(fp, mesg, event->minor_code); 13341ab64890Smrg if (ext) { 1335556b6652Smrg snprintf(mesg, sizeof(mesg), "%s.%d", ext->name, event->minor_code); 13361ab64890Smrg XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); 13371ab64890Smrg (void) fprintf(fp, " (%s)", buffer); 13381ab64890Smrg } 13391ab64890Smrg fputs("\n", fp); 13401ab64890Smrg } 13411ab64890Smrg if (event->error_code >= 128) { 13421ab64890Smrg /* kludge, try to find the extension that caused it */ 13431ab64890Smrg buffer[0] = '\0'; 13441ab64890Smrg for (ext = dpy->ext_procs; ext; ext = ext->next) { 134561b2299dSmrg if (ext->error_string) 13461ab64890Smrg (*ext->error_string)(dpy, event->error_code, &ext->codes, 13471ab64890Smrg buffer, BUFSIZ); 13481ab64890Smrg if (buffer[0]) { 13491ab64890Smrg bext = ext; 13501ab64890Smrg break; 13511ab64890Smrg } 13521ab64890Smrg if (ext->codes.first_error && 13531ab64890Smrg ext->codes.first_error < (int)event->error_code && 13541ab64890Smrg (!bext || ext->codes.first_error > bext->codes.first_error)) 13551ab64890Smrg bext = ext; 135661b2299dSmrg } 13571ab64890Smrg if (bext) 1358556b6652Smrg snprintf(buffer, sizeof(buffer), "%s.%d", bext->name, 1359556b6652Smrg event->error_code - bext->codes.first_error); 13601ab64890Smrg else 13611ab64890Smrg strcpy(buffer, "Value"); 13621ab64890Smrg XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); 13631ab64890Smrg if (mesg[0]) { 13641ab64890Smrg fputs(" ", fp); 13651ab64890Smrg (void) fprintf(fp, mesg, event->resourceid); 13661ab64890Smrg fputs("\n", fp); 13671ab64890Smrg } 13681ab64890Smrg /* let extensions try to print the values */ 13691ab64890Smrg for (ext = dpy->ext_procs; ext; ext = ext->next) { 13701ab64890Smrg if (ext->error_values) 13711ab64890Smrg (*ext->error_values)(dpy, event, fp); 13721ab64890Smrg } 13731ab64890Smrg } else if ((event->error_code == BadWindow) || 13741ab64890Smrg (event->error_code == BadPixmap) || 13751ab64890Smrg (event->error_code == BadCursor) || 13761ab64890Smrg (event->error_code == BadFont) || 13771ab64890Smrg (event->error_code == BadDrawable) || 13781ab64890Smrg (event->error_code == BadColor) || 13791ab64890Smrg (event->error_code == BadGC) || 13801ab64890Smrg (event->error_code == BadIDChoice) || 13811ab64890Smrg (event->error_code == BadValue) || 13821ab64890Smrg (event->error_code == BadAtom)) { 13831ab64890Smrg if (event->error_code == BadValue) 13841ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", 13851ab64890Smrg mesg, BUFSIZ); 13861ab64890Smrg else if (event->error_code == BadAtom) 13871ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", 13881ab64890Smrg mesg, BUFSIZ); 13891ab64890Smrg else 13901ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", 13911ab64890Smrg mesg, BUFSIZ); 13921ab64890Smrg fputs(" ", fp); 13931ab64890Smrg (void) fprintf(fp, mesg, event->resourceid); 13941ab64890Smrg fputs("\n", fp); 13951ab64890Smrg } 139661b2299dSmrg XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", 13971ab64890Smrg mesg, BUFSIZ); 13981ab64890Smrg fputs(" ", fp); 13991ab64890Smrg (void) fprintf(fp, mesg, event->serial); 14001ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", 14011ab64890Smrg mesg, BUFSIZ); 14021ab64890Smrg fputs("\n ", fp); 14031ab64890Smrg (void) fprintf(fp, mesg, dpy->request); 14041ab64890Smrg fputs("\n", fp); 14051ab64890Smrg if (event->error_code == BadImplementation) return 0; 14061ab64890Smrg return 1; 14071ab64890Smrg} 14081ab64890Smrg 14091ab64890Smrgint _XDefaultError( 14101ab64890Smrg Display *dpy, 14111ab64890Smrg XErrorEvent *event) 14121ab64890Smrg{ 14131ab64890Smrg if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0; 14141ab64890Smrg exit(1); 14151ab64890Smrg /*NOTREACHED*/ 14161ab64890Smrg} 14171ab64890Smrg 14181ab64890Smrg/*ARGSUSED*/ 141961b2299dSmrgBool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we) 14201ab64890Smrg{ 14211ab64890Smrg return True; 14221ab64890Smrg} 14231ab64890Smrg 14241ab64890Smrg/* 14251ab64890Smrg * _XError - upcall internal or user protocol error handler 14261ab64890Smrg */ 14271ab64890Smrgint _XError ( 14281ab64890Smrg Display *dpy, 14291ab64890Smrg register xError *rep) 14301ab64890Smrg{ 143161b2299dSmrg /* 14321ab64890Smrg * X_Error packet encountered! We need to unpack the error before 14331ab64890Smrg * giving it to the user. 14341ab64890Smrg */ 14351ab64890Smrg XEvent event; /* make it a large event */ 14361ab64890Smrg register _XAsyncHandler *async, *next; 14371ab64890Smrg 14381ab64890Smrg event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep); 14391ab64890Smrg 14401ab64890Smrg for (async = dpy->async_handlers; async; async = next) { 14411ab64890Smrg next = async->next; 14421ab64890Smrg if ((*async->handler)(dpy, (xReply *)rep, 14431ab64890Smrg (char *)rep, SIZEOF(xError), async->data)) 14441ab64890Smrg return 0; 14451ab64890Smrg } 14461ab64890Smrg 14471ab64890Smrg event.xerror.display = dpy; 14481ab64890Smrg event.xerror.type = X_Error; 14491ab64890Smrg event.xerror.resourceid = rep->resourceID; 14501ab64890Smrg event.xerror.error_code = rep->errorCode; 14511ab64890Smrg event.xerror.request_code = rep->majorCode; 14521ab64890Smrg event.xerror.minor_code = rep->minorCode; 14531ab64890Smrg if (dpy->error_vec && 14541ab64890Smrg !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep)) 14551ab64890Smrg return 0; 14561ab64890Smrg if (_XErrorFunction != NULL) { 1457c17aa6b1Smrg int rtn_val; 1458c17aa6b1Smrg#ifdef XTHREADS 1459c17aa6b1Smrg if (dpy->lock) 1460c17aa6b1Smrg (*dpy->lock->user_lock_display)(dpy); 1461c17aa6b1Smrg UnlockDisplay(dpy); 1462c17aa6b1Smrg#endif 1463c17aa6b1Smrg rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ 1464c17aa6b1Smrg#ifdef XTHREADS 1465c17aa6b1Smrg LockDisplay(dpy); 1466c17aa6b1Smrg if (dpy->lock) 1467c17aa6b1Smrg (*dpy->lock->user_unlock_display)(dpy); 1468c17aa6b1Smrg#endif 1469c17aa6b1Smrg return rtn_val; 14701ab64890Smrg } else { 14711ab64890Smrg return _XDefaultError(dpy, (XErrorEvent *)&event); 14721ab64890Smrg } 14731ab64890Smrg} 147461b2299dSmrg 14751ab64890Smrg/* 14761ab64890Smrg * _XIOError - call user connection error handler and exit 14771ab64890Smrg */ 14781ab64890Smrgint 14791ab64890Smrg_XIOError ( 14801ab64890Smrg Display *dpy) 14811ab64890Smrg{ 14821ab64890Smrg dpy->flags |= XlibDisplayIOError; 14831ab64890Smrg#ifdef WIN32 14841ab64890Smrg errno = WSAGetLastError(); 14851ab64890Smrg#endif 14861ab64890Smrg 14871ab64890Smrg /* This assumes that the thread calling exit will call any atexit handlers. 14881ab64890Smrg * If this does not hold, then an alternate solution would involve 14891ab64890Smrg * registering an atexit handler to take over the lock, which would only 14901ab64890Smrg * assume that the same thread calls all the atexit handlers. */ 14911ab64890Smrg#ifdef XTHREADS 14921ab64890Smrg if (dpy->lock) 14931ab64890Smrg (*dpy->lock->user_lock_display)(dpy); 14941ab64890Smrg#endif 14951ab64890Smrg UnlockDisplay(dpy); 14961ab64890Smrg 14971ab64890Smrg if (_XIOErrorFunction != NULL) 14981ab64890Smrg (*_XIOErrorFunction)(dpy); 14991ab64890Smrg else 15001ab64890Smrg _XDefaultIOError(dpy); 15011ab64890Smrg exit (1); 15021ab64890Smrg return 0; 15031ab64890Smrg} 15041ab64890Smrg 15051ab64890Smrg 15061ab64890Smrg/* 15071ab64890Smrg * This routine can be used to (cheaply) get some memory within a single 15081ab64890Smrg * Xlib routine for scratch space. A single buffer is reused each time 15091ab64890Smrg * if possible. To be MT safe, you can only call this between a call to 15101ab64890Smrg * GetReq* and a call to Data* or _XSend*, or in a context when the thread 15111ab64890Smrg * is guaranteed to not unlock the display. 15121ab64890Smrg */ 15131ab64890Smrgchar *_XAllocScratch( 15141ab64890Smrg register Display *dpy, 15151ab64890Smrg unsigned long nbytes) 15161ab64890Smrg{ 15171ab64890Smrg if (nbytes > dpy->scratch_length) { 15181ab64890Smrg if (dpy->scratch_buffer) Xfree (dpy->scratch_buffer); 1519556b6652Smrg if ((dpy->scratch_buffer = Xmalloc(nbytes))) 15201ab64890Smrg dpy->scratch_length = nbytes; 15211ab64890Smrg else dpy->scratch_length = 0; 15221ab64890Smrg } 15231ab64890Smrg return (dpy->scratch_buffer); 15241ab64890Smrg} 15251ab64890Smrg 15261ab64890Smrg/* 15271ab64890Smrg * Scratch space allocator you can call any time, multiple times, and be 15281ab64890Smrg * MT safe, but you must hand the buffer back with _XFreeTemp. 15291ab64890Smrg */ 15301ab64890Smrgchar *_XAllocTemp( 15311ab64890Smrg register Display *dpy, 15321ab64890Smrg unsigned long nbytes) 15331ab64890Smrg{ 15341ab64890Smrg char *buf; 15351ab64890Smrg 15361ab64890Smrg buf = _XAllocScratch(dpy, nbytes); 15371ab64890Smrg dpy->scratch_buffer = NULL; 15381ab64890Smrg dpy->scratch_length = 0; 15391ab64890Smrg return buf; 15401ab64890Smrg} 15411ab64890Smrg 15421ab64890Smrgvoid _XFreeTemp( 15431ab64890Smrg register Display *dpy, 15441ab64890Smrg char *buf, 15451ab64890Smrg unsigned long nbytes) 15461ab64890Smrg{ 15471ab64890Smrg if (dpy->scratch_buffer) 15481ab64890Smrg Xfree(dpy->scratch_buffer); 15491ab64890Smrg dpy->scratch_buffer = buf; 15501ab64890Smrg dpy->scratch_length = nbytes; 15511ab64890Smrg} 15521ab64890Smrg 15531ab64890Smrg/* 15541ab64890Smrg * Given a visual id, find the visual structure for this id on this display. 15551ab64890Smrg */ 15561ab64890SmrgVisual *_XVIDtoVisual( 15571ab64890Smrg Display *dpy, 15581ab64890Smrg VisualID id) 15591ab64890Smrg{ 15601ab64890Smrg register int i, j, k; 15611ab64890Smrg register Screen *sp; 15621ab64890Smrg register Depth *dp; 15631ab64890Smrg register Visual *vp; 15641ab64890Smrg for (i = 0; i < dpy->nscreens; i++) { 15651ab64890Smrg sp = &dpy->screens[i]; 15661ab64890Smrg for (j = 0; j < sp->ndepths; j++) { 15671ab64890Smrg dp = &sp->depths[j]; 15681ab64890Smrg /* if nvisuals == 0 then visuals will be NULL */ 15691ab64890Smrg for (k = 0; k < dp->nvisuals; k++) { 15701ab64890Smrg vp = &dp->visuals[k]; 15711ab64890Smrg if (vp->visualid == id) return (vp); 15721ab64890Smrg } 15731ab64890Smrg } 15741ab64890Smrg } 15751ab64890Smrg return (NULL); 15761ab64890Smrg} 15771ab64890Smrg 15781ab64890Smrgint 15791ab64890SmrgXFree (void *data) 15801ab64890Smrg{ 15811ab64890Smrg Xfree (data); 15821ab64890Smrg return 1; 15831ab64890Smrg} 15841ab64890Smrg 15851ab64890Smrg#ifdef _XNEEDBCOPYFUNC 15861ab64890Smrgvoid _Xbcopy(b1, b2, length) 15871ab64890Smrg register char *b1, *b2; 15881ab64890Smrg register length; 15891ab64890Smrg{ 15901ab64890Smrg if (b1 < b2) { 15911ab64890Smrg b2 += length; 15921ab64890Smrg b1 += length; 15931ab64890Smrg while (length--) 15941ab64890Smrg *--b2 = *--b1; 15951ab64890Smrg } else { 15961ab64890Smrg while (length--) 15971ab64890Smrg *b2++ = *b1++; 15981ab64890Smrg } 15991ab64890Smrg} 16001ab64890Smrg#endif 16011ab64890Smrg 16021ab64890Smrg#ifdef DataRoutineIsProcedure 16031ab64890Smrgvoid Data( 16041ab64890Smrg Display *dpy, 1605556b6652Smrg _Xconst char *data, 16061ab64890Smrg long len) 16071ab64890Smrg{ 16081ab64890Smrg if (dpy->bufptr + (len) <= dpy->bufmax) { 16091ab64890Smrg memcpy(dpy->bufptr, data, (int)len); 16101ab64890Smrg dpy->bufptr += ((len) + 3) & ~3; 16111ab64890Smrg } else { 16121ab64890Smrg _XSend(dpy, data, len); 16131ab64890Smrg } 16141ab64890Smrg} 16151ab64890Smrg#endif /* DataRoutineIsProcedure */ 16161ab64890Smrg 16171ab64890Smrg 16181ab64890Smrg#ifdef LONG64 16191ab64890Smrgint 16201ab64890Smrg_XData32( 16211ab64890Smrg Display *dpy, 1622556b6652Smrg register _Xconst long *data, 16231ab64890Smrg unsigned len) 16241ab64890Smrg{ 16251ab64890Smrg register int *buf; 16261ab64890Smrg register long i; 16271ab64890Smrg 16281ab64890Smrg while (len) { 16291ab64890Smrg buf = (int *)dpy->bufptr; 16301ab64890Smrg i = dpy->bufmax - (char *)buf; 16311ab64890Smrg if (!i) { 16321ab64890Smrg _XFlush(dpy); 16331ab64890Smrg continue; 16341ab64890Smrg } 16351ab64890Smrg if (len < i) 16361ab64890Smrg i = len; 16371ab64890Smrg dpy->bufptr = (char *)buf + i; 16381ab64890Smrg len -= i; 16391ab64890Smrg i >>= 2; 16401ab64890Smrg while (--i >= 0) 16411ab64890Smrg *buf++ = *data++; 16421ab64890Smrg } 16431ab64890Smrg return 0; 16441ab64890Smrg} 16451ab64890Smrg#endif /* LONG64 */ 16461ab64890Smrg 16471ab64890Smrg 16481ab64890Smrg 16491ab64890Smrg/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm. 16501ab64890Smrg * Otherwise, Xau will not be able to find your cookies in the Xauthority file. 16511ab64890Smrg * 16521ab64890Smrg * Note: POSIX says that the ``nodename'' member of utsname does _not_ have 16531ab64890Smrg * to have sufficient information for interfacing to the network, 16541ab64890Smrg * and so, you may be better off using gethostname (if it exists). 16551ab64890Smrg */ 16561ab64890Smrg 16572e9c7c8cSmrg#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4) 16581ab64890Smrg#define NEED_UTSNAME 16591ab64890Smrg#include <sys/utsname.h> 166088de56ccSmrg#else 166188de56ccSmrg#ifdef HAVE_UNISTD_H 166288de56ccSmrg#include <unistd.h> 166388de56ccSmrg#endif 16641ab64890Smrg#endif 16651ab64890Smrg 16661ab64890Smrg/* 16671ab64890Smrg * _XGetHostname - similar to gethostname but allows special processing. 16681ab64890Smrg */ 16691ab64890Smrgint _XGetHostname ( 16701ab64890Smrg char *buf, 16711ab64890Smrg int maxlen) 16721ab64890Smrg{ 16731ab64890Smrg int len; 16741ab64890Smrg 16751ab64890Smrg#ifdef NEED_UTSNAME 16761ab64890Smrg struct utsname name; 16771ab64890Smrg 16781ab64890Smrg if (maxlen <= 0 || buf == NULL) 16791ab64890Smrg return 0; 16801ab64890Smrg 16811ab64890Smrg uname (&name); 16821ab64890Smrg len = strlen (name.nodename); 16831ab64890Smrg if (len >= maxlen) len = maxlen - 1; 16841ab64890Smrg strncpy (buf, name.nodename, len); 16851ab64890Smrg buf[len] = '\0'; 16861ab64890Smrg#else 16871ab64890Smrg if (maxlen <= 0 || buf == NULL) 16881ab64890Smrg return 0; 16891ab64890Smrg 16901ab64890Smrg buf[0] = '\0'; 16911ab64890Smrg (void) gethostname (buf, maxlen); 16921ab64890Smrg buf [maxlen - 1] = '\0'; 16931ab64890Smrg len = strlen(buf); 16941ab64890Smrg#endif /* NEED_UTSNAME */ 16951ab64890Smrg return len; 16961ab64890Smrg} 16971ab64890Smrg 16981ab64890Smrg 16991ab64890Smrg/* 17001ab64890Smrg * _XScreenOfWindow - get the Screen of a given window 17011ab64890Smrg */ 17021ab64890Smrg 170361b2299dSmrgScreen *_XScreenOfWindow(Display *dpy, Window w) 17041ab64890Smrg{ 17051ab64890Smrg register int i; 17061ab64890Smrg Window root; 17071ab64890Smrg int x, y; /* dummy variables */ 17081ab64890Smrg unsigned int width, height, bw, depth; /* dummy variables */ 17091ab64890Smrg 17101ab64890Smrg if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height, 17111ab64890Smrg &bw, &depth) == False) { 17122e9c7c8cSmrg return NULL; 17131ab64890Smrg } 17141ab64890Smrg for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */ 17151ab64890Smrg if (root == RootWindow (dpy, i)) { 17161ab64890Smrg return ScreenOfDisplay (dpy, i); 17171ab64890Smrg } 17181ab64890Smrg } 17191ab64890Smrg return NULL; 17201ab64890Smrg} 17211ab64890Smrg 17221ab64890Smrg 1723556b6652Smrg/* 1724556b6652Smrg * WARNING: This implementation's pre-conditions and post-conditions 1725556b6652Smrg * must remain compatible with the old macro-based implementations of 1726556b6652Smrg * GetReq, GetReqExtra, GetResReq, and GetEmptyReq. The portions of the 1727556b6652Smrg * Display structure affected by those macros are part of libX11's 1728556b6652Smrg * ABI. 1729556b6652Smrg */ 1730556b6652Smrgvoid *_XGetRequest(Display *dpy, CARD8 type, size_t len) 1731556b6652Smrg{ 1732556b6652Smrg xReq *req; 1733556b6652Smrg 1734556b6652Smrg if (dpy->bufptr + len > dpy->bufmax) 1735556b6652Smrg _XFlush(dpy); 1736556b6652Smrg 1737556b6652Smrg if (len % 4) 1738556b6652Smrg fprintf(stderr, 1739556b6652Smrg "Xlib: request %d length %zd not a multiple of 4.\n", 1740556b6652Smrg type, len); 1741556b6652Smrg 1742556b6652Smrg dpy->last_req = dpy->bufptr; 1743556b6652Smrg 1744556b6652Smrg req = (xReq*)dpy->bufptr; 1745556b6652Smrg req->reqType = type; 1746556b6652Smrg req->length = len / 4; 1747556b6652Smrg dpy->bufptr += len; 1748556b6652Smrg dpy->request++; 1749556b6652Smrg return req; 1750556b6652Smrg} 1751556b6652Smrg 17521ab64890Smrg#if defined(WIN32) 17531ab64890Smrg 17541ab64890Smrg/* 17551ab64890Smrg * These functions are intended to be used internally to Xlib only. 17561ab64890Smrg * These functions will always prefix the path with a DOS drive in the 17571ab64890Smrg * form "<drive-letter>:". As such, these functions are only suitable 17581ab64890Smrg * for use by Xlib function that supply a root-based path to some 17591ab64890Smrg * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will 17601ab64890Smrg * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir". 17611ab64890Smrg */ 17621ab64890Smrg 17631ab64890Smrgstatic int access_file (path, pathbuf, len_pathbuf, pathret) 17641ab64890Smrg char* path; 17651ab64890Smrg char* pathbuf; 17661ab64890Smrg int len_pathbuf; 17671ab64890Smrg char** pathret; 17681ab64890Smrg{ 17691ab64890Smrg if (access (path, F_OK) == 0) { 17701ab64890Smrg if (strlen (path) < len_pathbuf) 17711ab64890Smrg *pathret = pathbuf; 17721ab64890Smrg else 17731ab64890Smrg *pathret = Xmalloc (strlen (path) + 1); 17741ab64890Smrg if (*pathret) { 17751ab64890Smrg strcpy (*pathret, path); 17761ab64890Smrg return 1; 17771ab64890Smrg } 17781ab64890Smrg } 17791ab64890Smrg return 0; 17801ab64890Smrg} 17811ab64890Smrg 17821ab64890Smrgstatic int AccessFile (path, pathbuf, len_pathbuf, pathret) 17831ab64890Smrg char* path; 17841ab64890Smrg char* pathbuf; 17851ab64890Smrg int len_pathbuf; 17861ab64890Smrg char** pathret; 17871ab64890Smrg{ 17881ab64890Smrg unsigned long drives; 17891ab64890Smrg int i, len; 17901ab64890Smrg char* drive; 17911ab64890Smrg char buf[MAX_PATH]; 17921ab64890Smrg char* bufp; 17931ab64890Smrg 17941ab64890Smrg /* just try the "raw" name first and see if it works */ 17951ab64890Smrg if (access_file (path, pathbuf, len_pathbuf, pathret)) 17961ab64890Smrg return 1; 17971ab64890Smrg 17981ab64890Smrg /* try the places set in the environment */ 17991ab64890Smrg drive = getenv ("_XBASEDRIVE"); 18001ab64890Smrg#ifdef __UNIXOS2__ 18011ab64890Smrg if (!drive) 18021ab64890Smrg drive = getenv ("X11ROOT"); 18031ab64890Smrg#endif 18041ab64890Smrg if (!drive) 18051ab64890Smrg drive = "C:"; 18061ab64890Smrg len = strlen (drive) + strlen (path); 18071ab64890Smrg if (len < MAX_PATH) bufp = buf; 18081ab64890Smrg else bufp = Xmalloc (len + 1); 18091ab64890Smrg strcpy (bufp, drive); 18101ab64890Smrg strcat (bufp, path); 18111ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 18121ab64890Smrg if (bufp != buf) Xfree (bufp); 18131ab64890Smrg return 1; 18141ab64890Smrg } 18151ab64890Smrg 181661b2299dSmrg#ifndef __UNIXOS2__ 18171ab64890Smrg /* one last place to look */ 18181ab64890Smrg drive = getenv ("HOMEDRIVE"); 18191ab64890Smrg if (drive) { 18201ab64890Smrg len = strlen (drive) + strlen (path); 18211ab64890Smrg if (len < MAX_PATH) bufp = buf; 18221ab64890Smrg else bufp = Xmalloc (len + 1); 18231ab64890Smrg strcpy (bufp, drive); 18241ab64890Smrg strcat (bufp, path); 18251ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 18261ab64890Smrg if (bufp != buf) Xfree (bufp); 18271ab64890Smrg return 1; 18281ab64890Smrg } 18291ab64890Smrg } 18301ab64890Smrg 18311ab64890Smrg /* tried everywhere else, go fishing */ 18321ab64890Smrg#define C_DRIVE ('C' - 'A') 18331ab64890Smrg#define Z_DRIVE ('Z' - 'A') 18341ab64890Smrg /* does OS/2 (with or with gcc-emx) have getdrives? */ 18351ab64890Smrg drives = _getdrives (); 18361ab64890Smrg for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */ 18371ab64890Smrg if ((1 << i) & drives) { 18381ab64890Smrg len = 2 + strlen (path); 18391ab64890Smrg if (len < MAX_PATH) bufp = buf; 18401ab64890Smrg else bufp = Xmalloc (len + 1); 18411ab64890Smrg *bufp = 'A' + i; 18421ab64890Smrg *(bufp + 1) = ':'; 18431ab64890Smrg *(bufp + 2) = '\0'; 18441ab64890Smrg strcat (bufp, path); 18451ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 18461ab64890Smrg if (bufp != buf) Xfree (bufp); 18471ab64890Smrg return 1; 18481ab64890Smrg } 18491ab64890Smrg } 18501ab64890Smrg } 18511ab64890Smrg#endif 18521ab64890Smrg return 0; 18531ab64890Smrg} 18541ab64890Smrg 18551ab64890Smrgint _XOpenFile(path, flags) 18561ab64890Smrg _Xconst char* path; 18571ab64890Smrg int flags; 18581ab64890Smrg{ 18591ab64890Smrg char buf[MAX_PATH]; 18601ab64890Smrg char* bufp = NULL; 18611ab64890Smrg int ret = -1; 18621ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 18631ab64890Smrg 18641ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 18651ab64890Smrg ret = open (bufp, flags); 18661ab64890Smrg 18671ab64890Smrg (void) SetErrorMode (olderror); 18681ab64890Smrg 18691ab64890Smrg if (bufp != buf) Xfree (bufp); 18701ab64890Smrg 18711ab64890Smrg return ret; 18721ab64890Smrg} 18731ab64890Smrg 18741ab64890Smrgint _XOpenFileMode(path, flags, mode) 18751ab64890Smrg _Xconst char* path; 18761ab64890Smrg int flags; 18771ab64890Smrg mode_t mode; 18781ab64890Smrg{ 18791ab64890Smrg char buf[MAX_PATH]; 18801ab64890Smrg char* bufp = NULL; 18811ab64890Smrg int ret = -1; 18821ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 18831ab64890Smrg 18841ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 18851ab64890Smrg ret = open (bufp, flags, mode); 18861ab64890Smrg 18871ab64890Smrg (void) SetErrorMode (olderror); 18881ab64890Smrg 18891ab64890Smrg if (bufp != buf) Xfree (bufp); 18901ab64890Smrg 18911ab64890Smrg return ret; 18921ab64890Smrg} 18931ab64890Smrg 18941ab64890Smrgvoid* _XFopenFile(path, mode) 18951ab64890Smrg _Xconst char* path; 18961ab64890Smrg _Xconst char* mode; 18971ab64890Smrg{ 18981ab64890Smrg char buf[MAX_PATH]; 18991ab64890Smrg char* bufp = NULL; 19001ab64890Smrg void* ret = NULL; 19011ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 19021ab64890Smrg 19031ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 19041ab64890Smrg ret = fopen (bufp, mode); 19051ab64890Smrg 19061ab64890Smrg (void) SetErrorMode (olderror); 19071ab64890Smrg 19081ab64890Smrg if (bufp != buf) Xfree (bufp); 19091ab64890Smrg 19101ab64890Smrg return ret; 19111ab64890Smrg} 19121ab64890Smrg 19131ab64890Smrgint _XAccessFile(path) 19141ab64890Smrg _Xconst char* path; 19151ab64890Smrg{ 19161ab64890Smrg char buf[MAX_PATH]; 19171ab64890Smrg char* bufp; 19181ab64890Smrg int ret = -1; 19191ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 19201ab64890Smrg 19211ab64890Smrg ret = AccessFile (path, buf, MAX_PATH, &bufp); 19221ab64890Smrg 19231ab64890Smrg (void) SetErrorMode (olderror); 19241ab64890Smrg 19251ab64890Smrg if (bufp != buf) Xfree (bufp); 19261ab64890Smrg 19271ab64890Smrg return ret; 19281ab64890Smrg} 19291ab64890Smrg 19301ab64890Smrg#endif 19311ab64890Smrg 19321ab64890Smrg#ifdef WIN32 19331ab64890Smrg#undef _Xdebug 19341ab64890Smrgint _Xdebug = 0; 19351ab64890Smrgint *_Xdebug_p = &_Xdebug; 19361ab64890Smrgvoid (**_XCreateMutex_fn_p)(LockInfoPtr) = &_XCreateMutex_fn; 19371ab64890Smrgvoid (**_XFreeMutex_fn_p)(LockInfoPtr) = &_XFreeMutex_fn; 19381ab64890Smrgvoid (**_XLockMutex_fn_p)(LockInfoPtr 19391ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 19401ab64890Smrg , char * /* file */ 19411ab64890Smrg , int /* line */ 19421ab64890Smrg#endif 19431ab64890Smrg ) = &_XLockMutex_fn; 19441ab64890Smrgvoid (**_XUnlockMutex_fn_p)(LockInfoPtr 19451ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 19461ab64890Smrg , char * /* file */ 19471ab64890Smrg , int /* line */ 19481ab64890Smrg#endif 19491ab64890Smrg ) = &_XUnlockMutex_fn; 19501ab64890SmrgLockInfoPtr *_Xglobal_lock_p = &_Xglobal_lock; 19511ab64890Smrg#endif 1952