XlibInt.c revision cf2acdde
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#ifdef WIN32 781ab64890Smrg#define ECHECK(err) (WSAGetLastError() == err) 791ab64890Smrg#define ESET(val) WSASetLastError(val) 801ab64890Smrg#else 811ab64890Smrg#ifdef __UNIXOS2__ 821ab64890Smrg#define ECHECK(err) (errno == err) 831ab64890Smrg#define ESET(val) 841ab64890Smrg#else 851ab64890Smrg#define ECHECK(err) (errno == err) 861ab64890Smrg#define ESET(val) errno = val 871ab64890Smrg#endif 881ab64890Smrg#endif 891ab64890Smrg 901ab64890Smrg#ifdef __UNIXOS2__ 911ab64890Smrg#include <limits.h> 921ab64890Smrg#define MAX_PATH _POSIX_PATH_MAX 931ab64890Smrg#endif 941ab64890Smrg 951ab64890Smrg/* 961ab64890Smrg * The following routines are internal routines used by Xlib for protocol 971ab64890Smrg * packet transmission and reception. 981ab64890Smrg * 991ab64890Smrg * _XIOError(Display *) will be called if any sort of system call error occurs. 1001ab64890Smrg * This is assumed to be a fatal condition, i.e., XIOError should not return. 1011ab64890Smrg * 1021ab64890Smrg * _XError(Display *, xError *) will be called whenever an X_Error event is 1031ab64890Smrg * received. This is not assumed to be a fatal condition, i.e., it is 1041ab64890Smrg * acceptable for this procedure to return. However, XError should NOT 1051ab64890Smrg * perform any operations (directly or indirectly) on the DISPLAY. 1061ab64890Smrg * 1071ab64890Smrg * Routines declared with a return type of 'Status' return 0 on failure, 10861b2299dSmrg * and non 0 on success. Routines with no declared return type don't 1091ab64890Smrg * return anything. Whenever possible routines that create objects return 1101ab64890Smrg * the object they have created. 1111ab64890Smrg */ 1121ab64890Smrg 1131ab64890Smrg#define POLLFD_CACHE_SIZE 5 1141ab64890Smrg 1151ab64890Smrg/* initialize the struct array passed to poll() below */ 1161ab64890SmrgBool _XPollfdCacheInit( 1171ab64890Smrg Display *dpy) 1181ab64890Smrg{ 1191ab64890Smrg#ifdef USE_POLL 1201ab64890Smrg struct pollfd *pfp; 1211ab64890Smrg 122556b6652Smrg pfp = Xmalloc(POLLFD_CACHE_SIZE * sizeof(struct pollfd)); 1231ab64890Smrg if (!pfp) 1241ab64890Smrg return False; 1251ab64890Smrg pfp[0].fd = dpy->fd; 1261ab64890Smrg pfp[0].events = POLLIN; 1271ab64890Smrg 1281ab64890Smrg dpy->filedes = (XPointer)pfp; 1291ab64890Smrg#endif 1301ab64890Smrg return True; 1311ab64890Smrg} 1321ab64890Smrg 1331ab64890Smrgvoid _XPollfdCacheAdd( 1341ab64890Smrg Display *dpy, 1351ab64890Smrg int fd) 1361ab64890Smrg{ 1371ab64890Smrg#ifdef USE_POLL 1381ab64890Smrg struct pollfd *pfp = (struct pollfd *)dpy->filedes; 1391ab64890Smrg 1401ab64890Smrg if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { 1411ab64890Smrg pfp[dpy->im_fd_length].fd = fd; 1421ab64890Smrg pfp[dpy->im_fd_length].events = POLLIN; 1431ab64890Smrg } 1441ab64890Smrg#endif 1451ab64890Smrg} 1461ab64890Smrg 1471ab64890Smrg/* ARGSUSED */ 1481ab64890Smrgvoid _XPollfdCacheDel( 1491ab64890Smrg Display *dpy, 1501ab64890Smrg int fd) /* not used */ 1511ab64890Smrg{ 1521ab64890Smrg#ifdef USE_POLL 1531ab64890Smrg struct pollfd *pfp = (struct pollfd *)dpy->filedes; 1541ab64890Smrg struct _XConnectionInfo *conni; 1551ab64890Smrg 1561ab64890Smrg /* just recalculate whole list */ 1571ab64890Smrg if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { 1581ab64890Smrg int loc = 1; 1591ab64890Smrg for (conni = dpy->im_fd_info; conni; conni=conni->next) { 1601ab64890Smrg pfp[loc].fd = conni->fd; 1611ab64890Smrg pfp[loc].events = POLLIN; 1621ab64890Smrg loc++; 1631ab64890Smrg } 1641ab64890Smrg } 1651ab64890Smrg#endif 1661ab64890Smrg} 1671ab64890Smrg 16861b2299dSmrgstatic int sync_hazard(Display *dpy) 16961b2299dSmrg{ 17061b2299dSmrg unsigned long span = dpy->request - dpy->last_request_read; 17161b2299dSmrg unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10); 17261b2299dSmrg return span >= 65535 - hazard - 10; 17361b2299dSmrg} 17461b2299dSmrg 1751ab64890Smrgstatic 17688de56ccSmrgvoid sync_while_locked(Display *dpy) 17788de56ccSmrg{ 17888de56ccSmrg#ifdef XTHREADS 17988de56ccSmrg if (dpy->lock) 18088de56ccSmrg (*dpy->lock->user_lock_display)(dpy); 18188de56ccSmrg#endif 18288de56ccSmrg UnlockDisplay(dpy); 18388de56ccSmrg SyncHandle(); 18488de56ccSmrg InternalLockDisplay(dpy, /* don't skip user locks */ 0); 18588de56ccSmrg#ifdef XTHREADS 18688de56ccSmrg if (dpy->lock) 18788de56ccSmrg (*dpy->lock->user_unlock_display)(dpy); 18888de56ccSmrg#endif 18988de56ccSmrg} 19088de56ccSmrg 19188de56ccSmrgvoid _XSeqSyncFunction( 1921ab64890Smrg register Display *dpy) 1931ab64890Smrg{ 1941ab64890Smrg xGetInputFocusReply rep; 1951ab64890Smrg register xReq *req; 1961ab64890Smrg 19761b2299dSmrg if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) { 1981ab64890Smrg GetEmptyReq(GetInputFocus, req); 1991ab64890Smrg (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); 20088de56ccSmrg sync_while_locked(dpy); 20161b2299dSmrg } else if (sync_hazard(dpy)) 20261b2299dSmrg _XSetPrivSyncFunction(dpy); 2031ab64890Smrg} 2041ab64890Smrg 20588de56ccSmrg/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */ 20661b2299dSmrgstatic int 20761b2299dSmrg_XPrivSyncFunction (Display *dpy) 20861b2299dSmrg{ 209e0787e08Smrg#ifdef XTHREADS 21088de56ccSmrg assert(!dpy->lock_fns); 21188de56ccSmrg#endif 21261b2299dSmrg assert(dpy->synchandler == _XPrivSyncFunction); 21361b2299dSmrg assert((dpy->flags & XlibDisplayPrivSync) != 0); 21461b2299dSmrg dpy->synchandler = dpy->savedsynchandler; 21561b2299dSmrg dpy->savedsynchandler = NULL; 21661b2299dSmrg dpy->flags &= ~XlibDisplayPrivSync; 21788de56ccSmrg if(dpy->synchandler) 21888de56ccSmrg dpy->synchandler(dpy); 21961b2299dSmrg _XIDHandler(dpy); 22061b2299dSmrg _XSeqSyncFunction(dpy); 22161b2299dSmrg return 0; 22261b2299dSmrg} 22361b2299dSmrg 22461b2299dSmrgvoid _XSetPrivSyncFunction(Display *dpy) 2251ab64890Smrg{ 22688de56ccSmrg#ifdef XTHREADS 22788de56ccSmrg if (dpy->lock_fns) 22888de56ccSmrg return; 22988de56ccSmrg#endif 23061b2299dSmrg if (!(dpy->flags & XlibDisplayPrivSync)) { 2311ab64890Smrg dpy->savedsynchandler = dpy->synchandler; 23261b2299dSmrg dpy->synchandler = _XPrivSyncFunction; 2331ab64890Smrg dpy->flags |= XlibDisplayPrivSync; 2341ab64890Smrg } 2351ab64890Smrg} 2361ab64890Smrg 23761b2299dSmrgvoid _XSetSeqSyncFunction(Display *dpy) 23861b2299dSmrg{ 23961b2299dSmrg if (sync_hazard(dpy)) 24061b2299dSmrg _XSetPrivSyncFunction (dpy); 24161b2299dSmrg} 24261b2299dSmrg 2431ab64890Smrg#ifdef LONG64 2441ab64890Smrgvoid _XRead32( 2451ab64890Smrg Display *dpy, 2461ab64890Smrg register long *data, 2471ab64890Smrg long len) 2481ab64890Smrg{ 2491ab64890Smrg register int *buf; 2501ab64890Smrg register long i; 2511ab64890Smrg 2521ab64890Smrg if (len) { 2531ab64890Smrg (void) _XRead(dpy, (char *)data, len); 2541ab64890Smrg i = len >> 2; 2551ab64890Smrg buf = (int *)data + i; 2561ab64890Smrg data += i; 2571ab64890Smrg while (--i >= 0) 2581ab64890Smrg *--data = *--buf; 2591ab64890Smrg } 2601ab64890Smrg} 2611ab64890Smrg#endif /* LONG64 */ 2621ab64890Smrg 2631ab64890Smrg 2641ab64890Smrg/* 2651ab64890Smrg * The hard part about this is that we only get 16 bits from a reply. 2661ab64890Smrg * We have three values that will march along, with the following invariant: 2671ab64890Smrg * dpy->last_request_read <= rep->sequenceNumber <= dpy->request 2681ab64890Smrg * We have to keep 2691ab64890Smrg * dpy->request - dpy->last_request_read < 2^16 2701ab64890Smrg * or else we won't know for sure what value to use in events. We do this 2711ab64890Smrg * by forcing syncs when we get close. 2721ab64890Smrg */ 2731ab64890Smrg 2741ab64890Smrgunsigned long 2751ab64890Smrg_XSetLastRequestRead( 2761ab64890Smrg register Display *dpy, 2771ab64890Smrg register xGenericReply *rep) 2781ab64890Smrg{ 2791ab64890Smrg register unsigned long newseq, lastseq; 2801ab64890Smrg 2811ab64890Smrg lastseq = dpy->last_request_read; 2821ab64890Smrg /* 2831ab64890Smrg * KeymapNotify has no sequence number, but is always guaranteed 2841ab64890Smrg * to immediately follow another event, except when generated via 2851ab64890Smrg * SendEvent (hmmm). 2861ab64890Smrg */ 2871ab64890Smrg if ((rep->type & 0x7f) == KeymapNotify) 2881ab64890Smrg return(lastseq); 2891ab64890Smrg 2901ab64890Smrg newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber; 2911ab64890Smrg 2921ab64890Smrg if (newseq < lastseq) { 2931ab64890Smrg newseq += 0x10000; 2941ab64890Smrg if (newseq > dpy->request) { 29561b2299dSmrg (void) fprintf (stderr, 2961ab64890Smrg "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n", 29761b2299dSmrg newseq, dpy->request, 2981ab64890Smrg (unsigned int) rep->type); 2991ab64890Smrg newseq -= 0x10000; 3001ab64890Smrg } 3011ab64890Smrg } 3021ab64890Smrg 3031ab64890Smrg dpy->last_request_read = newseq; 3041ab64890Smrg return(newseq); 3051ab64890Smrg} 3061ab64890Smrg 3071ab64890Smrg/* 3081ab64890Smrg * Support for internal connections, such as an IM might use. 3091ab64890Smrg * By Stephen Gildea, X Consortium, September 1993 3101ab64890Smrg */ 3111ab64890Smrg 3121ab64890Smrg/* _XRegisterInternalConnection 3131ab64890Smrg * Each IM (or Xlib extension) that opens a file descriptor that Xlib should 3141ab64890Smrg * include in its select/poll mask must call this function to register the 3151ab64890Smrg * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch 3161ab64890Smrg * will also be called. 3171ab64890Smrg * 3181ab64890Smrg * Whenever Xlib detects input available on fd, it will call callback 3191ab64890Smrg * with call_data to process it. If non-Xlib code calls select/poll 3201ab64890Smrg * and detects input available, it must call XProcessInternalConnection, 3211ab64890Smrg * which will call the associated callback. 3221ab64890Smrg * 3231ab64890Smrg * Non-Xlib code can learn about these additional fds by calling 3241ab64890Smrg * XInternalConnectionNumbers or, more typically, by registering 3251ab64890Smrg * a XConnectionWatchProc with XAddConnectionWatch 3261ab64890Smrg * to be called when fds are registered or unregistered. 3271ab64890Smrg * 3281ab64890Smrg * Returns True if registration succeeded, False if not, typically 3291ab64890Smrg * because could not allocate memory. 3301ab64890Smrg * Assumes Display locked when called. 3311ab64890Smrg */ 3321ab64890SmrgStatus 3331ab64890Smrg_XRegisterInternalConnection( 3341ab64890Smrg Display* dpy, 3351ab64890Smrg int fd, 3361ab64890Smrg _XInternalConnectionProc callback, 3371ab64890Smrg XPointer call_data 3381ab64890Smrg) 3391ab64890Smrg{ 3401ab64890Smrg struct _XConnectionInfo *new_conni, **iptr; 3411ab64890Smrg struct _XConnWatchInfo *watchers; 3421ab64890Smrg XPointer *wd; 3431ab64890Smrg 344556b6652Smrg new_conni = Xmalloc(sizeof(struct _XConnectionInfo)); 3451ab64890Smrg if (!new_conni) 3461ab64890Smrg return 0; 347556b6652Smrg new_conni->watch_data = Xmalloc(dpy->watcher_count * sizeof(XPointer)); 3481ab64890Smrg if (!new_conni->watch_data) { 3491ab64890Smrg Xfree(new_conni); 3501ab64890Smrg return 0; 3511ab64890Smrg } 3521ab64890Smrg new_conni->fd = fd; 3531ab64890Smrg new_conni->read_callback = callback; 3541ab64890Smrg new_conni->call_data = call_data; 3551ab64890Smrg new_conni->next = NULL; 3561ab64890Smrg /* link new structure onto end of list */ 3571ab64890Smrg for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next) 3581ab64890Smrg ; 3591ab64890Smrg *iptr = new_conni; 3601ab64890Smrg dpy->im_fd_length++; 3611ab64890Smrg _XPollfdCacheAdd(dpy, fd); 3621ab64890Smrg 3631ab64890Smrg for (watchers=dpy->conn_watchers, wd=new_conni->watch_data; 3641ab64890Smrg watchers; 3651ab64890Smrg watchers=watchers->next, wd++) { 3661ab64890Smrg *wd = NULL; /* for cleanliness */ 3671ab64890Smrg (*watchers->fn) (dpy, watchers->client_data, fd, True, wd); 3681ab64890Smrg } 3691ab64890Smrg 3701ab64890Smrg return 1; 3711ab64890Smrg} 3721ab64890Smrg 3731ab64890Smrg/* _XUnregisterInternalConnection 3741ab64890Smrg * Each IM (or Xlib extension) that closes a file descriptor previously 3751ab64890Smrg * registered with _XRegisterInternalConnection must call this function. 3761ab64890Smrg * Any XConnectionWatchProc registered by XAddConnectionWatch 3771ab64890Smrg * will also be called. 3781ab64890Smrg * 3791ab64890Smrg * Assumes Display locked when called. 3801ab64890Smrg */ 3811ab64890Smrgvoid 3821ab64890Smrg_XUnregisterInternalConnection( 3831ab64890Smrg Display* dpy, 3841ab64890Smrg int fd 3851ab64890Smrg) 3861ab64890Smrg{ 3871ab64890Smrg struct _XConnectionInfo *info_list, **prev; 3881ab64890Smrg struct _XConnWatchInfo *watch; 3891ab64890Smrg XPointer *wd; 3901ab64890Smrg 3911ab64890Smrg for (prev = &dpy->im_fd_info; (info_list = *prev); 3921ab64890Smrg prev = &info_list->next) { 3931ab64890Smrg if (info_list->fd == fd) { 3941ab64890Smrg *prev = info_list->next; 3951ab64890Smrg dpy->im_fd_length--; 3961ab64890Smrg for (watch=dpy->conn_watchers, wd=info_list->watch_data; 3971ab64890Smrg watch; 3981ab64890Smrg watch=watch->next, wd++) { 3991ab64890Smrg (*watch->fn) (dpy, watch->client_data, fd, False, wd); 4001ab64890Smrg } 401cf2acddeSmrg Xfree (info_list->watch_data); 4021ab64890Smrg Xfree (info_list); 4031ab64890Smrg break; 4041ab64890Smrg } 4051ab64890Smrg } 4061ab64890Smrg _XPollfdCacheDel(dpy, fd); 4071ab64890Smrg} 4081ab64890Smrg 4091ab64890Smrg/* XInternalConnectionNumbers 4101ab64890Smrg * Returns an array of fds and an array of corresponding call data. 4111ab64890Smrg * Typically a XConnectionWatchProc registered with XAddConnectionWatch 4121ab64890Smrg * will be used instead of this function to discover 4131ab64890Smrg * additional fds to include in the select/poll mask. 4141ab64890Smrg * 4151ab64890Smrg * The list is allocated with Xmalloc and should be freed by the caller 4161ab64890Smrg * with Xfree; 4171ab64890Smrg */ 4181ab64890SmrgStatus 4191ab64890SmrgXInternalConnectionNumbers( 4201ab64890Smrg Display *dpy, 4211ab64890Smrg int **fd_return, 4221ab64890Smrg int *count_return 4231ab64890Smrg) 4241ab64890Smrg{ 4251ab64890Smrg int count; 4261ab64890Smrg struct _XConnectionInfo *info_list; 4271ab64890Smrg int *fd_list; 4281ab64890Smrg 4291ab64890Smrg LockDisplay(dpy); 4301ab64890Smrg count = 0; 4311ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) 4321ab64890Smrg count++; 433556b6652Smrg fd_list = Xmalloc (count * sizeof(int)); 4341ab64890Smrg if (!fd_list) { 4351ab64890Smrg UnlockDisplay(dpy); 4361ab64890Smrg return 0; 4371ab64890Smrg } 4381ab64890Smrg count = 0; 4391ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 4401ab64890Smrg fd_list[count] = info_list->fd; 4411ab64890Smrg count++; 4421ab64890Smrg } 4431ab64890Smrg UnlockDisplay(dpy); 4441ab64890Smrg 4451ab64890Smrg *fd_return = fd_list; 4461ab64890Smrg *count_return = count; 4471ab64890Smrg return 1; 4481ab64890Smrg} 4491ab64890Smrg 4501ab64890Smrgvoid _XProcessInternalConnection( 4511ab64890Smrg Display *dpy, 4521ab64890Smrg struct _XConnectionInfo *conn_info) 4531ab64890Smrg{ 4541ab64890Smrg dpy->flags |= XlibDisplayProcConni; 4551ab64890Smrg UnlockDisplay(dpy); 4561ab64890Smrg (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data); 4571ab64890Smrg LockDisplay(dpy); 4581ab64890Smrg dpy->flags &= ~XlibDisplayProcConni; 4591ab64890Smrg} 4601ab64890Smrg 4611ab64890Smrg/* XProcessInternalConnection 4621ab64890Smrg * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection 4631ab64890Smrg * for this fd. 4641ab64890Smrg * The Display is NOT locked during the call. 4651ab64890Smrg */ 4661ab64890Smrgvoid 4671ab64890SmrgXProcessInternalConnection( 4681ab64890Smrg Display* dpy, 4691ab64890Smrg int fd 4701ab64890Smrg) 4711ab64890Smrg{ 4721ab64890Smrg struct _XConnectionInfo *info_list; 4731ab64890Smrg 4741ab64890Smrg LockDisplay(dpy); 4751ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 4761ab64890Smrg if (info_list->fd == fd) { 4771ab64890Smrg _XProcessInternalConnection(dpy, info_list); 4781ab64890Smrg break; 4791ab64890Smrg } 4801ab64890Smrg } 4811ab64890Smrg UnlockDisplay(dpy); 4821ab64890Smrg} 4831ab64890Smrg 4841ab64890Smrg/* XAddConnectionWatch 4851ab64890Smrg * Register a callback to be called whenever _XRegisterInternalConnection 4861ab64890Smrg * or _XUnregisterInternalConnection is called. 4871ab64890Smrg * Callbacks are called with the Display locked. 4881ab64890Smrg * If any connections are already registered, the callback is immediately 4891ab64890Smrg * called for each of them. 4901ab64890Smrg */ 4911ab64890SmrgStatus 4921ab64890SmrgXAddConnectionWatch( 4931ab64890Smrg Display* dpy, 4941ab64890Smrg XConnectionWatchProc callback, 4951ab64890Smrg XPointer client_data 4961ab64890Smrg) 4971ab64890Smrg{ 4981ab64890Smrg struct _XConnWatchInfo *new_watcher, **wptr; 4991ab64890Smrg struct _XConnectionInfo *info_list; 5001ab64890Smrg XPointer *wd_array; 5011ab64890Smrg 5021ab64890Smrg LockDisplay(dpy); 5031ab64890Smrg 5041ab64890Smrg /* allocate new watch data */ 5051ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 506556b6652Smrg wd_array = Xrealloc(info_list->watch_data, 507556b6652Smrg (dpy->watcher_count + 1) * sizeof(XPointer)); 5081ab64890Smrg if (!wd_array) { 5091ab64890Smrg UnlockDisplay(dpy); 5101ab64890Smrg return 0; 5111ab64890Smrg } 512c17aa6b1Smrg info_list->watch_data = wd_array; 5131ab64890Smrg wd_array[dpy->watcher_count] = NULL; /* for cleanliness */ 5141ab64890Smrg } 5151ab64890Smrg 516556b6652Smrg new_watcher = Xmalloc(sizeof(struct _XConnWatchInfo)); 5171ab64890Smrg if (!new_watcher) { 5181ab64890Smrg UnlockDisplay(dpy); 5191ab64890Smrg return 0; 5201ab64890Smrg } 5211ab64890Smrg new_watcher->fn = callback; 5221ab64890Smrg new_watcher->client_data = client_data; 5231ab64890Smrg new_watcher->next = NULL; 5241ab64890Smrg 5251ab64890Smrg /* link new structure onto end of list */ 5261ab64890Smrg for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next) 5271ab64890Smrg ; 5281ab64890Smrg *wptr = new_watcher; 5291ab64890Smrg dpy->watcher_count++; 5301ab64890Smrg 5311ab64890Smrg /* call new watcher on all currently registered fds */ 5321ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 5331ab64890Smrg (*callback) (dpy, client_data, info_list->fd, True, 5341ab64890Smrg info_list->watch_data + dpy->watcher_count - 1); 5351ab64890Smrg } 5361ab64890Smrg 5371ab64890Smrg UnlockDisplay(dpy); 5381ab64890Smrg return 1; 5391ab64890Smrg} 5401ab64890Smrg 5411ab64890Smrg/* XRemoveConnectionWatch 5421ab64890Smrg * Unregister a callback registered by XAddConnectionWatch. 5431ab64890Smrg * Both callback and client_data must match what was passed to 5441ab64890Smrg * XAddConnectionWatch. 54561b2299dSmrg */ 5461ab64890Smrgvoid 5471ab64890SmrgXRemoveConnectionWatch( 5481ab64890Smrg Display* dpy, 5491ab64890Smrg XConnectionWatchProc callback, 5501ab64890Smrg XPointer client_data 5511ab64890Smrg) 5521ab64890Smrg{ 5531ab64890Smrg struct _XConnWatchInfo *watch; 5541ab64890Smrg struct _XConnWatchInfo *previous = NULL; 5551ab64890Smrg struct _XConnectionInfo *conni; 5561ab64890Smrg int counter = 0; 5571ab64890Smrg 5581ab64890Smrg LockDisplay(dpy); 5591ab64890Smrg for (watch=dpy->conn_watchers; watch; watch=watch->next) { 5601ab64890Smrg if (watch->fn == callback && watch->client_data == client_data) { 5611ab64890Smrg if (previous) 5621ab64890Smrg previous->next = watch->next; 5631ab64890Smrg else 5641ab64890Smrg dpy->conn_watchers = watch->next; 5651ab64890Smrg Xfree (watch); 5661ab64890Smrg dpy->watcher_count--; 5671ab64890Smrg /* remove our watch_data for each connection */ 5681ab64890Smrg for (conni=dpy->im_fd_info; conni; conni=conni->next) { 5691ab64890Smrg /* don't bother realloc'ing; these arrays are small anyway */ 5701ab64890Smrg /* overlapping */ 5711ab64890Smrg memmove(conni->watch_data+counter, 5721ab64890Smrg conni->watch_data+counter+1, 5731ab64890Smrg dpy->watcher_count - counter); 5741ab64890Smrg } 5751ab64890Smrg break; 5761ab64890Smrg } 5771ab64890Smrg previous = watch; 5781ab64890Smrg counter++; 5791ab64890Smrg } 5801ab64890Smrg UnlockDisplay(dpy); 5811ab64890Smrg} 5821ab64890Smrg 5831ab64890Smrg/* end of internal connections support */ 5841ab64890Smrg 585b4ee4795Smrg/* Cookie jar implementation 586b4ee4795Smrg dpy->cookiejar is a linked list. _XEnq receives the events but leaves 587b4ee4795Smrg them in the normal EQ. _XStoreEvent returns the cookie event (minus 588b4ee4795Smrg data pointer) and adds it to the cookiejar. _XDeq just removes 589b4ee4795Smrg the entry like any other event but resets the data pointer for 590b4ee4795Smrg cookie events (to avoid double-free, the memory is re-used by Xlib). 591b4ee4795Smrg 592b4ee4795Smrg _XFetchEventCookie (called from XGetEventData) removes a cookie from the 593b4ee4795Smrg jar. _XFreeEventCookies removes all unclaimed cookies from the jar 594b4ee4795Smrg (called by XNextEvent). 595b4ee4795Smrg 596b4ee4795Smrg _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the 597b4ee4795Smrg normal EQ. 598b4ee4795Smrg */ 599b4ee4795Smrg 600b4ee4795Smrg#include "utlist.h" 601b4ee4795Smrgstruct stored_event { 602b4ee4795Smrg XGenericEventCookie ev; 603b4ee4795Smrg struct stored_event *prev; 604b4ee4795Smrg struct stored_event *next; 605b4ee4795Smrg}; 606b4ee4795Smrg 607b4ee4795SmrgBool 608b4ee4795Smrg_XIsEventCookie(Display *dpy, XEvent *ev) 609b4ee4795Smrg{ 610b4ee4795Smrg return (ev->xcookie.type == GenericEvent && 611b4ee4795Smrg dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL); 612b4ee4795Smrg} 613b4ee4795Smrg 614b4ee4795Smrg/** 615b4ee4795Smrg * Free all events in the event list. 616b4ee4795Smrg */ 617b4ee4795Smrgvoid 618b4ee4795Smrg_XFreeEventCookies(Display *dpy) 619b4ee4795Smrg{ 620b4ee4795Smrg struct stored_event **head, *e, *tmp; 621b4ee4795Smrg 622b4ee4795Smrg if (!dpy->cookiejar) 623b4ee4795Smrg return; 624b4ee4795Smrg 625b4ee4795Smrg head = (struct stored_event**)&dpy->cookiejar; 626b4ee4795Smrg 627b4ee4795Smrg DL_FOREACH_SAFE(*head, e, tmp) { 628b4ee4795Smrg if (dpy->cookiejar == e) 629b4ee4795Smrg dpy->cookiejar = NULL; 630c17aa6b1Smrg XFree(e->ev.data); 631c17aa6b1Smrg XFree(e); 632b4ee4795Smrg } 633b4ee4795Smrg} 634b4ee4795Smrg 635b4ee4795Smrg/** 636b4ee4795Smrg * Add an event to the display's event list. This event must be freed on the 637b4ee4795Smrg * next call to XNextEvent(). 638b4ee4795Smrg */ 639b4ee4795Smrgvoid 640b4ee4795Smrg_XStoreEventCookie(Display *dpy, XEvent *event) 641b4ee4795Smrg{ 642b4ee4795Smrg XGenericEventCookie* cookie = &event->xcookie; 643b4ee4795Smrg struct stored_event **head, *add; 644b4ee4795Smrg 645b4ee4795Smrg if (!_XIsEventCookie(dpy, event)) 646b4ee4795Smrg return; 647b4ee4795Smrg 648b4ee4795Smrg head = (struct stored_event**)(&dpy->cookiejar); 649b4ee4795Smrg 650b4ee4795Smrg add = Xmalloc(sizeof(struct stored_event)); 651b4ee4795Smrg if (!add) { 652b4ee4795Smrg ESET(ENOMEM); 653b4ee4795Smrg _XIOError(dpy); 654b4ee4795Smrg } 655b4ee4795Smrg add->ev = *cookie; 656b4ee4795Smrg DL_APPEND(*head, add); 657b4ee4795Smrg cookie->data = NULL; /* don't return data yet, must be claimed */ 658b4ee4795Smrg} 659b4ee4795Smrg 660b4ee4795Smrg/** 661b4ee4795Smrg * Return the event with the given cookie and remove it from the list. 662b4ee4795Smrg */ 663b4ee4795SmrgBool 664b4ee4795Smrg_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev) 665b4ee4795Smrg{ 666b4ee4795Smrg Bool ret = False; 667b4ee4795Smrg struct stored_event **head, *event; 668b4ee4795Smrg head = (struct stored_event**)&dpy->cookiejar; 669b4ee4795Smrg 670b4ee4795Smrg if (!_XIsEventCookie(dpy, (XEvent*)ev)) 671b4ee4795Smrg return ret; 672b4ee4795Smrg 673b4ee4795Smrg DL_FOREACH(*head, event) { 674b4ee4795Smrg if (event->ev.cookie == ev->cookie && 675b4ee4795Smrg event->ev.extension == ev->extension && 676b4ee4795Smrg event->ev.evtype == ev->evtype) { 677b4ee4795Smrg *ev = event->ev; 678b4ee4795Smrg DL_DELETE(*head, event); 679b4ee4795Smrg Xfree(event); 680b4ee4795Smrg ret = True; 681b4ee4795Smrg break; 682b4ee4795Smrg } 683b4ee4795Smrg } 684b4ee4795Smrg 685b4ee4795Smrg return ret; 686b4ee4795Smrg} 687b4ee4795Smrg 688b4ee4795SmrgBool 689b4ee4795Smrg_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out) 690b4ee4795Smrg{ 691b4ee4795Smrg Bool ret = False; 692b4ee4795Smrg int extension; 693b4ee4795Smrg 694b4ee4795Smrg if (!_XIsEventCookie(dpy, (XEvent*)in) || !out) 695b4ee4795Smrg return ret; 696b4ee4795Smrg 697b4ee4795Smrg extension = in->extension & 0x7F; 698b4ee4795Smrg 699b4ee4795Smrg if (!dpy->generic_event_copy_vec[extension]) 700b4ee4795Smrg return ret; 701b4ee4795Smrg 702b4ee4795Smrg ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out)); 703b4ee4795Smrg out->cookie = ret ? ++dpy->next_cookie : 0; 704b4ee4795Smrg return ret; 705b4ee4795Smrg} 706b4ee4795Smrg 7071ab64890Smrg 7081ab64890Smrg/* 7091ab64890Smrg * _XEnq - Place event packets on the display's queue. 7101ab64890Smrg * note that no squishing of move events in V11, since there 7111ab64890Smrg * is pointer motion hints.... 7121ab64890Smrg */ 7131ab64890Smrgvoid _XEnq( 7141ab64890Smrg register Display *dpy, 7151ab64890Smrg register xEvent *event) 7161ab64890Smrg{ 7171ab64890Smrg register _XQEvent *qelt; 718b4ee4795Smrg int type, extension; 7191ab64890Smrg 7201ab64890Smrg if ((qelt = dpy->qfree)) { 7211ab64890Smrg /* If dpy->qfree is non-NULL do this, else malloc a new one. */ 7221ab64890Smrg dpy->qfree = qelt->next; 7231ab64890Smrg } 724556b6652Smrg else if ((qelt = Xmalloc(sizeof(_XQEvent))) == NULL) { 7251ab64890Smrg /* Malloc call failed! */ 7261ab64890Smrg ESET(ENOMEM); 7271ab64890Smrg _XIOError(dpy); 7281ab64890Smrg } 7291ab64890Smrg qelt->next = NULL; 730b4ee4795Smrg 731b4ee4795Smrg type = event->u.u.type & 0177; 732b4ee4795Smrg extension = ((xGenericEvent*)event)->extension; 733295fb823Smrg 734295fb823Smrg qelt->event.type = type; 735556b6652Smrg /* If an extension has registered a generic_event_vec handler, then 736b4ee4795Smrg * it can handle event cookies. Otherwise, proceed with the normal 737b4ee4795Smrg * event handlers. 738b4ee4795Smrg * 739b4ee4795Smrg * If the generic_event_vec is called, qelt->event is a event cookie 740b4ee4795Smrg * with the data pointer and the "free" pointer set. Data pointer is 741b4ee4795Smrg * some memory allocated by the extension. 742b4ee4795Smrg */ 743b4ee4795Smrg if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) { 744b4ee4795Smrg XGenericEventCookie *cookie = &qelt->event.xcookie; 745b4ee4795Smrg (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event); 746b4ee4795Smrg cookie->cookie = ++dpy->next_cookie; 747b4ee4795Smrg 748b4ee4795Smrg qelt->qserial_num = dpy->next_event_serial_num++; 749b4ee4795Smrg if (dpy->tail) dpy->tail->next = qelt; 750b4ee4795Smrg else dpy->head = qelt; 751b4ee4795Smrg 752b4ee4795Smrg dpy->tail = qelt; 753b4ee4795Smrg dpy->qlen++; 754b4ee4795Smrg } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) { 7551ab64890Smrg qelt->qserial_num = dpy->next_event_serial_num++; 7561ab64890Smrg if (dpy->tail) dpy->tail->next = qelt; 7571ab64890Smrg else dpy->head = qelt; 75861b2299dSmrg 7591ab64890Smrg dpy->tail = qelt; 7601ab64890Smrg dpy->qlen++; 7611ab64890Smrg } else { 7621ab64890Smrg /* ignored, or stashed away for many-to-one compression */ 7631ab64890Smrg qelt->next = dpy->qfree; 7641ab64890Smrg dpy->qfree = qelt; 7651ab64890Smrg } 7661ab64890Smrg} 7671ab64890Smrg 7681ab64890Smrg/* 7691ab64890Smrg * _XDeq - Remove event packet from the display's queue. 7701ab64890Smrg */ 7711ab64890Smrgvoid _XDeq( 7721ab64890Smrg register Display *dpy, 7731ab64890Smrg register _XQEvent *prev, /* element before qelt */ 7741ab64890Smrg register _XQEvent *qelt) /* element to be unlinked */ 7751ab64890Smrg{ 7761ab64890Smrg if (prev) { 7771ab64890Smrg if ((prev->next = qelt->next) == NULL) 7781ab64890Smrg dpy->tail = prev; 7791ab64890Smrg } else { 7801ab64890Smrg /* no prev, so removing first elt */ 7811ab64890Smrg if ((dpy->head = qelt->next) == NULL) 7821ab64890Smrg dpy->tail = NULL; 7831ab64890Smrg } 7841ab64890Smrg qelt->qserial_num = 0; 7851ab64890Smrg qelt->next = dpy->qfree; 7861ab64890Smrg dpy->qfree = qelt; 7871ab64890Smrg dpy->qlen--; 788b4ee4795Smrg 789b4ee4795Smrg if (_XIsEventCookie(dpy, &qelt->event)) { 790b4ee4795Smrg XGenericEventCookie* cookie = &qelt->event.xcookie; 791b4ee4795Smrg /* dpy->qfree is re-used, reset memory to avoid double free on 792b4ee4795Smrg * _XFreeDisplayStructure */ 793b4ee4795Smrg cookie->data = NULL; 794b4ee4795Smrg } 7951ab64890Smrg} 7961ab64890Smrg 7971ab64890Smrg/* 7981ab64890Smrg * EventToWire in separate file in that often not needed. 7991ab64890Smrg */ 8001ab64890Smrg 8011ab64890Smrg/*ARGSUSED*/ 8021ab64890SmrgBool 8031ab64890Smrg_XUnknownWireEvent( 8041ab64890Smrg register Display *dpy, /* pointer to display structure */ 8051ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 8061ab64890Smrg register xEvent *event) /* wire protocol event */ 8071ab64890Smrg{ 8081ab64890Smrg#ifdef notdef 80961b2299dSmrg (void) fprintf(stderr, 8101ab64890Smrg "Xlib: unhandled wire event! event number = %d, display = %x\n.", 8111ab64890Smrg event->u.u.type, dpy); 8121ab64890Smrg#endif 8131ab64890Smrg return(False); 8141ab64890Smrg} 8151ab64890Smrg 816b4ee4795SmrgBool 817b4ee4795Smrg_XUnknownWireEventCookie( 818b4ee4795Smrg Display *dpy, /* pointer to display structure */ 819b4ee4795Smrg XGenericEventCookie *re, /* pointer to where event should be reformatted */ 820b4ee4795Smrg xEvent *event) /* wire protocol event */ 821b4ee4795Smrg{ 822b4ee4795Smrg#ifdef notdef 823b4ee4795Smrg fprintf(stderr, 824b4ee4795Smrg "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.", 825b4ee4795Smrg ((xGenericEvent*)event)->extension, dpy); 826b4ee4795Smrg#endif 827b4ee4795Smrg return(False); 828b4ee4795Smrg} 829b4ee4795Smrg 830b4ee4795SmrgBool 831b4ee4795Smrg_XUnknownCopyEventCookie( 832b4ee4795Smrg Display *dpy, /* pointer to display structure */ 833b4ee4795Smrg XGenericEventCookie *in, /* source */ 834b4ee4795Smrg XGenericEventCookie *out) /* destination */ 835b4ee4795Smrg{ 836b4ee4795Smrg#ifdef notdef 837b4ee4795Smrg fprintf(stderr, 838b4ee4795Smrg "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.", 839b4ee4795Smrg in->extension, dpy); 840b4ee4795Smrg#endif 841b4ee4795Smrg return(False); 842b4ee4795Smrg} 843b4ee4795Smrg 8441ab64890Smrg/*ARGSUSED*/ 8451ab64890SmrgStatus 8461ab64890Smrg_XUnknownNativeEvent( 8471ab64890Smrg register Display *dpy, /* pointer to display structure */ 8481ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 8491ab64890Smrg register xEvent *event) /* wire protocol event */ 8501ab64890Smrg{ 8511ab64890Smrg#ifdef notdef 85261b2299dSmrg (void) fprintf(stderr, 8531ab64890Smrg "Xlib: unhandled native event! event number = %d, display = %x\n.", 8541ab64890Smrg re->type, dpy); 8551ab64890Smrg#endif 8561ab64890Smrg return(0); 8571ab64890Smrg} 8581ab64890Smrg/* 8591ab64890Smrg * reformat a wire event into an XEvent structure of the right type. 8601ab64890Smrg */ 8611ab64890SmrgBool 8621ab64890Smrg_XWireToEvent( 8631ab64890Smrg register Display *dpy, /* pointer to display structure */ 8641ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 8651ab64890Smrg register xEvent *event) /* wire protocol event */ 8661ab64890Smrg{ 8671ab64890Smrg 8681ab64890Smrg re->type = event->u.u.type & 0x7f; 8691ab64890Smrg ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy, 8701ab64890Smrg (xGenericReply *)event); 8711ab64890Smrg ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0); 8721ab64890Smrg ((XAnyEvent *)re)->display = dpy; 87361b2299dSmrg 8741ab64890Smrg /* Ignore the leading bit of the event type since it is set when a 8751ab64890Smrg client sends an event rather than the server. */ 8761ab64890Smrg 8771ab64890Smrg switch (event-> u.u.type & 0177) { 8781ab64890Smrg case KeyPress: 8791ab64890Smrg case KeyRelease: 8801ab64890Smrg { 8811ab64890Smrg register XKeyEvent *ev = (XKeyEvent*) re; 8821ab64890Smrg ev->root = event->u.keyButtonPointer.root; 8831ab64890Smrg ev->window = event->u.keyButtonPointer.event; 8841ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 8851ab64890Smrg ev->time = event->u.keyButtonPointer.time; 8861ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 8871ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 8881ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 8891ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 8901ab64890Smrg ev->state = event->u.keyButtonPointer.state; 8911ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 8921ab64890Smrg ev->keycode = event->u.u.detail; 8931ab64890Smrg } 8941ab64890Smrg break; 8951ab64890Smrg case ButtonPress: 8961ab64890Smrg case ButtonRelease: 8971ab64890Smrg { 8981ab64890Smrg register XButtonEvent *ev = (XButtonEvent *) re; 8991ab64890Smrg ev->root = event->u.keyButtonPointer.root; 9001ab64890Smrg ev->window = event->u.keyButtonPointer.event; 9011ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 9021ab64890Smrg ev->time = event->u.keyButtonPointer.time; 9031ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 9041ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 9051ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 9061ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 9071ab64890Smrg ev->state = event->u.keyButtonPointer.state; 9081ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 9091ab64890Smrg ev->button = event->u.u.detail; 9101ab64890Smrg } 9111ab64890Smrg break; 9121ab64890Smrg case MotionNotify: 9131ab64890Smrg { 9141ab64890Smrg register XMotionEvent *ev = (XMotionEvent *)re; 9151ab64890Smrg ev->root = event->u.keyButtonPointer.root; 9161ab64890Smrg ev->window = event->u.keyButtonPointer.event; 9171ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 9181ab64890Smrg ev->time = event->u.keyButtonPointer.time; 9191ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 9201ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 9211ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 9221ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 9231ab64890Smrg ev->state = event->u.keyButtonPointer.state; 9241ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 9251ab64890Smrg ev->is_hint = event->u.u.detail; 9261ab64890Smrg } 9271ab64890Smrg break; 9281ab64890Smrg case EnterNotify: 9291ab64890Smrg case LeaveNotify: 9301ab64890Smrg { 9311ab64890Smrg register XCrossingEvent *ev = (XCrossingEvent *) re; 9321ab64890Smrg ev->root = event->u.enterLeave.root; 9331ab64890Smrg ev->window = event->u.enterLeave.event; 9341ab64890Smrg ev->subwindow = event->u.enterLeave.child; 9351ab64890Smrg ev->time = event->u.enterLeave.time; 9361ab64890Smrg ev->x = cvtINT16toInt(event->u.enterLeave.eventX); 9371ab64890Smrg ev->y = cvtINT16toInt(event->u.enterLeave.eventY); 9381ab64890Smrg ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX); 9391ab64890Smrg ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY); 9401ab64890Smrg ev->state = event->u.enterLeave.state; 9411ab64890Smrg ev->mode = event->u.enterLeave.mode; 94261b2299dSmrg ev->same_screen = (event->u.enterLeave.flags & 9431ab64890Smrg ELFlagSameScreen) && True; 9441ab64890Smrg ev->focus = (event->u.enterLeave.flags & 9451ab64890Smrg ELFlagFocus) && True; 9461ab64890Smrg ev->detail = event->u.u.detail; 9471ab64890Smrg } 9481ab64890Smrg break; 9491ab64890Smrg case FocusIn: 9501ab64890Smrg case FocusOut: 9511ab64890Smrg { 9521ab64890Smrg register XFocusChangeEvent *ev = (XFocusChangeEvent *) re; 9531ab64890Smrg ev->window = event->u.focus.window; 9541ab64890Smrg ev->mode = event->u.focus.mode; 9551ab64890Smrg ev->detail = event->u.u.detail; 9561ab64890Smrg } 9571ab64890Smrg break; 9581ab64890Smrg case KeymapNotify: 9591ab64890Smrg { 9601ab64890Smrg register XKeymapEvent *ev = (XKeymapEvent *) re; 9611ab64890Smrg ev->window = None; 9621ab64890Smrg memcpy(&ev->key_vector[1], 9631ab64890Smrg (char *)((xKeymapEvent *) event)->map, 9641ab64890Smrg sizeof (((xKeymapEvent *) event)->map)); 9651ab64890Smrg } 9661ab64890Smrg break; 9671ab64890Smrg case Expose: 9681ab64890Smrg { 9691ab64890Smrg register XExposeEvent *ev = (XExposeEvent *) re; 9701ab64890Smrg ev->window = event->u.expose.window; 9711ab64890Smrg ev->x = event->u.expose.x; 9721ab64890Smrg ev->y = event->u.expose.y; 9731ab64890Smrg ev->width = event->u.expose.width; 9741ab64890Smrg ev->height = event->u.expose.height; 9751ab64890Smrg ev->count = event->u.expose.count; 9761ab64890Smrg } 9771ab64890Smrg break; 9781ab64890Smrg case GraphicsExpose: 9791ab64890Smrg { 9801ab64890Smrg register XGraphicsExposeEvent *ev = 9811ab64890Smrg (XGraphicsExposeEvent *) re; 9821ab64890Smrg ev->drawable = event->u.graphicsExposure.drawable; 9831ab64890Smrg ev->x = event->u.graphicsExposure.x; 9841ab64890Smrg ev->y = event->u.graphicsExposure.y; 9851ab64890Smrg ev->width = event->u.graphicsExposure.width; 9861ab64890Smrg ev->height = event->u.graphicsExposure.height; 9871ab64890Smrg ev->count = event->u.graphicsExposure.count; 9881ab64890Smrg ev->major_code = event->u.graphicsExposure.majorEvent; 9891ab64890Smrg ev->minor_code = event->u.graphicsExposure.minorEvent; 9901ab64890Smrg } 9911ab64890Smrg break; 9921ab64890Smrg case NoExpose: 9931ab64890Smrg { 9941ab64890Smrg register XNoExposeEvent *ev = (XNoExposeEvent *) re; 9951ab64890Smrg ev->drawable = event->u.noExposure.drawable; 9961ab64890Smrg ev->major_code = event->u.noExposure.majorEvent; 9971ab64890Smrg ev->minor_code = event->u.noExposure.minorEvent; 9981ab64890Smrg } 9991ab64890Smrg break; 10001ab64890Smrg case VisibilityNotify: 10011ab64890Smrg { 10021ab64890Smrg register XVisibilityEvent *ev = (XVisibilityEvent *) re; 10031ab64890Smrg ev->window = event->u.visibility.window; 10041ab64890Smrg ev->state = event->u.visibility.state; 10051ab64890Smrg } 10061ab64890Smrg break; 10071ab64890Smrg case CreateNotify: 10081ab64890Smrg { 10091ab64890Smrg register XCreateWindowEvent *ev = 10101ab64890Smrg (XCreateWindowEvent *) re; 10111ab64890Smrg ev->window = event->u.createNotify.window; 10121ab64890Smrg ev->parent = event->u.createNotify.parent; 10131ab64890Smrg ev->x = cvtINT16toInt(event->u.createNotify.x); 10141ab64890Smrg ev->y = cvtINT16toInt(event->u.createNotify.y); 10151ab64890Smrg ev->width = event->u.createNotify.width; 10161ab64890Smrg ev->height = event->u.createNotify.height; 10171ab64890Smrg ev->border_width = event->u.createNotify.borderWidth; 10181ab64890Smrg ev->override_redirect = event->u.createNotify.override; 10191ab64890Smrg } 10201ab64890Smrg break; 10211ab64890Smrg case DestroyNotify: 10221ab64890Smrg { 10231ab64890Smrg register XDestroyWindowEvent *ev = 10241ab64890Smrg (XDestroyWindowEvent *) re; 10251ab64890Smrg ev->window = event->u.destroyNotify.window; 10261ab64890Smrg ev->event = event->u.destroyNotify.event; 10271ab64890Smrg } 10281ab64890Smrg break; 10291ab64890Smrg case UnmapNotify: 10301ab64890Smrg { 10311ab64890Smrg register XUnmapEvent *ev = (XUnmapEvent *) re; 10321ab64890Smrg ev->window = event->u.unmapNotify.window; 10331ab64890Smrg ev->event = event->u.unmapNotify.event; 10341ab64890Smrg ev->from_configure = event->u.unmapNotify.fromConfigure; 10351ab64890Smrg } 10361ab64890Smrg break; 10371ab64890Smrg case MapNotify: 10381ab64890Smrg { 10391ab64890Smrg register XMapEvent *ev = (XMapEvent *) re; 10401ab64890Smrg ev->window = event->u.mapNotify.window; 10411ab64890Smrg ev->event = event->u.mapNotify.event; 10421ab64890Smrg ev->override_redirect = event->u.mapNotify.override; 10431ab64890Smrg } 10441ab64890Smrg break; 10451ab64890Smrg case MapRequest: 10461ab64890Smrg { 10471ab64890Smrg register XMapRequestEvent *ev = (XMapRequestEvent *) re; 10481ab64890Smrg ev->window = event->u.mapRequest.window; 10491ab64890Smrg ev->parent = event->u.mapRequest.parent; 10501ab64890Smrg } 10511ab64890Smrg break; 10521ab64890Smrg case ReparentNotify: 10531ab64890Smrg { 10541ab64890Smrg register XReparentEvent *ev = (XReparentEvent *) re; 10551ab64890Smrg ev->event = event->u.reparent.event; 10561ab64890Smrg ev->window = event->u.reparent.window; 10571ab64890Smrg ev->parent = event->u.reparent.parent; 10581ab64890Smrg ev->x = cvtINT16toInt(event->u.reparent.x); 10591ab64890Smrg ev->y = cvtINT16toInt(event->u.reparent.y); 10601ab64890Smrg ev->override_redirect = event->u.reparent.override; 10611ab64890Smrg } 10621ab64890Smrg break; 10631ab64890Smrg case ConfigureNotify: 10641ab64890Smrg { 10651ab64890Smrg register XConfigureEvent *ev = (XConfigureEvent *) re; 10661ab64890Smrg ev->event = event->u.configureNotify.event; 10671ab64890Smrg ev->window = event->u.configureNotify.window; 10681ab64890Smrg ev->above = event->u.configureNotify.aboveSibling; 10691ab64890Smrg ev->x = cvtINT16toInt(event->u.configureNotify.x); 10701ab64890Smrg ev->y = cvtINT16toInt(event->u.configureNotify.y); 10711ab64890Smrg ev->width = event->u.configureNotify.width; 10721ab64890Smrg ev->height = event->u.configureNotify.height; 10731ab64890Smrg ev->border_width = event->u.configureNotify.borderWidth; 10741ab64890Smrg ev->override_redirect = event->u.configureNotify.override; 10751ab64890Smrg } 10761ab64890Smrg break; 10771ab64890Smrg case ConfigureRequest: 10781ab64890Smrg { 10791ab64890Smrg register XConfigureRequestEvent *ev = 10801ab64890Smrg (XConfigureRequestEvent *) re; 10811ab64890Smrg ev->window = event->u.configureRequest.window; 10821ab64890Smrg ev->parent = event->u.configureRequest.parent; 10831ab64890Smrg ev->above = event->u.configureRequest.sibling; 10841ab64890Smrg ev->x = cvtINT16toInt(event->u.configureRequest.x); 10851ab64890Smrg ev->y = cvtINT16toInt(event->u.configureRequest.y); 10861ab64890Smrg ev->width = event->u.configureRequest.width; 10871ab64890Smrg ev->height = event->u.configureRequest.height; 10881ab64890Smrg ev->border_width = event->u.configureRequest.borderWidth; 10891ab64890Smrg ev->value_mask = event->u.configureRequest.valueMask; 10901ab64890Smrg ev->detail = event->u.u.detail; 10911ab64890Smrg } 10921ab64890Smrg break; 10931ab64890Smrg case GravityNotify: 10941ab64890Smrg { 10951ab64890Smrg register XGravityEvent *ev = (XGravityEvent *) re; 10961ab64890Smrg ev->window = event->u.gravity.window; 10971ab64890Smrg ev->event = event->u.gravity.event; 10981ab64890Smrg ev->x = cvtINT16toInt(event->u.gravity.x); 10991ab64890Smrg ev->y = cvtINT16toInt(event->u.gravity.y); 11001ab64890Smrg } 11011ab64890Smrg break; 11021ab64890Smrg case ResizeRequest: 11031ab64890Smrg { 11041ab64890Smrg register XResizeRequestEvent *ev = 11051ab64890Smrg (XResizeRequestEvent *) re; 11061ab64890Smrg ev->window = event->u.resizeRequest.window; 11071ab64890Smrg ev->width = event->u.resizeRequest.width; 11081ab64890Smrg ev->height = event->u.resizeRequest.height; 11091ab64890Smrg } 11101ab64890Smrg break; 11111ab64890Smrg case CirculateNotify: 11121ab64890Smrg { 11131ab64890Smrg register XCirculateEvent *ev = (XCirculateEvent *) re; 11141ab64890Smrg ev->window = event->u.circulate.window; 11151ab64890Smrg ev->event = event->u.circulate.event; 11161ab64890Smrg ev->place = event->u.circulate.place; 11171ab64890Smrg } 11181ab64890Smrg break; 11191ab64890Smrg case CirculateRequest: 11201ab64890Smrg { 11211ab64890Smrg register XCirculateRequestEvent *ev = 11221ab64890Smrg (XCirculateRequestEvent *) re; 11231ab64890Smrg ev->window = event->u.circulate.window; 11241ab64890Smrg ev->parent = event->u.circulate.event; 11251ab64890Smrg ev->place = event->u.circulate.place; 11261ab64890Smrg } 11271ab64890Smrg break; 11281ab64890Smrg case PropertyNotify: 11291ab64890Smrg { 11301ab64890Smrg register XPropertyEvent *ev = (XPropertyEvent *) re; 11311ab64890Smrg ev->window = event->u.property.window; 11321ab64890Smrg ev->atom = event->u.property.atom; 11331ab64890Smrg ev->time = event->u.property.time; 11341ab64890Smrg ev->state = event->u.property.state; 11351ab64890Smrg } 11361ab64890Smrg break; 11371ab64890Smrg case SelectionClear: 11381ab64890Smrg { 11391ab64890Smrg register XSelectionClearEvent *ev = 11401ab64890Smrg (XSelectionClearEvent *) re; 11411ab64890Smrg ev->window = event->u.selectionClear.window; 11421ab64890Smrg ev->selection = event->u.selectionClear.atom; 11431ab64890Smrg ev->time = event->u.selectionClear.time; 11441ab64890Smrg } 11451ab64890Smrg break; 11461ab64890Smrg case SelectionRequest: 11471ab64890Smrg { 11481ab64890Smrg register XSelectionRequestEvent *ev = 11491ab64890Smrg (XSelectionRequestEvent *) re; 11501ab64890Smrg ev->owner = event->u.selectionRequest.owner; 11511ab64890Smrg ev->requestor = event->u.selectionRequest.requestor; 11521ab64890Smrg ev->selection = event->u.selectionRequest.selection; 11531ab64890Smrg ev->target = event->u.selectionRequest.target; 11541ab64890Smrg ev->property = event->u.selectionRequest.property; 11551ab64890Smrg ev->time = event->u.selectionRequest.time; 11561ab64890Smrg } 11571ab64890Smrg break; 11581ab64890Smrg case SelectionNotify: 11591ab64890Smrg { 11601ab64890Smrg register XSelectionEvent *ev = (XSelectionEvent *) re; 11611ab64890Smrg ev->requestor = event->u.selectionNotify.requestor; 11621ab64890Smrg ev->selection = event->u.selectionNotify.selection; 11631ab64890Smrg ev->target = event->u.selectionNotify.target; 11641ab64890Smrg ev->property = event->u.selectionNotify.property; 11651ab64890Smrg ev->time = event->u.selectionNotify.time; 11661ab64890Smrg } 11671ab64890Smrg break; 11681ab64890Smrg case ColormapNotify: 11691ab64890Smrg { 11701ab64890Smrg register XColormapEvent *ev = (XColormapEvent *) re; 11711ab64890Smrg ev->window = event->u.colormap.window; 11721ab64890Smrg ev->colormap = event->u.colormap.colormap; 11731ab64890Smrg ev->new = event->u.colormap.new; 11741ab64890Smrg ev->state = event->u.colormap.state; 11751ab64890Smrg } 11761ab64890Smrg break; 11771ab64890Smrg case ClientMessage: 11781ab64890Smrg { 11791ab64890Smrg register int i; 118061b2299dSmrg register XClientMessageEvent *ev 11811ab64890Smrg = (XClientMessageEvent *) re; 11821ab64890Smrg ev->window = event->u.clientMessage.window; 11831ab64890Smrg ev->format = event->u.u.detail; 11841ab64890Smrg switch (ev->format) { 118561b2299dSmrg case 8: 11861ab64890Smrg ev->message_type = event->u.clientMessage.u.b.type; 118761b2299dSmrg for (i = 0; i < 20; i++) 11881ab64890Smrg ev->data.b[i] = event->u.clientMessage.u.b.bytes[i]; 11891ab64890Smrg break; 11901ab64890Smrg case 16: 11911ab64890Smrg ev->message_type = event->u.clientMessage.u.s.type; 11921ab64890Smrg ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0); 11931ab64890Smrg ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1); 11941ab64890Smrg ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2); 11951ab64890Smrg ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3); 11961ab64890Smrg ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4); 11971ab64890Smrg ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5); 11981ab64890Smrg ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6); 11991ab64890Smrg ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7); 12001ab64890Smrg ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8); 12011ab64890Smrg ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9); 12021ab64890Smrg break; 12031ab64890Smrg case 32: 12041ab64890Smrg ev->message_type = event->u.clientMessage.u.l.type; 12051ab64890Smrg ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0); 12061ab64890Smrg ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1); 12071ab64890Smrg ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2); 12081ab64890Smrg ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3); 12091ab64890Smrg ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4); 12101ab64890Smrg break; 12111ab64890Smrg default: /* XXX should never occur */ 12121ab64890Smrg break; 12131ab64890Smrg } 12141ab64890Smrg } 12151ab64890Smrg break; 12161ab64890Smrg case MappingNotify: 12171ab64890Smrg { 12181ab64890Smrg register XMappingEvent *ev = (XMappingEvent *)re; 12191ab64890Smrg ev->window = 0; 12201ab64890Smrg ev->first_keycode = event->u.mappingNotify.firstKeyCode; 12211ab64890Smrg ev->request = event->u.mappingNotify.request; 12221ab64890Smrg ev->count = event->u.mappingNotify.count; 12231ab64890Smrg } 12241ab64890Smrg break; 12251ab64890Smrg default: 12261ab64890Smrg return(_XUnknownWireEvent(dpy, re, event)); 12271ab64890Smrg } 12281ab64890Smrg return(True); 12291ab64890Smrg} 12301ab64890Smrg 12311ab64890Smrg 12321ab64890Smrg/* 123361b2299dSmrg * _XDefaultIOError - Default fatal system error reporting routine. Called 12341ab64890Smrg * when an X internal system error is encountered. 12351ab64890Smrg */ 12361ab64890Smrgint _XDefaultIOError( 12371ab64890Smrg Display *dpy) 12381ab64890Smrg{ 12391ab64890Smrg if (ECHECK(EPIPE)) { 12401ab64890Smrg (void) fprintf (stderr, 12411ab64890Smrg "X connection to %s broken (explicit kill or server shutdown).\r\n", 12421ab64890Smrg DisplayString (dpy)); 12431ab64890Smrg } else { 124461b2299dSmrg (void) fprintf (stderr, 12451ab64890Smrg "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n", 12461ab64890Smrg#ifdef WIN32 12471ab64890Smrg WSAGetLastError(), strerror(WSAGetLastError()), 12481ab64890Smrg#else 12491ab64890Smrg errno, strerror (errno), 12501ab64890Smrg#endif 12511ab64890Smrg DisplayString (dpy)); 125261b2299dSmrg (void) fprintf (stderr, 12531ab64890Smrg " after %lu requests (%lu known processed) with %d events remaining.\r\n", 12541ab64890Smrg NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy), 12551ab64890Smrg QLength(dpy)); 12561ab64890Smrg 12571ab64890Smrg } 12581ab64890Smrg exit(1); 12591ab64890Smrg return(0); /* dummy - function should never return */ 12601ab64890Smrg} 12611ab64890Smrg 12621ab64890Smrg 12631ab64890Smrgstatic int _XPrintDefaultError( 12641ab64890Smrg Display *dpy, 12651ab64890Smrg XErrorEvent *event, 12661ab64890Smrg FILE *fp) 12671ab64890Smrg{ 12681ab64890Smrg char buffer[BUFSIZ]; 12691ab64890Smrg char mesg[BUFSIZ]; 12701ab64890Smrg char number[32]; 12711ab64890Smrg const char *mtype = "XlibMessage"; 12721ab64890Smrg register _XExtension *ext = (_XExtension *)NULL; 12731ab64890Smrg _XExtension *bext = (_XExtension *)NULL; 12741ab64890Smrg XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); 12751ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); 12761ab64890Smrg (void) fprintf(fp, "%s: %s\n ", mesg, buffer); 127761b2299dSmrg XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", 12781ab64890Smrg mesg, BUFSIZ); 12791ab64890Smrg (void) fprintf(fp, mesg, event->request_code); 12801ab64890Smrg if (event->request_code < 128) { 1281556b6652Smrg snprintf(number, sizeof(number), "%d", event->request_code); 12821ab64890Smrg XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); 12831ab64890Smrg } else { 12841ab64890Smrg for (ext = dpy->ext_procs; 12851ab64890Smrg ext && (ext->codes.major_opcode != event->request_code); 12861ab64890Smrg ext = ext->next) 12871ab64890Smrg ; 1288c17aa6b1Smrg if (ext) { 1289c17aa6b1Smrg strncpy(buffer, ext->name, BUFSIZ); 1290c17aa6b1Smrg buffer[BUFSIZ - 1] = '\0'; 1291c17aa6b1Smrg } else 12921ab64890Smrg buffer[0] = '\0'; 12931ab64890Smrg } 12941ab64890Smrg (void) fprintf(fp, " (%s)\n", buffer); 12951ab64890Smrg if (event->request_code >= 128) { 12961ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", 12971ab64890Smrg mesg, BUFSIZ); 12981ab64890Smrg fputs(" ", fp); 12991ab64890Smrg (void) fprintf(fp, mesg, event->minor_code); 13001ab64890Smrg if (ext) { 1301556b6652Smrg snprintf(mesg, sizeof(mesg), "%s.%d", ext->name, event->minor_code); 13021ab64890Smrg XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); 13031ab64890Smrg (void) fprintf(fp, " (%s)", buffer); 13041ab64890Smrg } 13051ab64890Smrg fputs("\n", fp); 13061ab64890Smrg } 13071ab64890Smrg if (event->error_code >= 128) { 13081ab64890Smrg /* kludge, try to find the extension that caused it */ 13091ab64890Smrg buffer[0] = '\0'; 13101ab64890Smrg for (ext = dpy->ext_procs; ext; ext = ext->next) { 131161b2299dSmrg if (ext->error_string) 13121ab64890Smrg (*ext->error_string)(dpy, event->error_code, &ext->codes, 13131ab64890Smrg buffer, BUFSIZ); 13141ab64890Smrg if (buffer[0]) { 13151ab64890Smrg bext = ext; 13161ab64890Smrg break; 13171ab64890Smrg } 13181ab64890Smrg if (ext->codes.first_error && 13191ab64890Smrg ext->codes.first_error < (int)event->error_code && 13201ab64890Smrg (!bext || ext->codes.first_error > bext->codes.first_error)) 13211ab64890Smrg bext = ext; 132261b2299dSmrg } 13231ab64890Smrg if (bext) 1324556b6652Smrg snprintf(buffer, sizeof(buffer), "%s.%d", bext->name, 1325556b6652Smrg event->error_code - bext->codes.first_error); 13261ab64890Smrg else 13271ab64890Smrg strcpy(buffer, "Value"); 13281ab64890Smrg XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); 13291ab64890Smrg if (mesg[0]) { 13301ab64890Smrg fputs(" ", fp); 13311ab64890Smrg (void) fprintf(fp, mesg, event->resourceid); 13321ab64890Smrg fputs("\n", fp); 13331ab64890Smrg } 13341ab64890Smrg /* let extensions try to print the values */ 13351ab64890Smrg for (ext = dpy->ext_procs; ext; ext = ext->next) { 13361ab64890Smrg if (ext->error_values) 13371ab64890Smrg (*ext->error_values)(dpy, event, fp); 13381ab64890Smrg } 13391ab64890Smrg } else if ((event->error_code == BadWindow) || 13401ab64890Smrg (event->error_code == BadPixmap) || 13411ab64890Smrg (event->error_code == BadCursor) || 13421ab64890Smrg (event->error_code == BadFont) || 13431ab64890Smrg (event->error_code == BadDrawable) || 13441ab64890Smrg (event->error_code == BadColor) || 13451ab64890Smrg (event->error_code == BadGC) || 13461ab64890Smrg (event->error_code == BadIDChoice) || 13471ab64890Smrg (event->error_code == BadValue) || 13481ab64890Smrg (event->error_code == BadAtom)) { 13491ab64890Smrg if (event->error_code == BadValue) 13501ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", 13511ab64890Smrg mesg, BUFSIZ); 13521ab64890Smrg else if (event->error_code == BadAtom) 13531ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", 13541ab64890Smrg mesg, BUFSIZ); 13551ab64890Smrg else 13561ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", 13571ab64890Smrg mesg, BUFSIZ); 13581ab64890Smrg fputs(" ", fp); 13591ab64890Smrg (void) fprintf(fp, mesg, event->resourceid); 13601ab64890Smrg fputs("\n", fp); 13611ab64890Smrg } 136261b2299dSmrg XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", 13631ab64890Smrg mesg, BUFSIZ); 13641ab64890Smrg fputs(" ", fp); 13651ab64890Smrg (void) fprintf(fp, mesg, event->serial); 13661ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", 13671ab64890Smrg mesg, BUFSIZ); 13681ab64890Smrg fputs("\n ", fp); 13691ab64890Smrg (void) fprintf(fp, mesg, dpy->request); 13701ab64890Smrg fputs("\n", fp); 13711ab64890Smrg if (event->error_code == BadImplementation) return 0; 13721ab64890Smrg return 1; 13731ab64890Smrg} 13741ab64890Smrg 13751ab64890Smrgint _XDefaultError( 13761ab64890Smrg Display *dpy, 13771ab64890Smrg XErrorEvent *event) 13781ab64890Smrg{ 13791ab64890Smrg if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0; 13801ab64890Smrg exit(1); 13811ab64890Smrg /*NOTREACHED*/ 13821ab64890Smrg} 13831ab64890Smrg 13841ab64890Smrg/*ARGSUSED*/ 138561b2299dSmrgBool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we) 13861ab64890Smrg{ 13871ab64890Smrg return True; 13881ab64890Smrg} 13891ab64890Smrg 13901ab64890Smrg/* 13911ab64890Smrg * _XError - upcall internal or user protocol error handler 13921ab64890Smrg */ 13931ab64890Smrgint _XError ( 13941ab64890Smrg Display *dpy, 13951ab64890Smrg register xError *rep) 13961ab64890Smrg{ 139761b2299dSmrg /* 13981ab64890Smrg * X_Error packet encountered! We need to unpack the error before 13991ab64890Smrg * giving it to the user. 14001ab64890Smrg */ 14011ab64890Smrg XEvent event; /* make it a large event */ 14021ab64890Smrg register _XAsyncHandler *async, *next; 14031ab64890Smrg 14041ab64890Smrg event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep); 14051ab64890Smrg 14061ab64890Smrg for (async = dpy->async_handlers; async; async = next) { 14071ab64890Smrg next = async->next; 14081ab64890Smrg if ((*async->handler)(dpy, (xReply *)rep, 14091ab64890Smrg (char *)rep, SIZEOF(xError), async->data)) 14101ab64890Smrg return 0; 14111ab64890Smrg } 14121ab64890Smrg 14131ab64890Smrg event.xerror.display = dpy; 14141ab64890Smrg event.xerror.type = X_Error; 14151ab64890Smrg event.xerror.resourceid = rep->resourceID; 14161ab64890Smrg event.xerror.error_code = rep->errorCode; 14171ab64890Smrg event.xerror.request_code = rep->majorCode; 14181ab64890Smrg event.xerror.minor_code = rep->minorCode; 14191ab64890Smrg if (dpy->error_vec && 14201ab64890Smrg !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep)) 14211ab64890Smrg return 0; 14221ab64890Smrg if (_XErrorFunction != NULL) { 1423c17aa6b1Smrg int rtn_val; 1424c17aa6b1Smrg#ifdef XTHREADS 1425c17aa6b1Smrg if (dpy->lock) 1426c17aa6b1Smrg (*dpy->lock->user_lock_display)(dpy); 1427c17aa6b1Smrg UnlockDisplay(dpy); 1428c17aa6b1Smrg#endif 1429c17aa6b1Smrg rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ 1430c17aa6b1Smrg#ifdef XTHREADS 1431c17aa6b1Smrg LockDisplay(dpy); 1432c17aa6b1Smrg if (dpy->lock) 1433c17aa6b1Smrg (*dpy->lock->user_unlock_display)(dpy); 1434c17aa6b1Smrg#endif 1435c17aa6b1Smrg return rtn_val; 14361ab64890Smrg } else { 14371ab64890Smrg return _XDefaultError(dpy, (XErrorEvent *)&event); 14381ab64890Smrg } 14391ab64890Smrg} 144061b2299dSmrg 14411ab64890Smrg/* 14421ab64890Smrg * _XIOError - call user connection error handler and exit 14431ab64890Smrg */ 14441ab64890Smrgint 14451ab64890Smrg_XIOError ( 14461ab64890Smrg Display *dpy) 14471ab64890Smrg{ 14481ab64890Smrg dpy->flags |= XlibDisplayIOError; 14491ab64890Smrg#ifdef WIN32 14501ab64890Smrg errno = WSAGetLastError(); 14511ab64890Smrg#endif 14521ab64890Smrg 14531ab64890Smrg /* This assumes that the thread calling exit will call any atexit handlers. 14541ab64890Smrg * If this does not hold, then an alternate solution would involve 14551ab64890Smrg * registering an atexit handler to take over the lock, which would only 14561ab64890Smrg * assume that the same thread calls all the atexit handlers. */ 14571ab64890Smrg#ifdef XTHREADS 14581ab64890Smrg if (dpy->lock) 14591ab64890Smrg (*dpy->lock->user_lock_display)(dpy); 14601ab64890Smrg#endif 14611ab64890Smrg UnlockDisplay(dpy); 14621ab64890Smrg 14631ab64890Smrg if (_XIOErrorFunction != NULL) 14641ab64890Smrg (*_XIOErrorFunction)(dpy); 14651ab64890Smrg else 14661ab64890Smrg _XDefaultIOError(dpy); 14671ab64890Smrg exit (1); 1468e89c59a9Schristos#ifndef __NetBSD__ 14691ab64890Smrg return 0; 1470e89c59a9Schristos#endif 14711ab64890Smrg} 14721ab64890Smrg 14731ab64890Smrg 14741ab64890Smrg/* 14751ab64890Smrg * This routine can be used to (cheaply) get some memory within a single 14761ab64890Smrg * Xlib routine for scratch space. A single buffer is reused each time 14771ab64890Smrg * if possible. To be MT safe, you can only call this between a call to 14781ab64890Smrg * GetReq* and a call to Data* or _XSend*, or in a context when the thread 14791ab64890Smrg * is guaranteed to not unlock the display. 14801ab64890Smrg */ 14811ab64890Smrgchar *_XAllocScratch( 14821ab64890Smrg register Display *dpy, 14831ab64890Smrg unsigned long nbytes) 14841ab64890Smrg{ 14851ab64890Smrg if (nbytes > dpy->scratch_length) { 1486cf2acddeSmrg Xfree (dpy->scratch_buffer); 1487cf2acddeSmrg dpy->scratch_buffer = Xmalloc(nbytes); 1488cf2acddeSmrg if (dpy->scratch_buffer) 14891ab64890Smrg dpy->scratch_length = nbytes; 14901ab64890Smrg else dpy->scratch_length = 0; 14911ab64890Smrg } 14921ab64890Smrg return (dpy->scratch_buffer); 14931ab64890Smrg} 14941ab64890Smrg 14951ab64890Smrg/* 14961ab64890Smrg * Scratch space allocator you can call any time, multiple times, and be 14971ab64890Smrg * MT safe, but you must hand the buffer back with _XFreeTemp. 14981ab64890Smrg */ 14991ab64890Smrgchar *_XAllocTemp( 15001ab64890Smrg register Display *dpy, 15011ab64890Smrg unsigned long nbytes) 15021ab64890Smrg{ 15031ab64890Smrg char *buf; 15041ab64890Smrg 15051ab64890Smrg buf = _XAllocScratch(dpy, nbytes); 15061ab64890Smrg dpy->scratch_buffer = NULL; 15071ab64890Smrg dpy->scratch_length = 0; 15081ab64890Smrg return buf; 15091ab64890Smrg} 15101ab64890Smrg 15111ab64890Smrgvoid _XFreeTemp( 15121ab64890Smrg register Display *dpy, 15131ab64890Smrg char *buf, 15141ab64890Smrg unsigned long nbytes) 15151ab64890Smrg{ 1516cf2acddeSmrg 1517cf2acddeSmrg Xfree(dpy->scratch_buffer); 15181ab64890Smrg dpy->scratch_buffer = buf; 15191ab64890Smrg dpy->scratch_length = nbytes; 15201ab64890Smrg} 15211ab64890Smrg 15221ab64890Smrg/* 15231ab64890Smrg * Given a visual id, find the visual structure for this id on this display. 15241ab64890Smrg */ 15251ab64890SmrgVisual *_XVIDtoVisual( 15261ab64890Smrg Display *dpy, 15271ab64890Smrg VisualID id) 15281ab64890Smrg{ 15291ab64890Smrg register int i, j, k; 15301ab64890Smrg register Screen *sp; 15311ab64890Smrg register Depth *dp; 15321ab64890Smrg register Visual *vp; 15331ab64890Smrg for (i = 0; i < dpy->nscreens; i++) { 15341ab64890Smrg sp = &dpy->screens[i]; 15351ab64890Smrg for (j = 0; j < sp->ndepths; j++) { 15361ab64890Smrg dp = &sp->depths[j]; 15371ab64890Smrg /* if nvisuals == 0 then visuals will be NULL */ 15381ab64890Smrg for (k = 0; k < dp->nvisuals; k++) { 15391ab64890Smrg vp = &dp->visuals[k]; 15401ab64890Smrg if (vp->visualid == id) return (vp); 15411ab64890Smrg } 15421ab64890Smrg } 15431ab64890Smrg } 15441ab64890Smrg return (NULL); 15451ab64890Smrg} 15461ab64890Smrg 15471ab64890Smrgint 15481ab64890SmrgXFree (void *data) 15491ab64890Smrg{ 15501ab64890Smrg Xfree (data); 15511ab64890Smrg return 1; 15521ab64890Smrg} 15531ab64890Smrg 15541ab64890Smrg#ifdef _XNEEDBCOPYFUNC 15551ab64890Smrgvoid _Xbcopy(b1, b2, length) 15561ab64890Smrg register char *b1, *b2; 15571ab64890Smrg register length; 15581ab64890Smrg{ 15591ab64890Smrg if (b1 < b2) { 15601ab64890Smrg b2 += length; 15611ab64890Smrg b1 += length; 15621ab64890Smrg while (length--) 15631ab64890Smrg *--b2 = *--b1; 15641ab64890Smrg } else { 15651ab64890Smrg while (length--) 15661ab64890Smrg *b2++ = *b1++; 15671ab64890Smrg } 15681ab64890Smrg} 15691ab64890Smrg#endif 15701ab64890Smrg 15711ab64890Smrg#ifdef DataRoutineIsProcedure 15721ab64890Smrgvoid Data( 15731ab64890Smrg Display *dpy, 1574556b6652Smrg _Xconst char *data, 15751ab64890Smrg long len) 15761ab64890Smrg{ 15771ab64890Smrg if (dpy->bufptr + (len) <= dpy->bufmax) { 15781ab64890Smrg memcpy(dpy->bufptr, data, (int)len); 15791ab64890Smrg dpy->bufptr += ((len) + 3) & ~3; 15801ab64890Smrg } else { 15811ab64890Smrg _XSend(dpy, data, len); 15821ab64890Smrg } 15831ab64890Smrg} 15841ab64890Smrg#endif /* DataRoutineIsProcedure */ 15851ab64890Smrg 15861ab64890Smrg 15871ab64890Smrg#ifdef LONG64 15881ab64890Smrgint 15891ab64890Smrg_XData32( 15901ab64890Smrg Display *dpy, 1591556b6652Smrg register _Xconst long *data, 15921ab64890Smrg unsigned len) 15931ab64890Smrg{ 15941ab64890Smrg register int *buf; 15951ab64890Smrg register long i; 15961ab64890Smrg 15971ab64890Smrg while (len) { 15981ab64890Smrg buf = (int *)dpy->bufptr; 15991ab64890Smrg i = dpy->bufmax - (char *)buf; 16001ab64890Smrg if (!i) { 16011ab64890Smrg _XFlush(dpy); 16021ab64890Smrg continue; 16031ab64890Smrg } 16041ab64890Smrg if (len < i) 16051ab64890Smrg i = len; 16061ab64890Smrg dpy->bufptr = (char *)buf + i; 16071ab64890Smrg len -= i; 16081ab64890Smrg i >>= 2; 16091ab64890Smrg while (--i >= 0) 16101ab64890Smrg *buf++ = *data++; 16111ab64890Smrg } 16121ab64890Smrg return 0; 16131ab64890Smrg} 16141ab64890Smrg#endif /* LONG64 */ 16151ab64890Smrg 16161ab64890Smrg 16171ab64890Smrg 16181ab64890Smrg/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm. 16191ab64890Smrg * Otherwise, Xau will not be able to find your cookies in the Xauthority file. 16201ab64890Smrg * 16211ab64890Smrg * Note: POSIX says that the ``nodename'' member of utsname does _not_ have 16221ab64890Smrg * to have sufficient information for interfacing to the network, 16231ab64890Smrg * and so, you may be better off using gethostname (if it exists). 16241ab64890Smrg */ 16251ab64890Smrg 16262e9c7c8cSmrg#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4) 16271ab64890Smrg#define NEED_UTSNAME 16281ab64890Smrg#include <sys/utsname.h> 162988de56ccSmrg#else 163088de56ccSmrg#ifdef HAVE_UNISTD_H 163188de56ccSmrg#include <unistd.h> 163288de56ccSmrg#endif 16331ab64890Smrg#endif 16341ab64890Smrg 16351ab64890Smrg/* 16361ab64890Smrg * _XGetHostname - similar to gethostname but allows special processing. 16371ab64890Smrg */ 16381ab64890Smrgint _XGetHostname ( 16391ab64890Smrg char *buf, 16401ab64890Smrg int maxlen) 16411ab64890Smrg{ 16421ab64890Smrg int len; 16431ab64890Smrg 16441ab64890Smrg#ifdef NEED_UTSNAME 16451ab64890Smrg struct utsname name; 16461ab64890Smrg 16471ab64890Smrg if (maxlen <= 0 || buf == NULL) 16481ab64890Smrg return 0; 16491ab64890Smrg 16501ab64890Smrg uname (&name); 16511ab64890Smrg len = strlen (name.nodename); 16521ab64890Smrg if (len >= maxlen) len = maxlen - 1; 16531ab64890Smrg strncpy (buf, name.nodename, len); 16541ab64890Smrg buf[len] = '\0'; 16551ab64890Smrg#else 16561ab64890Smrg if (maxlen <= 0 || buf == NULL) 16571ab64890Smrg return 0; 16581ab64890Smrg 16591ab64890Smrg buf[0] = '\0'; 16601ab64890Smrg (void) gethostname (buf, maxlen); 16611ab64890Smrg buf [maxlen - 1] = '\0'; 16621ab64890Smrg len = strlen(buf); 16631ab64890Smrg#endif /* NEED_UTSNAME */ 16641ab64890Smrg return len; 16651ab64890Smrg} 16661ab64890Smrg 16671ab64890Smrg 16681ab64890Smrg/* 16691ab64890Smrg * _XScreenOfWindow - get the Screen of a given window 16701ab64890Smrg */ 16711ab64890Smrg 167261b2299dSmrgScreen *_XScreenOfWindow(Display *dpy, Window w) 16731ab64890Smrg{ 16741ab64890Smrg register int i; 16751ab64890Smrg Window root; 16761ab64890Smrg int x, y; /* dummy variables */ 16771ab64890Smrg unsigned int width, height, bw, depth; /* dummy variables */ 16781ab64890Smrg 16791ab64890Smrg if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height, 16801ab64890Smrg &bw, &depth) == False) { 16812e9c7c8cSmrg return NULL; 16821ab64890Smrg } 16831ab64890Smrg for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */ 16841ab64890Smrg if (root == RootWindow (dpy, i)) { 16851ab64890Smrg return ScreenOfDisplay (dpy, i); 16861ab64890Smrg } 16871ab64890Smrg } 16881ab64890Smrg return NULL; 16891ab64890Smrg} 16901ab64890Smrg 16911ab64890Smrg 1692556b6652Smrg/* 1693556b6652Smrg * WARNING: This implementation's pre-conditions and post-conditions 1694556b6652Smrg * must remain compatible with the old macro-based implementations of 1695556b6652Smrg * GetReq, GetReqExtra, GetResReq, and GetEmptyReq. The portions of the 1696556b6652Smrg * Display structure affected by those macros are part of libX11's 1697556b6652Smrg * ABI. 1698556b6652Smrg */ 1699556b6652Smrgvoid *_XGetRequest(Display *dpy, CARD8 type, size_t len) 1700556b6652Smrg{ 1701556b6652Smrg xReq *req; 1702556b6652Smrg 1703556b6652Smrg if (dpy->bufptr + len > dpy->bufmax) 1704556b6652Smrg _XFlush(dpy); 1705c555af55Smrg /* Request still too large, so do not allow it to overflow. */ 1706c555af55Smrg if (dpy->bufptr + len > dpy->bufmax) { 1707c555af55Smrg fprintf(stderr, 1708c555af55Smrg "Xlib: request %d length %zd would exceed buffer size.\n", 1709c555af55Smrg type, len); 1710c555af55Smrg /* Changes failure condition from overflow to NULL dereference. */ 1711c555af55Smrg return NULL; 1712c555af55Smrg } 1713556b6652Smrg 1714556b6652Smrg if (len % 4) 1715556b6652Smrg fprintf(stderr, 1716556b6652Smrg "Xlib: request %d length %zd not a multiple of 4.\n", 1717556b6652Smrg type, len); 1718556b6652Smrg 1719556b6652Smrg dpy->last_req = dpy->bufptr; 1720556b6652Smrg 1721556b6652Smrg req = (xReq*)dpy->bufptr; 1722556b6652Smrg req->reqType = type; 1723556b6652Smrg req->length = len / 4; 1724556b6652Smrg dpy->bufptr += len; 1725556b6652Smrg dpy->request++; 1726556b6652Smrg return req; 1727556b6652Smrg} 1728556b6652Smrg 17291ab64890Smrg#if defined(WIN32) 17301ab64890Smrg 17311ab64890Smrg/* 17321ab64890Smrg * These functions are intended to be used internally to Xlib only. 17331ab64890Smrg * These functions will always prefix the path with a DOS drive in the 17341ab64890Smrg * form "<drive-letter>:". As such, these functions are only suitable 17351ab64890Smrg * for use by Xlib function that supply a root-based path to some 17361ab64890Smrg * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will 17371ab64890Smrg * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir". 17381ab64890Smrg */ 17391ab64890Smrg 17401ab64890Smrgstatic int access_file (path, pathbuf, len_pathbuf, pathret) 17411ab64890Smrg char* path; 17421ab64890Smrg char* pathbuf; 17431ab64890Smrg int len_pathbuf; 17441ab64890Smrg char** pathret; 17451ab64890Smrg{ 17461ab64890Smrg if (access (path, F_OK) == 0) { 17471ab64890Smrg if (strlen (path) < len_pathbuf) 17481ab64890Smrg *pathret = pathbuf; 17491ab64890Smrg else 17501ab64890Smrg *pathret = Xmalloc (strlen (path) + 1); 17511ab64890Smrg if (*pathret) { 17521ab64890Smrg strcpy (*pathret, path); 17531ab64890Smrg return 1; 17541ab64890Smrg } 17551ab64890Smrg } 17561ab64890Smrg return 0; 17571ab64890Smrg} 17581ab64890Smrg 17591ab64890Smrgstatic int AccessFile (path, pathbuf, len_pathbuf, pathret) 17601ab64890Smrg char* path; 17611ab64890Smrg char* pathbuf; 17621ab64890Smrg int len_pathbuf; 17631ab64890Smrg char** pathret; 17641ab64890Smrg{ 17651ab64890Smrg unsigned long drives; 17661ab64890Smrg int i, len; 17671ab64890Smrg char* drive; 17681ab64890Smrg char buf[MAX_PATH]; 17691ab64890Smrg char* bufp; 17701ab64890Smrg 17711ab64890Smrg /* just try the "raw" name first and see if it works */ 17721ab64890Smrg if (access_file (path, pathbuf, len_pathbuf, pathret)) 17731ab64890Smrg return 1; 17741ab64890Smrg 17751ab64890Smrg /* try the places set in the environment */ 17761ab64890Smrg drive = getenv ("_XBASEDRIVE"); 17771ab64890Smrg#ifdef __UNIXOS2__ 17781ab64890Smrg if (!drive) 17791ab64890Smrg drive = getenv ("X11ROOT"); 17801ab64890Smrg#endif 17811ab64890Smrg if (!drive) 17821ab64890Smrg drive = "C:"; 17831ab64890Smrg len = strlen (drive) + strlen (path); 17841ab64890Smrg if (len < MAX_PATH) bufp = buf; 17851ab64890Smrg else bufp = Xmalloc (len + 1); 17861ab64890Smrg strcpy (bufp, drive); 17871ab64890Smrg strcat (bufp, path); 17881ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 17891ab64890Smrg if (bufp != buf) Xfree (bufp); 17901ab64890Smrg return 1; 17911ab64890Smrg } 17921ab64890Smrg 179361b2299dSmrg#ifndef __UNIXOS2__ 17941ab64890Smrg /* one last place to look */ 17951ab64890Smrg drive = getenv ("HOMEDRIVE"); 17961ab64890Smrg if (drive) { 17971ab64890Smrg len = strlen (drive) + strlen (path); 17981ab64890Smrg if (len < MAX_PATH) bufp = buf; 17991ab64890Smrg else bufp = Xmalloc (len + 1); 18001ab64890Smrg strcpy (bufp, drive); 18011ab64890Smrg strcat (bufp, path); 18021ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 18031ab64890Smrg if (bufp != buf) Xfree (bufp); 18041ab64890Smrg return 1; 18051ab64890Smrg } 18061ab64890Smrg } 18071ab64890Smrg 18081ab64890Smrg /* tried everywhere else, go fishing */ 18091ab64890Smrg#define C_DRIVE ('C' - 'A') 18101ab64890Smrg#define Z_DRIVE ('Z' - 'A') 18111ab64890Smrg /* does OS/2 (with or with gcc-emx) have getdrives? */ 18121ab64890Smrg drives = _getdrives (); 18131ab64890Smrg for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */ 18141ab64890Smrg if ((1 << i) & drives) { 18151ab64890Smrg len = 2 + strlen (path); 18161ab64890Smrg if (len < MAX_PATH) bufp = buf; 18171ab64890Smrg else bufp = Xmalloc (len + 1); 18181ab64890Smrg *bufp = 'A' + i; 18191ab64890Smrg *(bufp + 1) = ':'; 18201ab64890Smrg *(bufp + 2) = '\0'; 18211ab64890Smrg strcat (bufp, path); 18221ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 18231ab64890Smrg if (bufp != buf) Xfree (bufp); 18241ab64890Smrg return 1; 18251ab64890Smrg } 18261ab64890Smrg } 18271ab64890Smrg } 18281ab64890Smrg#endif 18291ab64890Smrg return 0; 18301ab64890Smrg} 18311ab64890Smrg 18321ab64890Smrgint _XOpenFile(path, flags) 18331ab64890Smrg _Xconst char* path; 18341ab64890Smrg int flags; 18351ab64890Smrg{ 18361ab64890Smrg char buf[MAX_PATH]; 18371ab64890Smrg char* bufp = NULL; 18381ab64890Smrg int ret = -1; 18391ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 18401ab64890Smrg 18411ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 18421ab64890Smrg ret = open (bufp, flags); 18431ab64890Smrg 18441ab64890Smrg (void) SetErrorMode (olderror); 18451ab64890Smrg 18461ab64890Smrg if (bufp != buf) Xfree (bufp); 18471ab64890Smrg 18481ab64890Smrg return ret; 18491ab64890Smrg} 18501ab64890Smrg 18511ab64890Smrgint _XOpenFileMode(path, flags, mode) 18521ab64890Smrg _Xconst char* path; 18531ab64890Smrg int flags; 18541ab64890Smrg mode_t mode; 18551ab64890Smrg{ 18561ab64890Smrg char buf[MAX_PATH]; 18571ab64890Smrg char* bufp = NULL; 18581ab64890Smrg int ret = -1; 18591ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 18601ab64890Smrg 18611ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 18621ab64890Smrg ret = open (bufp, flags, mode); 18631ab64890Smrg 18641ab64890Smrg (void) SetErrorMode (olderror); 18651ab64890Smrg 18661ab64890Smrg if (bufp != buf) Xfree (bufp); 18671ab64890Smrg 18681ab64890Smrg return ret; 18691ab64890Smrg} 18701ab64890Smrg 18711ab64890Smrgvoid* _XFopenFile(path, mode) 18721ab64890Smrg _Xconst char* path; 18731ab64890Smrg _Xconst char* mode; 18741ab64890Smrg{ 18751ab64890Smrg char buf[MAX_PATH]; 18761ab64890Smrg char* bufp = NULL; 18771ab64890Smrg void* ret = NULL; 18781ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 18791ab64890Smrg 18801ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 18811ab64890Smrg ret = fopen (bufp, mode); 18821ab64890Smrg 18831ab64890Smrg (void) SetErrorMode (olderror); 18841ab64890Smrg 18851ab64890Smrg if (bufp != buf) Xfree (bufp); 18861ab64890Smrg 18871ab64890Smrg return ret; 18881ab64890Smrg} 18891ab64890Smrg 18901ab64890Smrgint _XAccessFile(path) 18911ab64890Smrg _Xconst char* path; 18921ab64890Smrg{ 18931ab64890Smrg char buf[MAX_PATH]; 18941ab64890Smrg char* bufp; 18951ab64890Smrg int ret = -1; 18961ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 18971ab64890Smrg 18981ab64890Smrg ret = AccessFile (path, buf, MAX_PATH, &bufp); 18991ab64890Smrg 19001ab64890Smrg (void) SetErrorMode (olderror); 19011ab64890Smrg 19021ab64890Smrg if (bufp != buf) Xfree (bufp); 19031ab64890Smrg 19041ab64890Smrg return ret; 19051ab64890Smrg} 19061ab64890Smrg 19071ab64890Smrg#endif 19081ab64890Smrg 19091ab64890Smrg#ifdef WIN32 19101ab64890Smrg#undef _Xdebug 19111ab64890Smrgint _Xdebug = 0; 19121ab64890Smrgint *_Xdebug_p = &_Xdebug; 19131ab64890Smrgvoid (**_XCreateMutex_fn_p)(LockInfoPtr) = &_XCreateMutex_fn; 19141ab64890Smrgvoid (**_XFreeMutex_fn_p)(LockInfoPtr) = &_XFreeMutex_fn; 19151ab64890Smrgvoid (**_XLockMutex_fn_p)(LockInfoPtr 19161ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 19171ab64890Smrg , char * /* file */ 19181ab64890Smrg , int /* line */ 19191ab64890Smrg#endif 19201ab64890Smrg ) = &_XLockMutex_fn; 19211ab64890Smrgvoid (**_XUnlockMutex_fn_p)(LockInfoPtr 19221ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 19231ab64890Smrg , char * /* file */ 19241ab64890Smrg , int /* line */ 19251ab64890Smrg#endif 19261ab64890Smrg ) = &_XUnlockMutex_fn; 19271ab64890SmrgLockInfoPtr *_Xglobal_lock_p = &_Xglobal_lock; 19281ab64890Smrg#endif 1929