XlibInt.c revision 15c3e985
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" 42f2d49d05Smrg#include "reallocarray.h" 431ab64890Smrg#include <X11/Xpoll.h> 4461b2299dSmrg#include <assert.h> 451ab64890Smrg#include <stdio.h> 461ab64890Smrg#ifdef WIN32 471ab64890Smrg#include <direct.h> 481ab64890Smrg#endif 491ab64890Smrg 50f2d49d05Smrg/* Needed for FIONREAD on Solaris */ 51f2d49d05Smrg#ifdef HAVE_SYS_FILIO_H 52f2d49d05Smrg#include <sys/filio.h> 53f2d49d05Smrg#endif 54f2d49d05Smrg 55f2d49d05Smrg/* Needed for FIONREAD on Cygwin */ 56f2d49d05Smrg#ifdef HAVE_SYS_SOCKET_H 57f2d49d05Smrg#include <sys/socket.h> 58f2d49d05Smrg#endif 59f2d49d05Smrg 60f2d49d05Smrg/* Needed for ioctl() on Solaris */ 61f2d49d05Smrg#ifdef HAVE_UNISTD_H 62f2d49d05Smrg#include <unistd.h> 63f2d49d05Smrg#endif 64f2d49d05Smrg 651ab64890Smrg#ifdef XTHREADS 661ab64890Smrg#include "locking.h" 671ab64890Smrg 68f2d49d05Smrg#ifdef HAVE_SYS_IOCTL_H 69f2d49d05Smrg#include <sys/ioctl.h> 70f2d49d05Smrg#endif 71f2d49d05Smrg 721ab64890Smrg/* these pointers get initialized by XInitThreads */ 731ab64890SmrgLockInfoPtr _Xglobal_lock = NULL; 741ab64890Smrgvoid (*_XCreateMutex_fn)(LockInfoPtr) = NULL; 751ab64890Smrg/* struct _XCVList *(*_XCreateCVL_fn)() = NULL; */ 761ab64890Smrgvoid (*_XFreeMutex_fn)(LockInfoPtr) = NULL; 771ab64890Smrgvoid (*_XLockMutex_fn)( 781ab64890Smrg LockInfoPtr /* lock */ 791ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 801ab64890Smrg , char * /* file */ 811ab64890Smrg , int /* line */ 821ab64890Smrg#endif 831ab64890Smrg ) = NULL; 841ab64890Smrgvoid (*_XUnlockMutex_fn)( 851ab64890Smrg LockInfoPtr /* lock */ 861ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 871ab64890Smrg , char * /* file */ 881ab64890Smrg , int /* line */ 891ab64890Smrg#endif 901ab64890Smrg ) = NULL; 911ab64890Smrgxthread_t (*_Xthread_self_fn)(void) = NULL; 921ab64890Smrg 931ab64890Smrg#define XThread_Self() ((*_Xthread_self_fn)()) 941ab64890Smrg 95295fb823Smrg#endif /* XTHREADS */ 961ab64890Smrg 971ab64890Smrg#ifdef WIN32 981ab64890Smrg#define ECHECK(err) (WSAGetLastError() == err) 991ab64890Smrg#define ESET(val) WSASetLastError(val) 1001ab64890Smrg#else 1011ab64890Smrg#ifdef __UNIXOS2__ 1021ab64890Smrg#define ECHECK(err) (errno == err) 1031ab64890Smrg#define ESET(val) 1041ab64890Smrg#else 1051ab64890Smrg#define ECHECK(err) (errno == err) 1061ab64890Smrg#define ESET(val) errno = val 1071ab64890Smrg#endif 1081ab64890Smrg#endif 1091ab64890Smrg 1101ab64890Smrg#ifdef __UNIXOS2__ 1111ab64890Smrg#include <limits.h> 1121ab64890Smrg#define MAX_PATH _POSIX_PATH_MAX 1131ab64890Smrg#endif 1141ab64890Smrg 1151ab64890Smrg/* 1161ab64890Smrg * The following routines are internal routines used by Xlib for protocol 1171ab64890Smrg * packet transmission and reception. 1181ab64890Smrg * 1191ab64890Smrg * _XIOError(Display *) will be called if any sort of system call error occurs. 1201ab64890Smrg * This is assumed to be a fatal condition, i.e., XIOError should not return. 1211ab64890Smrg * 1221ab64890Smrg * _XError(Display *, xError *) will be called whenever an X_Error event is 1231ab64890Smrg * received. This is not assumed to be a fatal condition, i.e., it is 1241ab64890Smrg * acceptable for this procedure to return. However, XError should NOT 1251ab64890Smrg * perform any operations (directly or indirectly) on the DISPLAY. 1261ab64890Smrg * 1271ab64890Smrg * Routines declared with a return type of 'Status' return 0 on failure, 12861b2299dSmrg * and non 0 on success. Routines with no declared return type don't 1291ab64890Smrg * return anything. Whenever possible routines that create objects return 1301ab64890Smrg * the object they have created. 1311ab64890Smrg */ 1321ab64890Smrg 1331ab64890Smrg#define POLLFD_CACHE_SIZE 5 1341ab64890Smrg 1351ab64890Smrg/* initialize the struct array passed to poll() below */ 1361ab64890SmrgBool _XPollfdCacheInit( 1371ab64890Smrg Display *dpy) 1381ab64890Smrg{ 1391ab64890Smrg#ifdef USE_POLL 1401ab64890Smrg struct pollfd *pfp; 1411ab64890Smrg 142556b6652Smrg pfp = Xmalloc(POLLFD_CACHE_SIZE * sizeof(struct pollfd)); 1431ab64890Smrg if (!pfp) 1441ab64890Smrg return False; 1451ab64890Smrg pfp[0].fd = dpy->fd; 1461ab64890Smrg pfp[0].events = POLLIN; 1471ab64890Smrg 1481ab64890Smrg dpy->filedes = (XPointer)pfp; 1491ab64890Smrg#endif 1501ab64890Smrg return True; 1511ab64890Smrg} 1521ab64890Smrg 1531ab64890Smrgvoid _XPollfdCacheAdd( 1541ab64890Smrg Display *dpy, 1551ab64890Smrg int fd) 1561ab64890Smrg{ 1571ab64890Smrg#ifdef USE_POLL 1581ab64890Smrg struct pollfd *pfp = (struct pollfd *)dpy->filedes; 1591ab64890Smrg 1601ab64890Smrg if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { 1611ab64890Smrg pfp[dpy->im_fd_length].fd = fd; 1621ab64890Smrg pfp[dpy->im_fd_length].events = POLLIN; 1631ab64890Smrg } 1641ab64890Smrg#endif 1651ab64890Smrg} 1661ab64890Smrg 1671ab64890Smrg/* ARGSUSED */ 1681ab64890Smrgvoid _XPollfdCacheDel( 1691ab64890Smrg Display *dpy, 1701ab64890Smrg int fd) /* not used */ 1711ab64890Smrg{ 1721ab64890Smrg#ifdef USE_POLL 1731ab64890Smrg struct pollfd *pfp = (struct pollfd *)dpy->filedes; 1741ab64890Smrg struct _XConnectionInfo *conni; 1751ab64890Smrg 1761ab64890Smrg /* just recalculate whole list */ 1771ab64890Smrg if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { 1781ab64890Smrg int loc = 1; 1791ab64890Smrg for (conni = dpy->im_fd_info; conni; conni=conni->next) { 1801ab64890Smrg pfp[loc].fd = conni->fd; 1811ab64890Smrg pfp[loc].events = POLLIN; 1821ab64890Smrg loc++; 1831ab64890Smrg } 1841ab64890Smrg } 1851ab64890Smrg#endif 1861ab64890Smrg} 1871ab64890Smrg 18861b2299dSmrgstatic int sync_hazard(Display *dpy) 18961b2299dSmrg{ 190dac667f7Smrg /* 191e90f245cSmaya * "span" and "hazard" need to be signed such that the ">=" comparison 192dac667f7Smrg * works correctly in the case that hazard is greater than 65525 193dac667f7Smrg */ 194dac667f7Smrg int64_t span = X_DPY_GET_REQUEST(dpy) - X_DPY_GET_LAST_REQUEST_READ(dpy); 195dac667f7Smrg int64_t hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10); 19661b2299dSmrg return span >= 65535 - hazard - 10; 19761b2299dSmrg} 19861b2299dSmrg 1991ab64890Smrgstatic 20088de56ccSmrgvoid sync_while_locked(Display *dpy) 20188de56ccSmrg{ 20288de56ccSmrg#ifdef XTHREADS 20388de56ccSmrg if (dpy->lock) 20488de56ccSmrg (*dpy->lock->user_lock_display)(dpy); 20588de56ccSmrg#endif 20688de56ccSmrg UnlockDisplay(dpy); 20788de56ccSmrg SyncHandle(); 20888de56ccSmrg InternalLockDisplay(dpy, /* don't skip user locks */ 0); 20988de56ccSmrg#ifdef XTHREADS 21088de56ccSmrg if (dpy->lock) 21188de56ccSmrg (*dpy->lock->user_unlock_display)(dpy); 21288de56ccSmrg#endif 21388de56ccSmrg} 21488de56ccSmrg 21588de56ccSmrgvoid _XSeqSyncFunction( 2161ab64890Smrg register Display *dpy) 2171ab64890Smrg{ 2181ab64890Smrg xGetInputFocusReply rep; 219bd8e7fb0Smrg _X_UNUSED register xReq *req; 2201ab64890Smrg 22115c3e985Smrg if ((X_DPY_GET_REQUEST(dpy) - X_DPY_GET_LAST_REQUEST_READ(dpy)) >= (65535 - BUFSIZE/SIZEOF(xReq))) { 2221ab64890Smrg GetEmptyReq(GetInputFocus, req); 2231ab64890Smrg (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); 22488de56ccSmrg sync_while_locked(dpy); 22561b2299dSmrg } else if (sync_hazard(dpy)) 22661b2299dSmrg _XSetPrivSyncFunction(dpy); 2271ab64890Smrg} 2281ab64890Smrg 22988de56ccSmrg/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */ 23061b2299dSmrgstatic int 23161b2299dSmrg_XPrivSyncFunction (Display *dpy) 23261b2299dSmrg{ 233e0787e08Smrg#ifdef XTHREADS 23488de56ccSmrg assert(!dpy->lock_fns); 23588de56ccSmrg#endif 23661b2299dSmrg assert(dpy->synchandler == _XPrivSyncFunction); 23761b2299dSmrg assert((dpy->flags & XlibDisplayPrivSync) != 0); 23861b2299dSmrg dpy->synchandler = dpy->savedsynchandler; 23961b2299dSmrg dpy->savedsynchandler = NULL; 24061b2299dSmrg dpy->flags &= ~XlibDisplayPrivSync; 24188de56ccSmrg if(dpy->synchandler) 24288de56ccSmrg dpy->synchandler(dpy); 24361b2299dSmrg _XIDHandler(dpy); 24461b2299dSmrg _XSeqSyncFunction(dpy); 24561b2299dSmrg return 0; 24661b2299dSmrg} 24761b2299dSmrg 24861b2299dSmrgvoid _XSetPrivSyncFunction(Display *dpy) 2491ab64890Smrg{ 25088de56ccSmrg#ifdef XTHREADS 25188de56ccSmrg if (dpy->lock_fns) 25288de56ccSmrg return; 25388de56ccSmrg#endif 25461b2299dSmrg if (!(dpy->flags & XlibDisplayPrivSync)) { 2551ab64890Smrg dpy->savedsynchandler = dpy->synchandler; 25661b2299dSmrg dpy->synchandler = _XPrivSyncFunction; 2571ab64890Smrg dpy->flags |= XlibDisplayPrivSync; 2581ab64890Smrg } 2591ab64890Smrg} 2601ab64890Smrg 26161b2299dSmrgvoid _XSetSeqSyncFunction(Display *dpy) 26261b2299dSmrg{ 26361b2299dSmrg if (sync_hazard(dpy)) 26461b2299dSmrg _XSetPrivSyncFunction (dpy); 26561b2299dSmrg} 26661b2299dSmrg 2671ab64890Smrg#ifdef LONG64 2681ab64890Smrgvoid _XRead32( 2691ab64890Smrg Display *dpy, 27015c3e985Smrg long *data, 2711ab64890Smrg long len) 2721ab64890Smrg{ 2731ab64890Smrg register int *buf; 2741ab64890Smrg register long i; 2751ab64890Smrg 2761ab64890Smrg if (len) { 2771ab64890Smrg (void) _XRead(dpy, (char *)data, len); 2781ab64890Smrg i = len >> 2; 2791ab64890Smrg buf = (int *)data + i; 2801ab64890Smrg data += i; 2811ab64890Smrg while (--i >= 0) 2821ab64890Smrg *--data = *--buf; 2831ab64890Smrg } 2841ab64890Smrg} 2851ab64890Smrg#endif /* LONG64 */ 2861ab64890Smrg 2871ab64890Smrg 2881ab64890Smrg/* 2891ab64890Smrg * The hard part about this is that we only get 16 bits from a reply. 2901ab64890Smrg * We have three values that will march along, with the following invariant: 2911ab64890Smrg * dpy->last_request_read <= rep->sequenceNumber <= dpy->request 2921ab64890Smrg * We have to keep 2931ab64890Smrg * dpy->request - dpy->last_request_read < 2^16 2941ab64890Smrg * or else we won't know for sure what value to use in events. We do this 2951ab64890Smrg * by forcing syncs when we get close. 2961ab64890Smrg */ 2971ab64890Smrg 2981ab64890Smrgunsigned long 2991ab64890Smrg_XSetLastRequestRead( 3001ab64890Smrg register Display *dpy, 3011ab64890Smrg register xGenericReply *rep) 3021ab64890Smrg{ 303dac667f7Smrg register uint64_t newseq, lastseq; 3041ab64890Smrg 305dac667f7Smrg lastseq = X_DPY_GET_LAST_REQUEST_READ(dpy); 3061ab64890Smrg /* 3071ab64890Smrg * KeymapNotify has no sequence number, but is always guaranteed 3081ab64890Smrg * to immediately follow another event, except when generated via 3091ab64890Smrg * SendEvent (hmmm). 3101ab64890Smrg */ 3111ab64890Smrg if ((rep->type & 0x7f) == KeymapNotify) 3121ab64890Smrg return(lastseq); 3131ab64890Smrg 314dac667f7Smrg newseq = (lastseq & ~((uint64_t)0xffff)) | rep->sequenceNumber; 3151ab64890Smrg 3161ab64890Smrg if (newseq < lastseq) { 3171ab64890Smrg newseq += 0x10000; 318dac667f7Smrg if (newseq > X_DPY_GET_REQUEST(dpy)) { 31961b2299dSmrg (void) fprintf (stderr, 320dac667f7Smrg "Xlib: sequence lost (0x%llx > 0x%llx) in reply type 0x%x!\n", 321dac667f7Smrg (unsigned long long)newseq, 322dac667f7Smrg (unsigned long long)(X_DPY_GET_REQUEST(dpy)), 3231ab64890Smrg (unsigned int) rep->type); 3241ab64890Smrg newseq -= 0x10000; 3251ab64890Smrg } 3261ab64890Smrg } 3271ab64890Smrg 328dac667f7Smrg X_DPY_SET_LAST_REQUEST_READ(dpy, newseq); 3291ab64890Smrg return(newseq); 3301ab64890Smrg} 3311ab64890Smrg 3321ab64890Smrg/* 3331ab64890Smrg * Support for internal connections, such as an IM might use. 3341ab64890Smrg * By Stephen Gildea, X Consortium, September 1993 3351ab64890Smrg */ 3361ab64890Smrg 3371ab64890Smrg/* _XRegisterInternalConnection 3381ab64890Smrg * Each IM (or Xlib extension) that opens a file descriptor that Xlib should 3391ab64890Smrg * include in its select/poll mask must call this function to register the 3401ab64890Smrg * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch 3411ab64890Smrg * will also be called. 3421ab64890Smrg * 3431ab64890Smrg * Whenever Xlib detects input available on fd, it will call callback 3441ab64890Smrg * with call_data to process it. If non-Xlib code calls select/poll 3451ab64890Smrg * and detects input available, it must call XProcessInternalConnection, 3461ab64890Smrg * which will call the associated callback. 3471ab64890Smrg * 3481ab64890Smrg * Non-Xlib code can learn about these additional fds by calling 3491ab64890Smrg * XInternalConnectionNumbers or, more typically, by registering 3501ab64890Smrg * a XConnectionWatchProc with XAddConnectionWatch 3511ab64890Smrg * to be called when fds are registered or unregistered. 3521ab64890Smrg * 3531ab64890Smrg * Returns True if registration succeeded, False if not, typically 3541ab64890Smrg * because could not allocate memory. 3551ab64890Smrg * Assumes Display locked when called. 3561ab64890Smrg */ 3571ab64890SmrgStatus 3581ab64890Smrg_XRegisterInternalConnection( 3591ab64890Smrg Display* dpy, 3601ab64890Smrg int fd, 3611ab64890Smrg _XInternalConnectionProc callback, 3621ab64890Smrg XPointer call_data 3631ab64890Smrg) 3641ab64890Smrg{ 3651ab64890Smrg struct _XConnectionInfo *new_conni, **iptr; 3661ab64890Smrg struct _XConnWatchInfo *watchers; 3671ab64890Smrg XPointer *wd; 3681ab64890Smrg 369556b6652Smrg new_conni = Xmalloc(sizeof(struct _XConnectionInfo)); 3701ab64890Smrg if (!new_conni) 3711ab64890Smrg return 0; 372f2d49d05Smrg new_conni->watch_data = Xmallocarray(dpy->watcher_count, sizeof(XPointer)); 3731ab64890Smrg if (!new_conni->watch_data) { 3741ab64890Smrg Xfree(new_conni); 3751ab64890Smrg return 0; 3761ab64890Smrg } 3771ab64890Smrg new_conni->fd = fd; 3781ab64890Smrg new_conni->read_callback = callback; 3791ab64890Smrg new_conni->call_data = call_data; 3801ab64890Smrg new_conni->next = NULL; 3811ab64890Smrg /* link new structure onto end of list */ 3821ab64890Smrg for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next) 3831ab64890Smrg ; 3841ab64890Smrg *iptr = new_conni; 3851ab64890Smrg dpy->im_fd_length++; 3861ab64890Smrg _XPollfdCacheAdd(dpy, fd); 3871ab64890Smrg 3881ab64890Smrg for (watchers=dpy->conn_watchers, wd=new_conni->watch_data; 3891ab64890Smrg watchers; 3901ab64890Smrg watchers=watchers->next, wd++) { 3911ab64890Smrg *wd = NULL; /* for cleanliness */ 3921ab64890Smrg (*watchers->fn) (dpy, watchers->client_data, fd, True, wd); 3931ab64890Smrg } 3941ab64890Smrg 3951ab64890Smrg return 1; 3961ab64890Smrg} 3971ab64890Smrg 3981ab64890Smrg/* _XUnregisterInternalConnection 3991ab64890Smrg * Each IM (or Xlib extension) that closes a file descriptor previously 4001ab64890Smrg * registered with _XRegisterInternalConnection must call this function. 4011ab64890Smrg * Any XConnectionWatchProc registered by XAddConnectionWatch 4021ab64890Smrg * will also be called. 4031ab64890Smrg * 4041ab64890Smrg * Assumes Display locked when called. 4051ab64890Smrg */ 4061ab64890Smrgvoid 4071ab64890Smrg_XUnregisterInternalConnection( 4081ab64890Smrg Display* dpy, 4091ab64890Smrg int fd 4101ab64890Smrg) 4111ab64890Smrg{ 4121ab64890Smrg struct _XConnectionInfo *info_list, **prev; 4131ab64890Smrg struct _XConnWatchInfo *watch; 4141ab64890Smrg XPointer *wd; 4151ab64890Smrg 4161ab64890Smrg for (prev = &dpy->im_fd_info; (info_list = *prev); 4171ab64890Smrg prev = &info_list->next) { 4181ab64890Smrg if (info_list->fd == fd) { 4191ab64890Smrg *prev = info_list->next; 4201ab64890Smrg dpy->im_fd_length--; 4211ab64890Smrg for (watch=dpy->conn_watchers, wd=info_list->watch_data; 4221ab64890Smrg watch; 4231ab64890Smrg watch=watch->next, wd++) { 4241ab64890Smrg (*watch->fn) (dpy, watch->client_data, fd, False, wd); 4251ab64890Smrg } 426cf2acddeSmrg Xfree (info_list->watch_data); 4271ab64890Smrg Xfree (info_list); 4281ab64890Smrg break; 4291ab64890Smrg } 4301ab64890Smrg } 4311ab64890Smrg _XPollfdCacheDel(dpy, fd); 4321ab64890Smrg} 4331ab64890Smrg 4341ab64890Smrg/* XInternalConnectionNumbers 4351ab64890Smrg * Returns an array of fds and an array of corresponding call data. 4361ab64890Smrg * Typically a XConnectionWatchProc registered with XAddConnectionWatch 4371ab64890Smrg * will be used instead of this function to discover 4381ab64890Smrg * additional fds to include in the select/poll mask. 4391ab64890Smrg * 4401ab64890Smrg * The list is allocated with Xmalloc and should be freed by the caller 4411ab64890Smrg * with Xfree; 4421ab64890Smrg */ 4431ab64890SmrgStatus 4441ab64890SmrgXInternalConnectionNumbers( 4451ab64890Smrg Display *dpy, 4461ab64890Smrg int **fd_return, 4471ab64890Smrg int *count_return 4481ab64890Smrg) 4491ab64890Smrg{ 4501ab64890Smrg int count; 4511ab64890Smrg struct _XConnectionInfo *info_list; 4521ab64890Smrg int *fd_list; 4531ab64890Smrg 4541ab64890Smrg LockDisplay(dpy); 4551ab64890Smrg count = 0; 4561ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) 4571ab64890Smrg count++; 458f2d49d05Smrg fd_list = Xmallocarray (count, sizeof(int)); 4591ab64890Smrg if (!fd_list) { 4601ab64890Smrg UnlockDisplay(dpy); 4611ab64890Smrg return 0; 4621ab64890Smrg } 4631ab64890Smrg count = 0; 4641ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 4651ab64890Smrg fd_list[count] = info_list->fd; 4661ab64890Smrg count++; 4671ab64890Smrg } 4681ab64890Smrg UnlockDisplay(dpy); 4691ab64890Smrg 4701ab64890Smrg *fd_return = fd_list; 4711ab64890Smrg *count_return = count; 4721ab64890Smrg return 1; 4731ab64890Smrg} 4741ab64890Smrg 4751ab64890Smrgvoid _XProcessInternalConnection( 4761ab64890Smrg Display *dpy, 4771ab64890Smrg struct _XConnectionInfo *conn_info) 4781ab64890Smrg{ 4791ab64890Smrg dpy->flags |= XlibDisplayProcConni; 4801ab64890Smrg UnlockDisplay(dpy); 4811ab64890Smrg (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data); 4821ab64890Smrg LockDisplay(dpy); 4831ab64890Smrg dpy->flags &= ~XlibDisplayProcConni; 4841ab64890Smrg} 4851ab64890Smrg 4861ab64890Smrg/* XProcessInternalConnection 4871ab64890Smrg * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection 4881ab64890Smrg * for this fd. 4891ab64890Smrg * The Display is NOT locked during the call. 4901ab64890Smrg */ 4911ab64890Smrgvoid 4921ab64890SmrgXProcessInternalConnection( 4931ab64890Smrg Display* dpy, 4941ab64890Smrg int fd 4951ab64890Smrg) 4961ab64890Smrg{ 4971ab64890Smrg struct _XConnectionInfo *info_list; 4981ab64890Smrg 4991ab64890Smrg LockDisplay(dpy); 5001ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 5011ab64890Smrg if (info_list->fd == fd) { 5021ab64890Smrg _XProcessInternalConnection(dpy, info_list); 5031ab64890Smrg break; 5041ab64890Smrg } 5051ab64890Smrg } 5061ab64890Smrg UnlockDisplay(dpy); 5071ab64890Smrg} 5081ab64890Smrg 5091ab64890Smrg/* XAddConnectionWatch 5101ab64890Smrg * Register a callback to be called whenever _XRegisterInternalConnection 5111ab64890Smrg * or _XUnregisterInternalConnection is called. 5121ab64890Smrg * Callbacks are called with the Display locked. 5131ab64890Smrg * If any connections are already registered, the callback is immediately 5141ab64890Smrg * called for each of them. 5151ab64890Smrg */ 5161ab64890SmrgStatus 5171ab64890SmrgXAddConnectionWatch( 5181ab64890Smrg Display* dpy, 5191ab64890Smrg XConnectionWatchProc callback, 5201ab64890Smrg XPointer client_data 5211ab64890Smrg) 5221ab64890Smrg{ 5231ab64890Smrg struct _XConnWatchInfo *new_watcher, **wptr; 5241ab64890Smrg struct _XConnectionInfo *info_list; 5251ab64890Smrg XPointer *wd_array; 5261ab64890Smrg 5271ab64890Smrg LockDisplay(dpy); 5281ab64890Smrg 5291ab64890Smrg /* allocate new watch data */ 5301ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 531f2d49d05Smrg wd_array = Xreallocarray(info_list->watch_data, 532f2d49d05Smrg dpy->watcher_count + 1, sizeof(XPointer)); 5331ab64890Smrg if (!wd_array) { 5341ab64890Smrg UnlockDisplay(dpy); 5351ab64890Smrg return 0; 5361ab64890Smrg } 537c17aa6b1Smrg info_list->watch_data = wd_array; 5381ab64890Smrg wd_array[dpy->watcher_count] = NULL; /* for cleanliness */ 5391ab64890Smrg } 5401ab64890Smrg 541556b6652Smrg new_watcher = Xmalloc(sizeof(struct _XConnWatchInfo)); 5421ab64890Smrg if (!new_watcher) { 5431ab64890Smrg UnlockDisplay(dpy); 5441ab64890Smrg return 0; 5451ab64890Smrg } 5461ab64890Smrg new_watcher->fn = callback; 5471ab64890Smrg new_watcher->client_data = client_data; 5481ab64890Smrg new_watcher->next = NULL; 5491ab64890Smrg 5501ab64890Smrg /* link new structure onto end of list */ 5511ab64890Smrg for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next) 5521ab64890Smrg ; 5531ab64890Smrg *wptr = new_watcher; 5541ab64890Smrg dpy->watcher_count++; 5551ab64890Smrg 5561ab64890Smrg /* call new watcher on all currently registered fds */ 5571ab64890Smrg for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { 5581ab64890Smrg (*callback) (dpy, client_data, info_list->fd, True, 5591ab64890Smrg info_list->watch_data + dpy->watcher_count - 1); 5601ab64890Smrg } 5611ab64890Smrg 5621ab64890Smrg UnlockDisplay(dpy); 5631ab64890Smrg return 1; 5641ab64890Smrg} 5651ab64890Smrg 5661ab64890Smrg/* XRemoveConnectionWatch 5671ab64890Smrg * Unregister a callback registered by XAddConnectionWatch. 5681ab64890Smrg * Both callback and client_data must match what was passed to 5691ab64890Smrg * XAddConnectionWatch. 57061b2299dSmrg */ 5711ab64890Smrgvoid 5721ab64890SmrgXRemoveConnectionWatch( 5731ab64890Smrg Display* dpy, 5741ab64890Smrg XConnectionWatchProc callback, 5751ab64890Smrg XPointer client_data 5761ab64890Smrg) 5771ab64890Smrg{ 5781ab64890Smrg struct _XConnWatchInfo *watch; 5791ab64890Smrg struct _XConnWatchInfo *previous = NULL; 5801ab64890Smrg struct _XConnectionInfo *conni; 5811ab64890Smrg int counter = 0; 5821ab64890Smrg 5831ab64890Smrg LockDisplay(dpy); 5841ab64890Smrg for (watch=dpy->conn_watchers; watch; watch=watch->next) { 5851ab64890Smrg if (watch->fn == callback && watch->client_data == client_data) { 5861ab64890Smrg if (previous) 5871ab64890Smrg previous->next = watch->next; 5881ab64890Smrg else 5891ab64890Smrg dpy->conn_watchers = watch->next; 5901ab64890Smrg Xfree (watch); 5911ab64890Smrg dpy->watcher_count--; 5921ab64890Smrg /* remove our watch_data for each connection */ 5931ab64890Smrg for (conni=dpy->im_fd_info; conni; conni=conni->next) { 5941ab64890Smrg /* don't bother realloc'ing; these arrays are small anyway */ 5951ab64890Smrg /* overlapping */ 5961ab64890Smrg memmove(conni->watch_data+counter, 5971ab64890Smrg conni->watch_data+counter+1, 5981ab64890Smrg dpy->watcher_count - counter); 5991ab64890Smrg } 6001ab64890Smrg break; 6011ab64890Smrg } 6021ab64890Smrg previous = watch; 6031ab64890Smrg counter++; 6041ab64890Smrg } 6051ab64890Smrg UnlockDisplay(dpy); 6061ab64890Smrg} 6071ab64890Smrg 6081ab64890Smrg/* end of internal connections support */ 6091ab64890Smrg 610b4ee4795Smrg/* Cookie jar implementation 611b4ee4795Smrg dpy->cookiejar is a linked list. _XEnq receives the events but leaves 612b4ee4795Smrg them in the normal EQ. _XStoreEvent returns the cookie event (minus 613b4ee4795Smrg data pointer) and adds it to the cookiejar. _XDeq just removes 614b4ee4795Smrg the entry like any other event but resets the data pointer for 615b4ee4795Smrg cookie events (to avoid double-free, the memory is re-used by Xlib). 616b4ee4795Smrg 617b4ee4795Smrg _XFetchEventCookie (called from XGetEventData) removes a cookie from the 618b4ee4795Smrg jar. _XFreeEventCookies removes all unclaimed cookies from the jar 619b4ee4795Smrg (called by XNextEvent). 620b4ee4795Smrg 621b4ee4795Smrg _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the 622b4ee4795Smrg normal EQ. 623b4ee4795Smrg */ 624b4ee4795Smrg 625b4ee4795Smrg#include "utlist.h" 626b4ee4795Smrgstruct stored_event { 627b4ee4795Smrg XGenericEventCookie ev; 628b4ee4795Smrg struct stored_event *prev; 629b4ee4795Smrg struct stored_event *next; 630b4ee4795Smrg}; 631b4ee4795Smrg 632b4ee4795SmrgBool 633b4ee4795Smrg_XIsEventCookie(Display *dpy, XEvent *ev) 634b4ee4795Smrg{ 635b4ee4795Smrg return (ev->xcookie.type == GenericEvent && 636b4ee4795Smrg dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL); 637b4ee4795Smrg} 638b4ee4795Smrg 639b4ee4795Smrg/** 640b4ee4795Smrg * Free all events in the event list. 641b4ee4795Smrg */ 642b4ee4795Smrgvoid 643b4ee4795Smrg_XFreeEventCookies(Display *dpy) 644b4ee4795Smrg{ 645b4ee4795Smrg struct stored_event **head, *e, *tmp; 646b4ee4795Smrg 647b4ee4795Smrg if (!dpy->cookiejar) 648b4ee4795Smrg return; 649b4ee4795Smrg 650b4ee4795Smrg head = (struct stored_event**)&dpy->cookiejar; 651b4ee4795Smrg 652b4ee4795Smrg DL_FOREACH_SAFE(*head, e, tmp) { 653c17aa6b1Smrg XFree(e->ev.data); 654c17aa6b1Smrg XFree(e); 655b4ee4795Smrg } 65615c3e985Smrg dpy->cookiejar = NULL; 657b4ee4795Smrg} 658b4ee4795Smrg 659b4ee4795Smrg/** 660b4ee4795Smrg * Add an event to the display's event list. This event must be freed on the 661b4ee4795Smrg * next call to XNextEvent(). 662b4ee4795Smrg */ 663b4ee4795Smrgvoid 664b4ee4795Smrg_XStoreEventCookie(Display *dpy, XEvent *event) 665b4ee4795Smrg{ 666b4ee4795Smrg XGenericEventCookie* cookie = &event->xcookie; 667b4ee4795Smrg struct stored_event **head, *add; 668b4ee4795Smrg 669b4ee4795Smrg if (!_XIsEventCookie(dpy, event)) 670b4ee4795Smrg return; 671b4ee4795Smrg 672b4ee4795Smrg head = (struct stored_event**)(&dpy->cookiejar); 673b4ee4795Smrg 674b4ee4795Smrg add = Xmalloc(sizeof(struct stored_event)); 675b4ee4795Smrg if (!add) { 676b4ee4795Smrg ESET(ENOMEM); 677b4ee4795Smrg _XIOError(dpy); 67815c3e985Smrg return; 679b4ee4795Smrg } 680b4ee4795Smrg add->ev = *cookie; 681b4ee4795Smrg DL_APPEND(*head, add); 682b4ee4795Smrg cookie->data = NULL; /* don't return data yet, must be claimed */ 683b4ee4795Smrg} 684b4ee4795Smrg 685b4ee4795Smrg/** 686b4ee4795Smrg * Return the event with the given cookie and remove it from the list. 687b4ee4795Smrg */ 688b4ee4795SmrgBool 689b4ee4795Smrg_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev) 690b4ee4795Smrg{ 691b4ee4795Smrg Bool ret = False; 692b4ee4795Smrg struct stored_event **head, *event; 693b4ee4795Smrg head = (struct stored_event**)&dpy->cookiejar; 694b4ee4795Smrg 695b4ee4795Smrg if (!_XIsEventCookie(dpy, (XEvent*)ev)) 696b4ee4795Smrg return ret; 697b4ee4795Smrg 698b4ee4795Smrg DL_FOREACH(*head, event) { 699b4ee4795Smrg if (event->ev.cookie == ev->cookie && 700b4ee4795Smrg event->ev.extension == ev->extension && 701b4ee4795Smrg event->ev.evtype == ev->evtype) { 702b4ee4795Smrg *ev = event->ev; 703b4ee4795Smrg DL_DELETE(*head, event); 704b4ee4795Smrg Xfree(event); 705b4ee4795Smrg ret = True; 706b4ee4795Smrg break; 707b4ee4795Smrg } 708b4ee4795Smrg } 709b4ee4795Smrg 710b4ee4795Smrg return ret; 711b4ee4795Smrg} 712b4ee4795Smrg 713b4ee4795SmrgBool 714b4ee4795Smrg_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out) 715b4ee4795Smrg{ 716b4ee4795Smrg Bool ret = False; 717b4ee4795Smrg int extension; 718b4ee4795Smrg 719b4ee4795Smrg if (!_XIsEventCookie(dpy, (XEvent*)in) || !out) 720b4ee4795Smrg return ret; 721b4ee4795Smrg 722b4ee4795Smrg extension = in->extension & 0x7F; 723b4ee4795Smrg 724b4ee4795Smrg if (!dpy->generic_event_copy_vec[extension]) 725b4ee4795Smrg return ret; 726b4ee4795Smrg 727b4ee4795Smrg ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out)); 728b4ee4795Smrg out->cookie = ret ? ++dpy->next_cookie : 0; 729b4ee4795Smrg return ret; 730b4ee4795Smrg} 731b4ee4795Smrg 7321ab64890Smrg 7331ab64890Smrg/* 7341ab64890Smrg * _XEnq - Place event packets on the display's queue. 7351ab64890Smrg * note that no squishing of move events in V11, since there 7361ab64890Smrg * is pointer motion hints.... 7371ab64890Smrg */ 7381ab64890Smrgvoid _XEnq( 7391ab64890Smrg register Display *dpy, 7401ab64890Smrg register xEvent *event) 7411ab64890Smrg{ 7421ab64890Smrg register _XQEvent *qelt; 743b4ee4795Smrg int type, extension; 7441ab64890Smrg 7451ab64890Smrg if ((qelt = dpy->qfree)) { 7461ab64890Smrg /* If dpy->qfree is non-NULL do this, else malloc a new one. */ 7471ab64890Smrg dpy->qfree = qelt->next; 7481ab64890Smrg } 749556b6652Smrg else if ((qelt = Xmalloc(sizeof(_XQEvent))) == NULL) { 7501ab64890Smrg /* Malloc call failed! */ 7511ab64890Smrg ESET(ENOMEM); 7521ab64890Smrg _XIOError(dpy); 75315c3e985Smrg return; 7541ab64890Smrg } 7551ab64890Smrg qelt->next = NULL; 756b4ee4795Smrg 757b4ee4795Smrg type = event->u.u.type & 0177; 758b4ee4795Smrg extension = ((xGenericEvent*)event)->extension; 759295fb823Smrg 760295fb823Smrg qelt->event.type = type; 761556b6652Smrg /* If an extension has registered a generic_event_vec handler, then 762b4ee4795Smrg * it can handle event cookies. Otherwise, proceed with the normal 763b4ee4795Smrg * event handlers. 764b4ee4795Smrg * 765b4ee4795Smrg * If the generic_event_vec is called, qelt->event is a event cookie 766b4ee4795Smrg * with the data pointer and the "free" pointer set. Data pointer is 767b4ee4795Smrg * some memory allocated by the extension. 768b4ee4795Smrg */ 769b4ee4795Smrg if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) { 770b4ee4795Smrg XGenericEventCookie *cookie = &qelt->event.xcookie; 771b4ee4795Smrg (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event); 772b4ee4795Smrg cookie->cookie = ++dpy->next_cookie; 773b4ee4795Smrg 774b4ee4795Smrg qelt->qserial_num = dpy->next_event_serial_num++; 775b4ee4795Smrg if (dpy->tail) dpy->tail->next = qelt; 776b4ee4795Smrg else dpy->head = qelt; 777b4ee4795Smrg 778b4ee4795Smrg dpy->tail = qelt; 779b4ee4795Smrg dpy->qlen++; 780b4ee4795Smrg } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) { 7811ab64890Smrg qelt->qserial_num = dpy->next_event_serial_num++; 7821ab64890Smrg if (dpy->tail) dpy->tail->next = qelt; 7831ab64890Smrg else dpy->head = qelt; 78461b2299dSmrg 7851ab64890Smrg dpy->tail = qelt; 7861ab64890Smrg dpy->qlen++; 7871ab64890Smrg } else { 7881ab64890Smrg /* ignored, or stashed away for many-to-one compression */ 7891ab64890Smrg qelt->next = dpy->qfree; 7901ab64890Smrg dpy->qfree = qelt; 7911ab64890Smrg } 7921ab64890Smrg} 7931ab64890Smrg 7941ab64890Smrg/* 7951ab64890Smrg * _XDeq - Remove event packet from the display's queue. 7961ab64890Smrg */ 7971ab64890Smrgvoid _XDeq( 7981ab64890Smrg register Display *dpy, 7991ab64890Smrg register _XQEvent *prev, /* element before qelt */ 8001ab64890Smrg register _XQEvent *qelt) /* element to be unlinked */ 8011ab64890Smrg{ 8021ab64890Smrg if (prev) { 8031ab64890Smrg if ((prev->next = qelt->next) == NULL) 8041ab64890Smrg dpy->tail = prev; 8051ab64890Smrg } else { 8061ab64890Smrg /* no prev, so removing first elt */ 8071ab64890Smrg if ((dpy->head = qelt->next) == NULL) 8081ab64890Smrg dpy->tail = NULL; 8091ab64890Smrg } 8101ab64890Smrg qelt->qserial_num = 0; 8111ab64890Smrg qelt->next = dpy->qfree; 8121ab64890Smrg dpy->qfree = qelt; 8131ab64890Smrg dpy->qlen--; 814b4ee4795Smrg 815b4ee4795Smrg if (_XIsEventCookie(dpy, &qelt->event)) { 816b4ee4795Smrg XGenericEventCookie* cookie = &qelt->event.xcookie; 817b4ee4795Smrg /* dpy->qfree is re-used, reset memory to avoid double free on 818b4ee4795Smrg * _XFreeDisplayStructure */ 819b4ee4795Smrg cookie->data = NULL; 820b4ee4795Smrg } 8211ab64890Smrg} 8221ab64890Smrg 8231ab64890Smrg/* 8241ab64890Smrg * EventToWire in separate file in that often not needed. 8251ab64890Smrg */ 8261ab64890Smrg 8271ab64890Smrg/*ARGSUSED*/ 8281ab64890SmrgBool 8291ab64890Smrg_XUnknownWireEvent( 8301ab64890Smrg register Display *dpy, /* pointer to display structure */ 8311ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 8321ab64890Smrg register xEvent *event) /* wire protocol event */ 8331ab64890Smrg{ 8341ab64890Smrg#ifdef notdef 83561b2299dSmrg (void) fprintf(stderr, 8361ab64890Smrg "Xlib: unhandled wire event! event number = %d, display = %x\n.", 8371ab64890Smrg event->u.u.type, dpy); 8381ab64890Smrg#endif 8391ab64890Smrg return(False); 8401ab64890Smrg} 8411ab64890Smrg 842b4ee4795SmrgBool 843b4ee4795Smrg_XUnknownWireEventCookie( 844b4ee4795Smrg Display *dpy, /* pointer to display structure */ 845b4ee4795Smrg XGenericEventCookie *re, /* pointer to where event should be reformatted */ 846b4ee4795Smrg xEvent *event) /* wire protocol event */ 847b4ee4795Smrg{ 848b4ee4795Smrg#ifdef notdef 849b4ee4795Smrg fprintf(stderr, 850b4ee4795Smrg "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.", 851b4ee4795Smrg ((xGenericEvent*)event)->extension, dpy); 852b4ee4795Smrg#endif 853b4ee4795Smrg return(False); 854b4ee4795Smrg} 855b4ee4795Smrg 856b4ee4795SmrgBool 857b4ee4795Smrg_XUnknownCopyEventCookie( 858b4ee4795Smrg Display *dpy, /* pointer to display structure */ 859b4ee4795Smrg XGenericEventCookie *in, /* source */ 860b4ee4795Smrg XGenericEventCookie *out) /* destination */ 861b4ee4795Smrg{ 862b4ee4795Smrg#ifdef notdef 863b4ee4795Smrg fprintf(stderr, 864b4ee4795Smrg "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.", 865b4ee4795Smrg in->extension, dpy); 866b4ee4795Smrg#endif 867b4ee4795Smrg return(False); 868b4ee4795Smrg} 869b4ee4795Smrg 8701ab64890Smrg/*ARGSUSED*/ 8711ab64890SmrgStatus 8721ab64890Smrg_XUnknownNativeEvent( 8731ab64890Smrg register Display *dpy, /* pointer to display structure */ 8741ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 8751ab64890Smrg register xEvent *event) /* wire protocol event */ 8761ab64890Smrg{ 8771ab64890Smrg#ifdef notdef 87861b2299dSmrg (void) fprintf(stderr, 8791ab64890Smrg "Xlib: unhandled native event! event number = %d, display = %x\n.", 8801ab64890Smrg re->type, dpy); 8811ab64890Smrg#endif 8821ab64890Smrg return(0); 8831ab64890Smrg} 8841ab64890Smrg/* 8851ab64890Smrg * reformat a wire event into an XEvent structure of the right type. 8861ab64890Smrg */ 8871ab64890SmrgBool 8881ab64890Smrg_XWireToEvent( 8891ab64890Smrg register Display *dpy, /* pointer to display structure */ 8901ab64890Smrg register XEvent *re, /* pointer to where event should be reformatted */ 8911ab64890Smrg register xEvent *event) /* wire protocol event */ 8921ab64890Smrg{ 8931ab64890Smrg 8941ab64890Smrg re->type = event->u.u.type & 0x7f; 8951ab64890Smrg ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy, 8961ab64890Smrg (xGenericReply *)event); 8971ab64890Smrg ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0); 8981ab64890Smrg ((XAnyEvent *)re)->display = dpy; 89961b2299dSmrg 9001ab64890Smrg /* Ignore the leading bit of the event type since it is set when a 9011ab64890Smrg client sends an event rather than the server. */ 9021ab64890Smrg 9031ab64890Smrg switch (event-> u.u.type & 0177) { 9041ab64890Smrg case KeyPress: 9051ab64890Smrg case KeyRelease: 9061ab64890Smrg { 9071ab64890Smrg register XKeyEvent *ev = (XKeyEvent*) re; 9081ab64890Smrg ev->root = event->u.keyButtonPointer.root; 9091ab64890Smrg ev->window = event->u.keyButtonPointer.event; 9101ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 9111ab64890Smrg ev->time = event->u.keyButtonPointer.time; 9121ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 9131ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 9141ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 9151ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 9161ab64890Smrg ev->state = event->u.keyButtonPointer.state; 9171ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 9181ab64890Smrg ev->keycode = event->u.u.detail; 9191ab64890Smrg } 9201ab64890Smrg break; 9211ab64890Smrg case ButtonPress: 9221ab64890Smrg case ButtonRelease: 9231ab64890Smrg { 9241ab64890Smrg register XButtonEvent *ev = (XButtonEvent *) re; 9251ab64890Smrg ev->root = event->u.keyButtonPointer.root; 9261ab64890Smrg ev->window = event->u.keyButtonPointer.event; 9271ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 9281ab64890Smrg ev->time = event->u.keyButtonPointer.time; 9291ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 9301ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 9311ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 9321ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 9331ab64890Smrg ev->state = event->u.keyButtonPointer.state; 9341ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 9351ab64890Smrg ev->button = event->u.u.detail; 9361ab64890Smrg } 9371ab64890Smrg break; 9381ab64890Smrg case MotionNotify: 9391ab64890Smrg { 9401ab64890Smrg register XMotionEvent *ev = (XMotionEvent *)re; 9411ab64890Smrg ev->root = event->u.keyButtonPointer.root; 9421ab64890Smrg ev->window = event->u.keyButtonPointer.event; 9431ab64890Smrg ev->subwindow = event->u.keyButtonPointer.child; 9441ab64890Smrg ev->time = event->u.keyButtonPointer.time; 9451ab64890Smrg ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); 9461ab64890Smrg ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); 9471ab64890Smrg ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); 9481ab64890Smrg ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); 9491ab64890Smrg ev->state = event->u.keyButtonPointer.state; 9501ab64890Smrg ev->same_screen = event->u.keyButtonPointer.sameScreen; 9511ab64890Smrg ev->is_hint = event->u.u.detail; 9521ab64890Smrg } 9531ab64890Smrg break; 9541ab64890Smrg case EnterNotify: 9551ab64890Smrg case LeaveNotify: 9561ab64890Smrg { 9571ab64890Smrg register XCrossingEvent *ev = (XCrossingEvent *) re; 9581ab64890Smrg ev->root = event->u.enterLeave.root; 9591ab64890Smrg ev->window = event->u.enterLeave.event; 9601ab64890Smrg ev->subwindow = event->u.enterLeave.child; 9611ab64890Smrg ev->time = event->u.enterLeave.time; 9621ab64890Smrg ev->x = cvtINT16toInt(event->u.enterLeave.eventX); 9631ab64890Smrg ev->y = cvtINT16toInt(event->u.enterLeave.eventY); 9641ab64890Smrg ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX); 9651ab64890Smrg ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY); 9661ab64890Smrg ev->state = event->u.enterLeave.state; 9671ab64890Smrg ev->mode = event->u.enterLeave.mode; 96861b2299dSmrg ev->same_screen = (event->u.enterLeave.flags & 9691ab64890Smrg ELFlagSameScreen) && True; 9701ab64890Smrg ev->focus = (event->u.enterLeave.flags & 9711ab64890Smrg ELFlagFocus) && True; 9721ab64890Smrg ev->detail = event->u.u.detail; 9731ab64890Smrg } 9741ab64890Smrg break; 9751ab64890Smrg case FocusIn: 9761ab64890Smrg case FocusOut: 9771ab64890Smrg { 9781ab64890Smrg register XFocusChangeEvent *ev = (XFocusChangeEvent *) re; 9791ab64890Smrg ev->window = event->u.focus.window; 9801ab64890Smrg ev->mode = event->u.focus.mode; 9811ab64890Smrg ev->detail = event->u.u.detail; 9821ab64890Smrg } 9831ab64890Smrg break; 9841ab64890Smrg case KeymapNotify: 9851ab64890Smrg { 9861ab64890Smrg register XKeymapEvent *ev = (XKeymapEvent *) re; 9871ab64890Smrg ev->window = None; 9881ab64890Smrg memcpy(&ev->key_vector[1], 9891ab64890Smrg (char *)((xKeymapEvent *) event)->map, 9901ab64890Smrg sizeof (((xKeymapEvent *) event)->map)); 9911ab64890Smrg } 9921ab64890Smrg break; 9931ab64890Smrg case Expose: 9941ab64890Smrg { 9951ab64890Smrg register XExposeEvent *ev = (XExposeEvent *) re; 9961ab64890Smrg ev->window = event->u.expose.window; 9971ab64890Smrg ev->x = event->u.expose.x; 9981ab64890Smrg ev->y = event->u.expose.y; 9991ab64890Smrg ev->width = event->u.expose.width; 10001ab64890Smrg ev->height = event->u.expose.height; 10011ab64890Smrg ev->count = event->u.expose.count; 10021ab64890Smrg } 10031ab64890Smrg break; 10041ab64890Smrg case GraphicsExpose: 10051ab64890Smrg { 10061ab64890Smrg register XGraphicsExposeEvent *ev = 10071ab64890Smrg (XGraphicsExposeEvent *) re; 10081ab64890Smrg ev->drawable = event->u.graphicsExposure.drawable; 10091ab64890Smrg ev->x = event->u.graphicsExposure.x; 10101ab64890Smrg ev->y = event->u.graphicsExposure.y; 10111ab64890Smrg ev->width = event->u.graphicsExposure.width; 10121ab64890Smrg ev->height = event->u.graphicsExposure.height; 10131ab64890Smrg ev->count = event->u.graphicsExposure.count; 10141ab64890Smrg ev->major_code = event->u.graphicsExposure.majorEvent; 10151ab64890Smrg ev->minor_code = event->u.graphicsExposure.minorEvent; 10161ab64890Smrg } 10171ab64890Smrg break; 10181ab64890Smrg case NoExpose: 10191ab64890Smrg { 10201ab64890Smrg register XNoExposeEvent *ev = (XNoExposeEvent *) re; 10211ab64890Smrg ev->drawable = event->u.noExposure.drawable; 10221ab64890Smrg ev->major_code = event->u.noExposure.majorEvent; 10231ab64890Smrg ev->minor_code = event->u.noExposure.minorEvent; 10241ab64890Smrg } 10251ab64890Smrg break; 10261ab64890Smrg case VisibilityNotify: 10271ab64890Smrg { 10281ab64890Smrg register XVisibilityEvent *ev = (XVisibilityEvent *) re; 10291ab64890Smrg ev->window = event->u.visibility.window; 10301ab64890Smrg ev->state = event->u.visibility.state; 10311ab64890Smrg } 10321ab64890Smrg break; 10331ab64890Smrg case CreateNotify: 10341ab64890Smrg { 10351ab64890Smrg register XCreateWindowEvent *ev = 10361ab64890Smrg (XCreateWindowEvent *) re; 10371ab64890Smrg ev->window = event->u.createNotify.window; 10381ab64890Smrg ev->parent = event->u.createNotify.parent; 10391ab64890Smrg ev->x = cvtINT16toInt(event->u.createNotify.x); 10401ab64890Smrg ev->y = cvtINT16toInt(event->u.createNotify.y); 10411ab64890Smrg ev->width = event->u.createNotify.width; 10421ab64890Smrg ev->height = event->u.createNotify.height; 10431ab64890Smrg ev->border_width = event->u.createNotify.borderWidth; 10441ab64890Smrg ev->override_redirect = event->u.createNotify.override; 10451ab64890Smrg } 10461ab64890Smrg break; 10471ab64890Smrg case DestroyNotify: 10481ab64890Smrg { 10491ab64890Smrg register XDestroyWindowEvent *ev = 10501ab64890Smrg (XDestroyWindowEvent *) re; 10511ab64890Smrg ev->window = event->u.destroyNotify.window; 10521ab64890Smrg ev->event = event->u.destroyNotify.event; 10531ab64890Smrg } 10541ab64890Smrg break; 10551ab64890Smrg case UnmapNotify: 10561ab64890Smrg { 10571ab64890Smrg register XUnmapEvent *ev = (XUnmapEvent *) re; 10581ab64890Smrg ev->window = event->u.unmapNotify.window; 10591ab64890Smrg ev->event = event->u.unmapNotify.event; 10601ab64890Smrg ev->from_configure = event->u.unmapNotify.fromConfigure; 10611ab64890Smrg } 10621ab64890Smrg break; 10631ab64890Smrg case MapNotify: 10641ab64890Smrg { 10651ab64890Smrg register XMapEvent *ev = (XMapEvent *) re; 10661ab64890Smrg ev->window = event->u.mapNotify.window; 10671ab64890Smrg ev->event = event->u.mapNotify.event; 10681ab64890Smrg ev->override_redirect = event->u.mapNotify.override; 10691ab64890Smrg } 10701ab64890Smrg break; 10711ab64890Smrg case MapRequest: 10721ab64890Smrg { 10731ab64890Smrg register XMapRequestEvent *ev = (XMapRequestEvent *) re; 10741ab64890Smrg ev->window = event->u.mapRequest.window; 10751ab64890Smrg ev->parent = event->u.mapRequest.parent; 10761ab64890Smrg } 10771ab64890Smrg break; 10781ab64890Smrg case ReparentNotify: 10791ab64890Smrg { 10801ab64890Smrg register XReparentEvent *ev = (XReparentEvent *) re; 10811ab64890Smrg ev->event = event->u.reparent.event; 10821ab64890Smrg ev->window = event->u.reparent.window; 10831ab64890Smrg ev->parent = event->u.reparent.parent; 10841ab64890Smrg ev->x = cvtINT16toInt(event->u.reparent.x); 10851ab64890Smrg ev->y = cvtINT16toInt(event->u.reparent.y); 10861ab64890Smrg ev->override_redirect = event->u.reparent.override; 10871ab64890Smrg } 10881ab64890Smrg break; 10891ab64890Smrg case ConfigureNotify: 10901ab64890Smrg { 10911ab64890Smrg register XConfigureEvent *ev = (XConfigureEvent *) re; 10921ab64890Smrg ev->event = event->u.configureNotify.event; 10931ab64890Smrg ev->window = event->u.configureNotify.window; 10941ab64890Smrg ev->above = event->u.configureNotify.aboveSibling; 10951ab64890Smrg ev->x = cvtINT16toInt(event->u.configureNotify.x); 10961ab64890Smrg ev->y = cvtINT16toInt(event->u.configureNotify.y); 10971ab64890Smrg ev->width = event->u.configureNotify.width; 10981ab64890Smrg ev->height = event->u.configureNotify.height; 10991ab64890Smrg ev->border_width = event->u.configureNotify.borderWidth; 11001ab64890Smrg ev->override_redirect = event->u.configureNotify.override; 11011ab64890Smrg } 11021ab64890Smrg break; 11031ab64890Smrg case ConfigureRequest: 11041ab64890Smrg { 11051ab64890Smrg register XConfigureRequestEvent *ev = 11061ab64890Smrg (XConfigureRequestEvent *) re; 11071ab64890Smrg ev->window = event->u.configureRequest.window; 11081ab64890Smrg ev->parent = event->u.configureRequest.parent; 11091ab64890Smrg ev->above = event->u.configureRequest.sibling; 11101ab64890Smrg ev->x = cvtINT16toInt(event->u.configureRequest.x); 11111ab64890Smrg ev->y = cvtINT16toInt(event->u.configureRequest.y); 11121ab64890Smrg ev->width = event->u.configureRequest.width; 11131ab64890Smrg ev->height = event->u.configureRequest.height; 11141ab64890Smrg ev->border_width = event->u.configureRequest.borderWidth; 11151ab64890Smrg ev->value_mask = event->u.configureRequest.valueMask; 11161ab64890Smrg ev->detail = event->u.u.detail; 11171ab64890Smrg } 11181ab64890Smrg break; 11191ab64890Smrg case GravityNotify: 11201ab64890Smrg { 11211ab64890Smrg register XGravityEvent *ev = (XGravityEvent *) re; 11221ab64890Smrg ev->window = event->u.gravity.window; 11231ab64890Smrg ev->event = event->u.gravity.event; 11241ab64890Smrg ev->x = cvtINT16toInt(event->u.gravity.x); 11251ab64890Smrg ev->y = cvtINT16toInt(event->u.gravity.y); 11261ab64890Smrg } 11271ab64890Smrg break; 11281ab64890Smrg case ResizeRequest: 11291ab64890Smrg { 11301ab64890Smrg register XResizeRequestEvent *ev = 11311ab64890Smrg (XResizeRequestEvent *) re; 11321ab64890Smrg ev->window = event->u.resizeRequest.window; 11331ab64890Smrg ev->width = event->u.resizeRequest.width; 11341ab64890Smrg ev->height = event->u.resizeRequest.height; 11351ab64890Smrg } 11361ab64890Smrg break; 11371ab64890Smrg case CirculateNotify: 11381ab64890Smrg { 11391ab64890Smrg register XCirculateEvent *ev = (XCirculateEvent *) re; 11401ab64890Smrg ev->window = event->u.circulate.window; 11411ab64890Smrg ev->event = event->u.circulate.event; 11421ab64890Smrg ev->place = event->u.circulate.place; 11431ab64890Smrg } 11441ab64890Smrg break; 11451ab64890Smrg case CirculateRequest: 11461ab64890Smrg { 11471ab64890Smrg register XCirculateRequestEvent *ev = 11481ab64890Smrg (XCirculateRequestEvent *) re; 11491ab64890Smrg ev->window = event->u.circulate.window; 11501ab64890Smrg ev->parent = event->u.circulate.event; 11511ab64890Smrg ev->place = event->u.circulate.place; 11521ab64890Smrg } 11531ab64890Smrg break; 11541ab64890Smrg case PropertyNotify: 11551ab64890Smrg { 11561ab64890Smrg register XPropertyEvent *ev = (XPropertyEvent *) re; 11571ab64890Smrg ev->window = event->u.property.window; 11581ab64890Smrg ev->atom = event->u.property.atom; 11591ab64890Smrg ev->time = event->u.property.time; 11601ab64890Smrg ev->state = event->u.property.state; 11611ab64890Smrg } 11621ab64890Smrg break; 11631ab64890Smrg case SelectionClear: 11641ab64890Smrg { 11651ab64890Smrg register XSelectionClearEvent *ev = 11661ab64890Smrg (XSelectionClearEvent *) re; 11671ab64890Smrg ev->window = event->u.selectionClear.window; 11681ab64890Smrg ev->selection = event->u.selectionClear.atom; 11691ab64890Smrg ev->time = event->u.selectionClear.time; 11701ab64890Smrg } 11711ab64890Smrg break; 11721ab64890Smrg case SelectionRequest: 11731ab64890Smrg { 11741ab64890Smrg register XSelectionRequestEvent *ev = 11751ab64890Smrg (XSelectionRequestEvent *) re; 11761ab64890Smrg ev->owner = event->u.selectionRequest.owner; 11771ab64890Smrg ev->requestor = event->u.selectionRequest.requestor; 11781ab64890Smrg ev->selection = event->u.selectionRequest.selection; 11791ab64890Smrg ev->target = event->u.selectionRequest.target; 11801ab64890Smrg ev->property = event->u.selectionRequest.property; 11811ab64890Smrg ev->time = event->u.selectionRequest.time; 11821ab64890Smrg } 11831ab64890Smrg break; 11841ab64890Smrg case SelectionNotify: 11851ab64890Smrg { 11861ab64890Smrg register XSelectionEvent *ev = (XSelectionEvent *) re; 11871ab64890Smrg ev->requestor = event->u.selectionNotify.requestor; 11881ab64890Smrg ev->selection = event->u.selectionNotify.selection; 11891ab64890Smrg ev->target = event->u.selectionNotify.target; 11901ab64890Smrg ev->property = event->u.selectionNotify.property; 11911ab64890Smrg ev->time = event->u.selectionNotify.time; 11921ab64890Smrg } 11931ab64890Smrg break; 11941ab64890Smrg case ColormapNotify: 11951ab64890Smrg { 11961ab64890Smrg register XColormapEvent *ev = (XColormapEvent *) re; 11971ab64890Smrg ev->window = event->u.colormap.window; 11981ab64890Smrg ev->colormap = event->u.colormap.colormap; 11991ab64890Smrg ev->new = event->u.colormap.new; 12001ab64890Smrg ev->state = event->u.colormap.state; 12011ab64890Smrg } 12021ab64890Smrg break; 12031ab64890Smrg case ClientMessage: 12041ab64890Smrg { 12051ab64890Smrg register int i; 120661b2299dSmrg register XClientMessageEvent *ev 12071ab64890Smrg = (XClientMessageEvent *) re; 12081ab64890Smrg ev->window = event->u.clientMessage.window; 12091ab64890Smrg ev->format = event->u.u.detail; 12101ab64890Smrg switch (ev->format) { 121161b2299dSmrg case 8: 12121ab64890Smrg ev->message_type = event->u.clientMessage.u.b.type; 121361b2299dSmrg for (i = 0; i < 20; i++) 12141ab64890Smrg ev->data.b[i] = event->u.clientMessage.u.b.bytes[i]; 12151ab64890Smrg break; 12161ab64890Smrg case 16: 12171ab64890Smrg ev->message_type = event->u.clientMessage.u.s.type; 12181ab64890Smrg ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0); 12191ab64890Smrg ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1); 12201ab64890Smrg ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2); 12211ab64890Smrg ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3); 12221ab64890Smrg ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4); 12231ab64890Smrg ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5); 12241ab64890Smrg ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6); 12251ab64890Smrg ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7); 12261ab64890Smrg ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8); 12271ab64890Smrg ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9); 12281ab64890Smrg break; 12291ab64890Smrg case 32: 12301ab64890Smrg ev->message_type = event->u.clientMessage.u.l.type; 12311ab64890Smrg ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0); 12321ab64890Smrg ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1); 12331ab64890Smrg ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2); 12341ab64890Smrg ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3); 12351ab64890Smrg ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4); 12361ab64890Smrg break; 12371ab64890Smrg default: /* XXX should never occur */ 12381ab64890Smrg break; 12391ab64890Smrg } 12401ab64890Smrg } 12411ab64890Smrg break; 12421ab64890Smrg case MappingNotify: 12431ab64890Smrg { 12441ab64890Smrg register XMappingEvent *ev = (XMappingEvent *)re; 12451ab64890Smrg ev->window = 0; 12461ab64890Smrg ev->first_keycode = event->u.mappingNotify.firstKeyCode; 12471ab64890Smrg ev->request = event->u.mappingNotify.request; 12481ab64890Smrg ev->count = event->u.mappingNotify.count; 12491ab64890Smrg } 12501ab64890Smrg break; 12511ab64890Smrg default: 12521ab64890Smrg return(_XUnknownWireEvent(dpy, re, event)); 12531ab64890Smrg } 12541ab64890Smrg return(True); 12551ab64890Smrg} 12561ab64890Smrg 1257f2d49d05Smrgstatic int 1258f2d49d05SmrgSocketBytesReadable(Display *dpy) 1259f2d49d05Smrg{ 1260f2d49d05Smrg int bytes = 0, last_error; 1261f2d49d05Smrg#ifdef WIN32 1262f2d49d05Smrg last_error = WSAGetLastError(); 1263f2d49d05Smrg ioctlsocket(ConnectionNumber(dpy), FIONREAD, &bytes); 1264f2d49d05Smrg WSASetLastError(last_error); 1265f2d49d05Smrg#else 1266f2d49d05Smrg last_error = errno; 1267f2d49d05Smrg ioctl(ConnectionNumber(dpy), FIONREAD, &bytes); 1268f2d49d05Smrg errno = last_error; 1269f2d49d05Smrg#endif 1270f2d49d05Smrg return bytes; 1271f2d49d05Smrg} 12721ab64890Smrg 127315c3e985Smrg_X_NORETURN void _XDefaultIOErrorExit( 127415c3e985Smrg Display *dpy, 127515c3e985Smrg void *user_data) 127615c3e985Smrg{ 127715c3e985Smrg exit(1); 127815c3e985Smrg /*NOTREACHED*/ 127915c3e985Smrg} 128015c3e985Smrg 12811ab64890Smrg/* 128261b2299dSmrg * _XDefaultIOError - Default fatal system error reporting routine. Called 12831ab64890Smrg * when an X internal system error is encountered. 12841ab64890Smrg */ 1285bd8e7fb0Smrg_X_NORETURN int _XDefaultIOError( 12861ab64890Smrg Display *dpy) 12871ab64890Smrg{ 1288f2d49d05Smrg int killed = ECHECK(EPIPE); 1289f2d49d05Smrg 1290f2d49d05Smrg /* 1291f2d49d05Smrg * If the socket was closed on the far end, the final recvmsg in 1292f2d49d05Smrg * xcb will have thrown EAGAIN because we're non-blocking. Detect 1293f2d49d05Smrg * this to get the more informative error message. 1294f2d49d05Smrg */ 1295f2d49d05Smrg if (ECHECK(EAGAIN) && SocketBytesReadable(dpy) <= 0) 1296f2d49d05Smrg killed = True; 1297f2d49d05Smrg 1298f2d49d05Smrg if (killed) { 1299f2d49d05Smrg fprintf (stderr, 1300f2d49d05Smrg "X connection to %s broken (explicit kill or server shutdown).\r\n", 1301f2d49d05Smrg DisplayString (dpy)); 13021ab64890Smrg } else { 1303f2d49d05Smrg fprintf (stderr, 1304f2d49d05Smrg "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n", 13051ab64890Smrg#ifdef WIN32 1306f2d49d05Smrg WSAGetLastError(), strerror(WSAGetLastError()), 13071ab64890Smrg#else 1308f2d49d05Smrg errno, strerror (errno), 13091ab64890Smrg#endif 1310f2d49d05Smrg DisplayString (dpy)); 1311f2d49d05Smrg fprintf (stderr, 1312f2d49d05Smrg " after %lu requests (%lu known processed) with %d events remaining.\r\n", 1313f2d49d05Smrg NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy), 1314f2d49d05Smrg QLength(dpy)); 1315f2d49d05Smrg } 13161ab64890Smrg 13171ab64890Smrg exit(1); 1318dac667f7Smrg /*NOTREACHED*/ 13191ab64890Smrg} 13201ab64890Smrg 13211ab64890Smrg 13221ab64890Smrgstatic int _XPrintDefaultError( 13231ab64890Smrg Display *dpy, 13241ab64890Smrg XErrorEvent *event, 13251ab64890Smrg FILE *fp) 13261ab64890Smrg{ 13271ab64890Smrg char buffer[BUFSIZ]; 13281ab64890Smrg char mesg[BUFSIZ]; 13291ab64890Smrg char number[32]; 13301ab64890Smrg const char *mtype = "XlibMessage"; 13311ab64890Smrg register _XExtension *ext = (_XExtension *)NULL; 13321ab64890Smrg _XExtension *bext = (_XExtension *)NULL; 13331ab64890Smrg XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); 13341ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); 13351ab64890Smrg (void) fprintf(fp, "%s: %s\n ", mesg, buffer); 133661b2299dSmrg XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", 13371ab64890Smrg mesg, BUFSIZ); 13381ab64890Smrg (void) fprintf(fp, mesg, event->request_code); 13391ab64890Smrg if (event->request_code < 128) { 1340556b6652Smrg snprintf(number, sizeof(number), "%d", event->request_code); 13411ab64890Smrg XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); 13421ab64890Smrg } else { 13431ab64890Smrg for (ext = dpy->ext_procs; 13441ab64890Smrg ext && (ext->codes.major_opcode != event->request_code); 13451ab64890Smrg ext = ext->next) 13461ab64890Smrg ; 1347c17aa6b1Smrg if (ext) { 1348c17aa6b1Smrg strncpy(buffer, ext->name, BUFSIZ); 1349c17aa6b1Smrg buffer[BUFSIZ - 1] = '\0'; 1350c17aa6b1Smrg } else 13511ab64890Smrg buffer[0] = '\0'; 13521ab64890Smrg } 13531ab64890Smrg (void) fprintf(fp, " (%s)\n", buffer); 13541ab64890Smrg if (event->request_code >= 128) { 13551ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", 13561ab64890Smrg mesg, BUFSIZ); 13571ab64890Smrg fputs(" ", fp); 13581ab64890Smrg (void) fprintf(fp, mesg, event->minor_code); 13591ab64890Smrg if (ext) { 1360556b6652Smrg snprintf(mesg, sizeof(mesg), "%s.%d", ext->name, event->minor_code); 13611ab64890Smrg XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); 13621ab64890Smrg (void) fprintf(fp, " (%s)", buffer); 13631ab64890Smrg } 13641ab64890Smrg fputs("\n", fp); 13651ab64890Smrg } 13661ab64890Smrg if (event->error_code >= 128) { 13671ab64890Smrg /* kludge, try to find the extension that caused it */ 13681ab64890Smrg buffer[0] = '\0'; 13691ab64890Smrg for (ext = dpy->ext_procs; ext; ext = ext->next) { 137061b2299dSmrg if (ext->error_string) 13711ab64890Smrg (*ext->error_string)(dpy, event->error_code, &ext->codes, 13721ab64890Smrg buffer, BUFSIZ); 13731ab64890Smrg if (buffer[0]) { 13741ab64890Smrg bext = ext; 13751ab64890Smrg break; 13761ab64890Smrg } 13771ab64890Smrg if (ext->codes.first_error && 13781ab64890Smrg ext->codes.first_error < (int)event->error_code && 13791ab64890Smrg (!bext || ext->codes.first_error > bext->codes.first_error)) 13801ab64890Smrg bext = ext; 138161b2299dSmrg } 13821ab64890Smrg if (bext) 1383556b6652Smrg snprintf(buffer, sizeof(buffer), "%s.%d", bext->name, 1384556b6652Smrg event->error_code - bext->codes.first_error); 13851ab64890Smrg else 13861ab64890Smrg strcpy(buffer, "Value"); 13871ab64890Smrg XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); 13881ab64890Smrg if (mesg[0]) { 13891ab64890Smrg fputs(" ", fp); 13901ab64890Smrg (void) fprintf(fp, mesg, event->resourceid); 13911ab64890Smrg fputs("\n", fp); 13921ab64890Smrg } 13931ab64890Smrg /* let extensions try to print the values */ 13941ab64890Smrg for (ext = dpy->ext_procs; ext; ext = ext->next) { 13951ab64890Smrg if (ext->error_values) 13961ab64890Smrg (*ext->error_values)(dpy, event, fp); 13971ab64890Smrg } 13981ab64890Smrg } else if ((event->error_code == BadWindow) || 13991ab64890Smrg (event->error_code == BadPixmap) || 14001ab64890Smrg (event->error_code == BadCursor) || 14011ab64890Smrg (event->error_code == BadFont) || 14021ab64890Smrg (event->error_code == BadDrawable) || 14031ab64890Smrg (event->error_code == BadColor) || 14041ab64890Smrg (event->error_code == BadGC) || 14051ab64890Smrg (event->error_code == BadIDChoice) || 14061ab64890Smrg (event->error_code == BadValue) || 14071ab64890Smrg (event->error_code == BadAtom)) { 14081ab64890Smrg if (event->error_code == BadValue) 14091ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", 14101ab64890Smrg mesg, BUFSIZ); 14111ab64890Smrg else if (event->error_code == BadAtom) 14121ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", 14131ab64890Smrg mesg, BUFSIZ); 14141ab64890Smrg else 14151ab64890Smrg XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", 14161ab64890Smrg mesg, BUFSIZ); 14171ab64890Smrg fputs(" ", fp); 14181ab64890Smrg (void) fprintf(fp, mesg, event->resourceid); 14191ab64890Smrg fputs("\n", fp); 14201ab64890Smrg } 142161b2299dSmrg XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", 14221ab64890Smrg mesg, BUFSIZ); 14231ab64890Smrg fputs(" ", fp); 14241ab64890Smrg (void) fprintf(fp, mesg, event->serial); 1425dac667f7Smrg XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%lld", 14261ab64890Smrg mesg, BUFSIZ); 14271ab64890Smrg fputs("\n ", fp); 1428dac667f7Smrg (void) fprintf(fp, mesg, (unsigned long long)(X_DPY_GET_REQUEST(dpy))); 14291ab64890Smrg fputs("\n", fp); 14301ab64890Smrg if (event->error_code == BadImplementation) return 0; 14311ab64890Smrg return 1; 14321ab64890Smrg} 14331ab64890Smrg 14341ab64890Smrgint _XDefaultError( 14351ab64890Smrg Display *dpy, 14361ab64890Smrg XErrorEvent *event) 14371ab64890Smrg{ 14381ab64890Smrg if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0; 1439bd8e7fb0Smrg 1440bd8e7fb0Smrg /* 1441bd8e7fb0Smrg * Store in dpy flags that the client is exiting on an unhandled XError 1442bd8e7fb0Smrg * (pretend it is an IOError, since the application is dying anyway it 1443bd8e7fb0Smrg * does not make a difference). 1444bd8e7fb0Smrg * This is useful for _XReply not to hang if the application makes Xlib 1445bd8e7fb0Smrg * calls in _fini as part of process termination. 1446bd8e7fb0Smrg */ 1447bd8e7fb0Smrg dpy->flags |= XlibDisplayIOError; 1448bd8e7fb0Smrg 14491ab64890Smrg exit(1); 14501ab64890Smrg /*NOTREACHED*/ 14511ab64890Smrg} 14521ab64890Smrg 14531ab64890Smrg/*ARGSUSED*/ 145461b2299dSmrgBool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we) 14551ab64890Smrg{ 14561ab64890Smrg return True; 14571ab64890Smrg} 14581ab64890Smrg 14591ab64890Smrg/* 14601ab64890Smrg * _XError - upcall internal or user protocol error handler 14611ab64890Smrg */ 14621ab64890Smrgint _XError ( 14631ab64890Smrg Display *dpy, 14641ab64890Smrg register xError *rep) 14651ab64890Smrg{ 146661b2299dSmrg /* 14671ab64890Smrg * X_Error packet encountered! We need to unpack the error before 14681ab64890Smrg * giving it to the user. 14691ab64890Smrg */ 14701ab64890Smrg XEvent event; /* make it a large event */ 14711ab64890Smrg register _XAsyncHandler *async, *next; 14721ab64890Smrg 14731ab64890Smrg event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep); 14741ab64890Smrg 14751ab64890Smrg for (async = dpy->async_handlers; async; async = next) { 14761ab64890Smrg next = async->next; 14771ab64890Smrg if ((*async->handler)(dpy, (xReply *)rep, 14781ab64890Smrg (char *)rep, SIZEOF(xError), async->data)) 14791ab64890Smrg return 0; 14801ab64890Smrg } 14811ab64890Smrg 14821ab64890Smrg event.xerror.display = dpy; 14831ab64890Smrg event.xerror.type = X_Error; 14841ab64890Smrg event.xerror.resourceid = rep->resourceID; 14851ab64890Smrg event.xerror.error_code = rep->errorCode; 14861ab64890Smrg event.xerror.request_code = rep->majorCode; 14871ab64890Smrg event.xerror.minor_code = rep->minorCode; 14881ab64890Smrg if (dpy->error_vec && 14891ab64890Smrg !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep)) 14901ab64890Smrg return 0; 14911ab64890Smrg if (_XErrorFunction != NULL) { 1492c17aa6b1Smrg int rtn_val; 1493c17aa6b1Smrg#ifdef XTHREADS 149415c3e985Smrg struct _XErrorThreadInfo thread_info = { 149515c3e985Smrg .error_thread = xthread_self(), 149615c3e985Smrg .next = dpy->error_threads 149715c3e985Smrg }, **prev; 149815c3e985Smrg dpy->error_threads = &thread_info; 1499c17aa6b1Smrg if (dpy->lock) 1500c17aa6b1Smrg (*dpy->lock->user_lock_display)(dpy); 1501c17aa6b1Smrg UnlockDisplay(dpy); 1502c17aa6b1Smrg#endif 1503c17aa6b1Smrg rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ 1504c17aa6b1Smrg#ifdef XTHREADS 1505c17aa6b1Smrg LockDisplay(dpy); 1506c17aa6b1Smrg if (dpy->lock) 1507c17aa6b1Smrg (*dpy->lock->user_unlock_display)(dpy); 150815c3e985Smrg 150915c3e985Smrg /* unlink thread_info from the list */ 151015c3e985Smrg for (prev = &dpy->error_threads; *prev != &thread_info; prev = &(*prev)->next) 151115c3e985Smrg ; 151215c3e985Smrg *prev = thread_info.next; 1513c17aa6b1Smrg#endif 1514c17aa6b1Smrg return rtn_val; 15151ab64890Smrg } else { 15161ab64890Smrg return _XDefaultError(dpy, (XErrorEvent *)&event); 15171ab64890Smrg } 15181ab64890Smrg} 151961b2299dSmrg 15201ab64890Smrg/* 15211ab64890Smrg * _XIOError - call user connection error handler and exit 15221ab64890Smrg */ 15231ab64890Smrgint 15241ab64890Smrg_XIOError ( 15251ab64890Smrg Display *dpy) 15261ab64890Smrg{ 152715c3e985Smrg XIOErrorExitHandler exit_handler; 152815c3e985Smrg void *exit_handler_data; 152915c3e985Smrg 15301ab64890Smrg dpy->flags |= XlibDisplayIOError; 15311ab64890Smrg#ifdef WIN32 15321ab64890Smrg errno = WSAGetLastError(); 15331ab64890Smrg#endif 15341ab64890Smrg 15351ab64890Smrg /* This assumes that the thread calling exit will call any atexit handlers. 15361ab64890Smrg * If this does not hold, then an alternate solution would involve 15371ab64890Smrg * registering an atexit handler to take over the lock, which would only 15381ab64890Smrg * assume that the same thread calls all the atexit handlers. */ 15391ab64890Smrg#ifdef XTHREADS 15401ab64890Smrg if (dpy->lock) 15411ab64890Smrg (*dpy->lock->user_lock_display)(dpy); 15421ab64890Smrg#endif 154315c3e985Smrg exit_handler = dpy->exit_handler; 154415c3e985Smrg exit_handler_data = dpy->exit_handler_data; 15451ab64890Smrg UnlockDisplay(dpy); 15461ab64890Smrg 15471ab64890Smrg if (_XIOErrorFunction != NULL) 15481ab64890Smrg (*_XIOErrorFunction)(dpy); 15491ab64890Smrg else 15501ab64890Smrg _XDefaultIOError(dpy); 155115c3e985Smrg 155215c3e985Smrg exit_handler(dpy, exit_handler_data); 155315c3e985Smrg return 1; 15541ab64890Smrg} 15551ab64890Smrg 15561ab64890Smrg 15571ab64890Smrg/* 15581ab64890Smrg * This routine can be used to (cheaply) get some memory within a single 15591ab64890Smrg * Xlib routine for scratch space. A single buffer is reused each time 15601ab64890Smrg * if possible. To be MT safe, you can only call this between a call to 15611ab64890Smrg * GetReq* and a call to Data* or _XSend*, or in a context when the thread 15621ab64890Smrg * is guaranteed to not unlock the display. 15631ab64890Smrg */ 15641ab64890Smrgchar *_XAllocScratch( 15651ab64890Smrg register Display *dpy, 15661ab64890Smrg unsigned long nbytes) 15671ab64890Smrg{ 15681ab64890Smrg if (nbytes > dpy->scratch_length) { 1569cf2acddeSmrg Xfree (dpy->scratch_buffer); 1570cf2acddeSmrg dpy->scratch_buffer = Xmalloc(nbytes); 1571cf2acddeSmrg if (dpy->scratch_buffer) 15721ab64890Smrg dpy->scratch_length = nbytes; 15731ab64890Smrg else dpy->scratch_length = 0; 15741ab64890Smrg } 15751ab64890Smrg return (dpy->scratch_buffer); 15761ab64890Smrg} 15771ab64890Smrg 15781ab64890Smrg/* 15791ab64890Smrg * Scratch space allocator you can call any time, multiple times, and be 15801ab64890Smrg * MT safe, but you must hand the buffer back with _XFreeTemp. 15811ab64890Smrg */ 15821ab64890Smrgchar *_XAllocTemp( 15831ab64890Smrg register Display *dpy, 15841ab64890Smrg unsigned long nbytes) 15851ab64890Smrg{ 15861ab64890Smrg char *buf; 15871ab64890Smrg 15881ab64890Smrg buf = _XAllocScratch(dpy, nbytes); 15891ab64890Smrg dpy->scratch_buffer = NULL; 15901ab64890Smrg dpy->scratch_length = 0; 15911ab64890Smrg return buf; 15921ab64890Smrg} 15931ab64890Smrg 15941ab64890Smrgvoid _XFreeTemp( 15951ab64890Smrg register Display *dpy, 15961ab64890Smrg char *buf, 15971ab64890Smrg unsigned long nbytes) 15981ab64890Smrg{ 1599cf2acddeSmrg 1600cf2acddeSmrg Xfree(dpy->scratch_buffer); 16011ab64890Smrg dpy->scratch_buffer = buf; 16021ab64890Smrg dpy->scratch_length = nbytes; 16031ab64890Smrg} 16041ab64890Smrg 16051ab64890Smrg/* 16061ab64890Smrg * Given a visual id, find the visual structure for this id on this display. 16071ab64890Smrg */ 16081ab64890SmrgVisual *_XVIDtoVisual( 16091ab64890Smrg Display *dpy, 16101ab64890Smrg VisualID id) 16111ab64890Smrg{ 16121ab64890Smrg register int i, j, k; 16131ab64890Smrg register Screen *sp; 16141ab64890Smrg register Depth *dp; 16151ab64890Smrg register Visual *vp; 16161ab64890Smrg for (i = 0; i < dpy->nscreens; i++) { 16171ab64890Smrg sp = &dpy->screens[i]; 16181ab64890Smrg for (j = 0; j < sp->ndepths; j++) { 16191ab64890Smrg dp = &sp->depths[j]; 16201ab64890Smrg /* if nvisuals == 0 then visuals will be NULL */ 16211ab64890Smrg for (k = 0; k < dp->nvisuals; k++) { 16221ab64890Smrg vp = &dp->visuals[k]; 16231ab64890Smrg if (vp->visualid == id) return (vp); 16241ab64890Smrg } 16251ab64890Smrg } 16261ab64890Smrg } 16271ab64890Smrg return (NULL); 16281ab64890Smrg} 16291ab64890Smrg 16301ab64890Smrgint 16311ab64890SmrgXFree (void *data) 16321ab64890Smrg{ 16331ab64890Smrg Xfree (data); 16341ab64890Smrg return 1; 16351ab64890Smrg} 16361ab64890Smrg 16371ab64890Smrg#ifdef _XNEEDBCOPYFUNC 16381ab64890Smrgvoid _Xbcopy(b1, b2, length) 16391ab64890Smrg register char *b1, *b2; 16401ab64890Smrg register length; 16411ab64890Smrg{ 16421ab64890Smrg if (b1 < b2) { 16431ab64890Smrg b2 += length; 16441ab64890Smrg b1 += length; 16451ab64890Smrg while (length--) 16461ab64890Smrg *--b2 = *--b1; 16471ab64890Smrg } else { 16481ab64890Smrg while (length--) 16491ab64890Smrg *b2++ = *b1++; 16501ab64890Smrg } 16511ab64890Smrg} 16521ab64890Smrg#endif 16531ab64890Smrg 16541ab64890Smrg#ifdef DataRoutineIsProcedure 16551ab64890Smrgvoid Data( 16561ab64890Smrg Display *dpy, 1657556b6652Smrg _Xconst char *data, 16581ab64890Smrg long len) 16591ab64890Smrg{ 16601ab64890Smrg if (dpy->bufptr + (len) <= dpy->bufmax) { 16611ab64890Smrg memcpy(dpy->bufptr, data, (int)len); 16621ab64890Smrg dpy->bufptr += ((len) + 3) & ~3; 16631ab64890Smrg } else { 16641ab64890Smrg _XSend(dpy, data, len); 16651ab64890Smrg } 16661ab64890Smrg} 16671ab64890Smrg#endif /* DataRoutineIsProcedure */ 16681ab64890Smrg 16691ab64890Smrg 16701ab64890Smrg#ifdef LONG64 16711ab64890Smrgint 16721ab64890Smrg_XData32( 16731ab64890Smrg Display *dpy, 167415c3e985Smrg _Xconst long *data, 16751ab64890Smrg unsigned len) 16761ab64890Smrg{ 16771ab64890Smrg register int *buf; 16781ab64890Smrg register long i; 16791ab64890Smrg 16801ab64890Smrg while (len) { 16811ab64890Smrg buf = (int *)dpy->bufptr; 16821ab64890Smrg i = dpy->bufmax - (char *)buf; 16831ab64890Smrg if (!i) { 16841ab64890Smrg _XFlush(dpy); 16851ab64890Smrg continue; 16861ab64890Smrg } 16871ab64890Smrg if (len < i) 16881ab64890Smrg i = len; 16891ab64890Smrg dpy->bufptr = (char *)buf + i; 16901ab64890Smrg len -= i; 16911ab64890Smrg i >>= 2; 16921ab64890Smrg while (--i >= 0) 16931ab64890Smrg *buf++ = *data++; 16941ab64890Smrg } 16951ab64890Smrg return 0; 16961ab64890Smrg} 16971ab64890Smrg#endif /* LONG64 */ 16981ab64890Smrg 16991ab64890Smrg 17001ab64890Smrg 17011ab64890Smrg/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm. 17021ab64890Smrg * Otherwise, Xau will not be able to find your cookies in the Xauthority file. 17031ab64890Smrg * 17041ab64890Smrg * Note: POSIX says that the ``nodename'' member of utsname does _not_ have 17051ab64890Smrg * to have sufficient information for interfacing to the network, 17061ab64890Smrg * and so, you may be better off using gethostname (if it exists). 17071ab64890Smrg */ 17081ab64890Smrg 17092e9c7c8cSmrg#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4) 17101ab64890Smrg#define NEED_UTSNAME 17111ab64890Smrg#include <sys/utsname.h> 171288de56ccSmrg#else 171388de56ccSmrg#ifdef HAVE_UNISTD_H 171488de56ccSmrg#include <unistd.h> 171588de56ccSmrg#endif 17161ab64890Smrg#endif 17171ab64890Smrg 17181ab64890Smrg/* 17191ab64890Smrg * _XGetHostname - similar to gethostname but allows special processing. 17201ab64890Smrg */ 17211ab64890Smrgint _XGetHostname ( 17221ab64890Smrg char *buf, 17231ab64890Smrg int maxlen) 17241ab64890Smrg{ 17251ab64890Smrg int len; 17261ab64890Smrg 17271ab64890Smrg#ifdef NEED_UTSNAME 17281ab64890Smrg struct utsname name; 17291ab64890Smrg 17301ab64890Smrg if (maxlen <= 0 || buf == NULL) 17311ab64890Smrg return 0; 17321ab64890Smrg 17331ab64890Smrg uname (&name); 1734e90f245cSmaya len = (int) strlen (name.nodename); 17351ab64890Smrg if (len >= maxlen) len = maxlen - 1; 1736e90f245cSmaya strncpy (buf, name.nodename, (size_t) len); 17371ab64890Smrg buf[len] = '\0'; 17381ab64890Smrg#else 17391ab64890Smrg if (maxlen <= 0 || buf == NULL) 17401ab64890Smrg return 0; 17411ab64890Smrg 17421ab64890Smrg buf[0] = '\0'; 17431ab64890Smrg (void) gethostname (buf, maxlen); 17441ab64890Smrg buf [maxlen - 1] = '\0'; 1745e90f245cSmaya len = (int) strlen(buf); 17461ab64890Smrg#endif /* NEED_UTSNAME */ 17471ab64890Smrg return len; 17481ab64890Smrg} 17491ab64890Smrg 17501ab64890Smrg 17511ab64890Smrg/* 17521ab64890Smrg * _XScreenOfWindow - get the Screen of a given window 17531ab64890Smrg */ 17541ab64890Smrg 175561b2299dSmrgScreen *_XScreenOfWindow(Display *dpy, Window w) 17561ab64890Smrg{ 17571ab64890Smrg register int i; 17581ab64890Smrg Window root; 17591ab64890Smrg int x, y; /* dummy variables */ 17601ab64890Smrg unsigned int width, height, bw, depth; /* dummy variables */ 17611ab64890Smrg 17621ab64890Smrg if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height, 17631ab64890Smrg &bw, &depth) == False) { 17642e9c7c8cSmrg return NULL; 17651ab64890Smrg } 17661ab64890Smrg for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */ 17671ab64890Smrg if (root == RootWindow (dpy, i)) { 17681ab64890Smrg return ScreenOfDisplay (dpy, i); 17691ab64890Smrg } 17701ab64890Smrg } 17711ab64890Smrg return NULL; 17721ab64890Smrg} 17731ab64890Smrg 17741ab64890Smrg 1775556b6652Smrg/* 1776556b6652Smrg * WARNING: This implementation's pre-conditions and post-conditions 1777556b6652Smrg * must remain compatible with the old macro-based implementations of 1778556b6652Smrg * GetReq, GetReqExtra, GetResReq, and GetEmptyReq. The portions of the 1779556b6652Smrg * Display structure affected by those macros are part of libX11's 1780556b6652Smrg * ABI. 1781556b6652Smrg */ 1782556b6652Smrgvoid *_XGetRequest(Display *dpy, CARD8 type, size_t len) 1783556b6652Smrg{ 1784556b6652Smrg xReq *req; 1785556b6652Smrg 1786556b6652Smrg if (dpy->bufptr + len > dpy->bufmax) 1787556b6652Smrg _XFlush(dpy); 1788c555af55Smrg /* Request still too large, so do not allow it to overflow. */ 1789c555af55Smrg if (dpy->bufptr + len > dpy->bufmax) { 1790c555af55Smrg fprintf(stderr, 1791c555af55Smrg "Xlib: request %d length %zd would exceed buffer size.\n", 1792c555af55Smrg type, len); 1793c555af55Smrg /* Changes failure condition from overflow to NULL dereference. */ 1794c555af55Smrg return NULL; 1795c555af55Smrg } 1796556b6652Smrg 1797556b6652Smrg if (len % 4) 1798556b6652Smrg fprintf(stderr, 1799556b6652Smrg "Xlib: request %d length %zd not a multiple of 4.\n", 1800556b6652Smrg type, len); 1801556b6652Smrg 1802556b6652Smrg dpy->last_req = dpy->bufptr; 1803556b6652Smrg 1804556b6652Smrg req = (xReq*)dpy->bufptr; 1805556b6652Smrg req->reqType = type; 1806556b6652Smrg req->length = len / 4; 1807556b6652Smrg dpy->bufptr += len; 1808dac667f7Smrg X_DPY_REQUEST_INCREMENT(dpy); 1809556b6652Smrg return req; 1810556b6652Smrg} 1811556b6652Smrg 18121ab64890Smrg#if defined(WIN32) 18131ab64890Smrg 18141ab64890Smrg/* 18151ab64890Smrg * These functions are intended to be used internally to Xlib only. 18161ab64890Smrg * These functions will always prefix the path with a DOS drive in the 18171ab64890Smrg * form "<drive-letter>:". As such, these functions are only suitable 18181ab64890Smrg * for use by Xlib function that supply a root-based path to some 18191ab64890Smrg * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will 18201ab64890Smrg * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir". 18211ab64890Smrg */ 18221ab64890Smrg 18231ab64890Smrgstatic int access_file (path, pathbuf, len_pathbuf, pathret) 18241ab64890Smrg char* path; 18251ab64890Smrg char* pathbuf; 18261ab64890Smrg int len_pathbuf; 18271ab64890Smrg char** pathret; 18281ab64890Smrg{ 18291ab64890Smrg if (access (path, F_OK) == 0) { 18301ab64890Smrg if (strlen (path) < len_pathbuf) 18311ab64890Smrg *pathret = pathbuf; 18321ab64890Smrg else 18331ab64890Smrg *pathret = Xmalloc (strlen (path) + 1); 18341ab64890Smrg if (*pathret) { 18351ab64890Smrg strcpy (*pathret, path); 18361ab64890Smrg return 1; 18371ab64890Smrg } 18381ab64890Smrg } 18391ab64890Smrg return 0; 18401ab64890Smrg} 18411ab64890Smrg 18421ab64890Smrgstatic int AccessFile (path, pathbuf, len_pathbuf, pathret) 18431ab64890Smrg char* path; 18441ab64890Smrg char* pathbuf; 18451ab64890Smrg int len_pathbuf; 18461ab64890Smrg char** pathret; 18471ab64890Smrg{ 18481ab64890Smrg unsigned long drives; 18491ab64890Smrg int i, len; 18501ab64890Smrg char* drive; 18511ab64890Smrg char buf[MAX_PATH]; 18521ab64890Smrg char* bufp; 18531ab64890Smrg 18541ab64890Smrg /* just try the "raw" name first and see if it works */ 18551ab64890Smrg if (access_file (path, pathbuf, len_pathbuf, pathret)) 18561ab64890Smrg return 1; 18571ab64890Smrg 18581ab64890Smrg /* try the places set in the environment */ 18591ab64890Smrg drive = getenv ("_XBASEDRIVE"); 18601ab64890Smrg#ifdef __UNIXOS2__ 18611ab64890Smrg if (!drive) 18621ab64890Smrg drive = getenv ("X11ROOT"); 18631ab64890Smrg#endif 18641ab64890Smrg if (!drive) 18651ab64890Smrg drive = "C:"; 18661ab64890Smrg len = strlen (drive) + strlen (path); 18671ab64890Smrg if (len < MAX_PATH) bufp = buf; 18681ab64890Smrg else bufp = Xmalloc (len + 1); 18691ab64890Smrg strcpy (bufp, drive); 18701ab64890Smrg strcat (bufp, path); 18711ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 18721ab64890Smrg if (bufp != buf) Xfree (bufp); 18731ab64890Smrg return 1; 18741ab64890Smrg } 18751ab64890Smrg 187661b2299dSmrg#ifndef __UNIXOS2__ 18771ab64890Smrg /* one last place to look */ 18781ab64890Smrg drive = getenv ("HOMEDRIVE"); 18791ab64890Smrg if (drive) { 18801ab64890Smrg len = strlen (drive) + strlen (path); 18811ab64890Smrg if (len < MAX_PATH) bufp = buf; 18821ab64890Smrg else bufp = Xmalloc (len + 1); 18831ab64890Smrg strcpy (bufp, drive); 18841ab64890Smrg strcat (bufp, path); 18851ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 18861ab64890Smrg if (bufp != buf) Xfree (bufp); 18871ab64890Smrg return 1; 18881ab64890Smrg } 18891ab64890Smrg } 18901ab64890Smrg 18911ab64890Smrg /* tried everywhere else, go fishing */ 18921ab64890Smrg#define C_DRIVE ('C' - 'A') 18931ab64890Smrg#define Z_DRIVE ('Z' - 'A') 18941ab64890Smrg /* does OS/2 (with or with gcc-emx) have getdrives? */ 18951ab64890Smrg drives = _getdrives (); 18961ab64890Smrg for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */ 18971ab64890Smrg if ((1 << i) & drives) { 18981ab64890Smrg len = 2 + strlen (path); 18991ab64890Smrg if (len < MAX_PATH) bufp = buf; 19001ab64890Smrg else bufp = Xmalloc (len + 1); 19011ab64890Smrg *bufp = 'A' + i; 19021ab64890Smrg *(bufp + 1) = ':'; 19031ab64890Smrg *(bufp + 2) = '\0'; 19041ab64890Smrg strcat (bufp, path); 19051ab64890Smrg if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { 19061ab64890Smrg if (bufp != buf) Xfree (bufp); 19071ab64890Smrg return 1; 19081ab64890Smrg } 19091ab64890Smrg } 19101ab64890Smrg } 19111ab64890Smrg#endif 19121ab64890Smrg return 0; 19131ab64890Smrg} 19141ab64890Smrg 19151ab64890Smrgint _XOpenFile(path, flags) 19161ab64890Smrg _Xconst char* path; 19171ab64890Smrg int flags; 19181ab64890Smrg{ 19191ab64890Smrg char buf[MAX_PATH]; 19201ab64890Smrg char* bufp = NULL; 19211ab64890Smrg int ret = -1; 19221ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 19231ab64890Smrg 19241ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 19251ab64890Smrg ret = open (bufp, flags); 19261ab64890Smrg 19271ab64890Smrg (void) SetErrorMode (olderror); 19281ab64890Smrg 19291ab64890Smrg if (bufp != buf) Xfree (bufp); 19301ab64890Smrg 19311ab64890Smrg return ret; 19321ab64890Smrg} 19331ab64890Smrg 19341ab64890Smrgint _XOpenFileMode(path, flags, mode) 19351ab64890Smrg _Xconst char* path; 19361ab64890Smrg int flags; 19371ab64890Smrg mode_t mode; 19381ab64890Smrg{ 19391ab64890Smrg char buf[MAX_PATH]; 19401ab64890Smrg char* bufp = NULL; 19411ab64890Smrg int ret = -1; 19421ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 19431ab64890Smrg 19441ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 19451ab64890Smrg ret = open (bufp, flags, mode); 19461ab64890Smrg 19471ab64890Smrg (void) SetErrorMode (olderror); 19481ab64890Smrg 19491ab64890Smrg if (bufp != buf) Xfree (bufp); 19501ab64890Smrg 19511ab64890Smrg return ret; 19521ab64890Smrg} 19531ab64890Smrg 19541ab64890Smrgvoid* _XFopenFile(path, mode) 19551ab64890Smrg _Xconst char* path; 19561ab64890Smrg _Xconst char* mode; 19571ab64890Smrg{ 19581ab64890Smrg char buf[MAX_PATH]; 19591ab64890Smrg char* bufp = NULL; 19601ab64890Smrg void* ret = NULL; 19611ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 19621ab64890Smrg 19631ab64890Smrg if (AccessFile (path, buf, MAX_PATH, &bufp)) 19641ab64890Smrg ret = fopen (bufp, mode); 19651ab64890Smrg 19661ab64890Smrg (void) SetErrorMode (olderror); 19671ab64890Smrg 19681ab64890Smrg if (bufp != buf) Xfree (bufp); 19691ab64890Smrg 19701ab64890Smrg return ret; 19711ab64890Smrg} 19721ab64890Smrg 19731ab64890Smrgint _XAccessFile(path) 19741ab64890Smrg _Xconst char* path; 19751ab64890Smrg{ 19761ab64890Smrg char buf[MAX_PATH]; 19771ab64890Smrg char* bufp; 19781ab64890Smrg int ret = -1; 19791ab64890Smrg UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); 19801ab64890Smrg 19811ab64890Smrg ret = AccessFile (path, buf, MAX_PATH, &bufp); 19821ab64890Smrg 19831ab64890Smrg (void) SetErrorMode (olderror); 19841ab64890Smrg 19851ab64890Smrg if (bufp != buf) Xfree (bufp); 19861ab64890Smrg 19871ab64890Smrg return ret; 19881ab64890Smrg} 19891ab64890Smrg 19901ab64890Smrg#endif 19911ab64890Smrg 19921ab64890Smrg#ifdef WIN32 19931ab64890Smrg#undef _Xdebug 19941ab64890Smrgint _Xdebug = 0; 19951ab64890Smrgint *_Xdebug_p = &_Xdebug; 19961ab64890Smrgvoid (**_XCreateMutex_fn_p)(LockInfoPtr) = &_XCreateMutex_fn; 19971ab64890Smrgvoid (**_XFreeMutex_fn_p)(LockInfoPtr) = &_XFreeMutex_fn; 19981ab64890Smrgvoid (**_XLockMutex_fn_p)(LockInfoPtr 19991ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 20001ab64890Smrg , char * /* file */ 20011ab64890Smrg , int /* line */ 20021ab64890Smrg#endif 20031ab64890Smrg ) = &_XLockMutex_fn; 20041ab64890Smrgvoid (**_XUnlockMutex_fn_p)(LockInfoPtr 20051ab64890Smrg#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) 20061ab64890Smrg , char * /* file */ 20071ab64890Smrg , int /* line */ 20081ab64890Smrg#endif 20091ab64890Smrg ) = &_XUnlockMutex_fn; 20101ab64890SmrgLockInfoPtr *_Xglobal_lock_p = &_Xglobal_lock; 20111ab64890Smrg#endif 2012