From 2ebef6288467ce0f0583a0d0d2ef9afd637ee7e6 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Tue, 26 Jul 2016 00:34:34 +0200 Subject: update all files with NX relevant changes to libX11 1.3.4 --- nx-X11/lib/X11/ChkIfEv.c | 26 +- nx-X11/lib/X11/ConnDis.c | 291 ++++++++------ nx-X11/lib/X11/IfEvent.c | 15 +- nx-X11/lib/X11/OpenDis.c | 200 +++++++--- nx-X11/lib/X11/PeekEvent.c | 15 +- nx-X11/lib/X11/PeekIfEv.c | 15 +- nx-X11/lib/X11/Pending.c | 9 +- nx-X11/lib/X11/WinEvent.c | 18 +- nx-X11/lib/X11/Xlib.h | 156 ++++---- nx-X11/lib/X11/XlibAsync.c | 84 ++-- nx-X11/lib/X11/XlibInt.c | 975 ++++++++++++++++++++++++++++++++------------- nx-X11/lib/X11/Xlibint.h | 268 ++++++++++--- nx-X11/lib/X11/Xprivate.h | 28 ++ nx-X11/lib/X11/lcFile.c | 244 ++++++++++-- nx-X11/lib/X11/utlist.h | 115 ++++++ 15 files changed, 1750 insertions(+), 709 deletions(-) create mode 100644 nx-X11/lib/X11/Xprivate.h create mode 100644 nx-X11/lib/X11/utlist.h diff --git a/nx-X11/lib/X11/ChkIfEv.c b/nx-X11/lib/X11/ChkIfEv.c index 5de869492..313e4395c 100644 --- a/nx-X11/lib/X11/ChkIfEv.c +++ b/nx-X11/lib/X11/ChkIfEv.c @@ -23,28 +23,27 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ -/* $XFree86$ */ #ifdef HAVE_CONFIG_H #include #endif #include "Xlibint.h" -/* +/* * Check existing events in queue to find if any match. If so, return. * If not, flush buffer and see if any more events are readable. If one * matches, return. If all else fails, tell the user no events found. */ -Bool XCheckIfEvent (dpy, event, predicate, arg) - register Display *dpy; +Bool XCheckIfEvent ( + register Display *dpy, + register XEvent *event, /* XEvent to be filled in. */ Bool (*predicate)( Display* /* display */, XEvent* /* event */, char* /* arg */ - ); /* function to call */ - register XEvent *event; /* XEvent to be filled in. */ - char *arg; + ), /* function to call */ + char *arg) { register _XQEvent *prev, *qelt; unsigned long qe_serial = 0; @@ -60,6 +59,7 @@ Bool XCheckIfEvent (dpy, event, predicate, arg) && (*predicate)(dpy, &qelt->event, arg)) { *event = qelt->event; _XDeq(dpy, prev, qelt); + _XStoreEventCookie(dpy, event); UnlockDisplay(dpy); return True; } @@ -90,15 +90,16 @@ Bool XCheckIfEvent (dpy, event, predicate, arg) * events. */ -Bool XCheckIfEventNoFlush (dpy, event, predicate, arg) - register Display *dpy; +Bool XCheckIfEventNoFlush ( + register Display *dpy, + register XEvent *event, /* XEvent to be filled in. */ Bool (*predicate)( Display* /* display */, XEvent* /* event */, char* /* arg */ - ); /* function to call */ - register XEvent *event; /* XEvent to be filled in. */ - char *arg; + ), /* function to call */ + char *arg) + { register _XQEvent *prev, *qelt; unsigned long qe_serial = 0; @@ -114,6 +115,7 @@ Bool XCheckIfEventNoFlush (dpy, event, predicate, arg) && (*predicate)(dpy, &qelt->event, arg)) { *event = qelt->event; _XDeq(dpy, prev, qelt); + _XStoreEventCookie(dpy, event); UnlockDisplay(dpy); return True; } diff --git a/nx-X11/lib/X11/ConnDis.c b/nx-X11/lib/X11/ConnDis.c index fdf4593e2..46b71b23f 100644 --- a/nx-X11/lib/X11/ConnDis.c +++ b/nx-X11/lib/X11/ConnDis.c @@ -24,7 +24,7 @@ /**************************************************************************/ /* - + Copyright 1989, 1998 The Open Group Permission to use, copy, modify, distribute, and sell this software and its @@ -49,7 +49,7 @@ in this Software without prior written authorization from The Open Group. */ -/* +/* * This file contains operating system dependencies. */ @@ -59,9 +59,12 @@ in this Software without prior written authorization from The Open Group. #include #include #include +#ifdef HASXDMAUTH #include +#endif #include #include +#include #if !defined(WIN32) #ifndef Lynx @@ -77,10 +80,6 @@ in this Software without prior written authorization from The Open Group. #define X_CONNECTION_RETRIES 5 #endif -#ifdef LOCALCONN -#include -#endif - #include "Xintconn.h" /* prototypes */ @@ -96,7 +95,7 @@ static void GetAuthorization( int *auth_datalenp); /* functions */ -static char *copystring (char *src, int len) +static char *copystring (const char *src, int len) { char *dst = Xmalloc (len + 1); @@ -108,8 +107,38 @@ static char *copystring (char *src, int len) return dst; } +#define Xstrdup(s) copystring(s, strlen(s)) -/* +#ifdef TCPCONN +# define TCP_TRANS "tcp" +#endif +#ifdef UNIXCONN +# define UNIX_TRANS "unix" +#endif +#if defined(LOCALCONN) || defined(OS2PIPECONN) || defined(UNIXCONN) +# define LOCAL_TRANS "local" +#endif + +/* FIXME: This should be handled through Makefile/configure logic. See configure.ac in upstream libX11 */ + +#ifdef UNIXCONN +# ifdef TCPCONN +# define LOCAL_TRANSPORT_LIST LOCAL_TRANS,UNIX_TRANS,TCP_TRANS +# else +# define LOCAL_TRANSPORT_LIST LOCAL_TRANS,UNIX_TRANS +# endif +#else +# ifdef TCPCONN +# define LOCAL_TRANSPORT_LIST TCP_TRANS +# else +# define LOCAL_TRANSPORT_LIST +# endif +#endif + + + + +/* * Attempts to connect to server, given display name. Returns file descriptor * (network socket) or -1 if connection fails. Display names may be of the * following format: @@ -126,7 +155,7 @@ static char *copystring (char *src, int len) * by IETF RFC 2732. * * If no hostname and no protocol is specified, the string is interpreted - * as the most efficient local connection to a server on the same machine. + * as the most efficient local connection to a server on the same machine. * This is usually: * * o shared memory @@ -170,11 +199,11 @@ _X11TransConnectDisplay ( char* address = addrbuf; XtransConnInfo trans_conn = NULL; /* transport connection object */ int connect_stat; -#ifdef LOCALCONN - struct utsname sys; -#endif -#ifdef TCPCONN - char *tcphostname = NULL; /* A place to save hostname pointer */ +#if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN) + Bool reset_hostname = False; /* Reset hostname? */ + char *original_hostname = NULL; + int local_transport_index = -1; + const char *local_transport[] = { LOCAL_TRANSPORT_LIST, NULL }; #endif p = display_name; @@ -216,7 +245,7 @@ _X11TransConnectDisplay ( #endif /* - * Step 0, find the protocol. This is delimited by the optional + * Step 0, find the protocol. This is delimited by the optional * slash ('/'). */ for (lastp = p; *p && *p != ':' && *p != '/'; p++) ; @@ -287,7 +316,7 @@ _X11TransConnectDisplay ( /* * Step 1, find the hostname. This is delimited by either one colon, * or two colons in the case of DECnet (DECnet Phase V allows a single - * colon in the hostname). (See note above regarding IPv6 numeric + * colon in the hostname). (See note above regarding IPv6 numeric * addresses with triple colons or [] brackets.) */ @@ -299,7 +328,7 @@ _X11TransConnectDisplay ( if (!lastc) return NULL; /* must have a colon */ - if ((lastp != lastc) && (*(lastc - 1) == ':') + if ((lastp != lastc) && (*(lastc - 1) == ':') #if defined(IPv6) && defined(AF_INET6) && ( ((lastc - 1) == lastp) || (*(lastc - 2) != ':')) #endif @@ -327,23 +356,17 @@ _X11TransConnectDisplay ( p = lastc; -#ifdef LOCALCONN +#if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN) /* check if phostname == localnodename AND protocol not specified */ - if (!pprotocol && phostname && uname(&sys) >= 0 && - !strncmp(phostname, sys.nodename, - (strlen(sys.nodename) < strlen(phostname) ? - strlen(phostname) : strlen(sys.nodename)))) - { -#ifdef TCPCONN - /* - * We'll first attempt to connect using the local transport. If - * this fails (which is the case if sshd X protocol forwarding is - * being used), retry using tcp and this hostname. - */ - tcphostname = copystring(phostname, strlen(phostname)); -#endif - Xfree (phostname); - phostname = copystring ("unix", 4); + if (!pprotocol && phostname) { + char localhostname[256]; + + if ((_XGetHostname (localhostname, sizeof localhostname) > 0) + && (strcmp(phostname, localhostname) == 0)) { + original_hostname = phostname; + phostname = NULL; + reset_hostname = True; + } } #endif @@ -363,7 +386,7 @@ _X11TransConnectDisplay ( /* - * Step 2, find the display number. This field is required and is + * Step 2, find the display number. This field is required and is * delimited either by a nul or a period, depending on whether or not * a screen number is present. */ @@ -437,7 +460,7 @@ _X11TransConnectDisplay ( /* - * Step 3, find the screen number. This field is optional. It is + * Step 3, find the screen number. This field is optional. It is * present only if the display number was followed by a period (which * we've already verified is the only non-nul character). */ @@ -460,7 +483,7 @@ _X11TransConnectDisplay ( * idisplay display number * iscreen screen number * dnet DECnet boolean - * + * * We can now decide which transport to use based on the ConnectionFlags * build parameter the hostname string. If phostname is NULL or equals * the string "local", then choose the best transport. If phostname @@ -490,59 +513,41 @@ _X11TransConnectDisplay ( #if defined(TCPCONN) || defined(UNIXCONN) || defined(LOCALCONN) || defined(MNX_TCPCONN) || defined(OS2PIPECONN) if (!pprotocol) { - if (!phostname) { -#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN) - pprotocol = copystring ("local", 5); -#if defined(TCPCONN) - tcphostname = copystring("localhost", 9); +#if defined(UNIXCONN) + if (phostname && (strcmp (phostname, "unix") == 0)) { + Xfree(pprotocol); + pprotocol = copystring ("unix", 4); + } else #endif +#ifdef HAVE_LAUNCHD + if (phostname && phostname[0]=='/') { + pprotocol = copystring ("local", 5); } - else - { #endif + if (!phostname) + { + if (local_transport[0] != NULL) { + pprotocol = Xstrdup(local_transport[0]); + local_transport_index = 0; + } + } + + if (!pprotocol) { /* if still not found one, tcp is our last resort */ pprotocol = copystring ("tcp", 3); } } #endif -#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN) - /* - * Now that the defaults have been established, see if we have any - * special names that we have to override: - * - * :N => if UNIXCONN then unix-domain-socket - * ::N => if UNIXCONN then unix-domain-socket - * unix:N => if UNIXCONN then unix-domain-socket - * - * Note that if UNIXCONN isn't defined, then we can use the default - * transport connection function set above. - */ - - if (!phostname) { -#ifdef apollo - ; /* Unix domain sockets are *really* bad on apollos */ -#else - if( pprotocol ) Xfree(pprotocol); - pprotocol = copystring ("local", 5); -#endif - } - else if (strcmp (phostname, "unix") == 0) { - if( pprotocol ) Xfree(pprotocol); - pprotocol = copystring ("local", 5); - } -#endif -#if defined(TCPCONN) connect: -#endif /* * This seems kind of backwards, but we need to put the protocol, * host, and port back together to pass to _X11TransOpenCOTSClient(). */ { - int olen = 3 + (pprotocol ? strlen(pprotocol) : 0) + - (phostname ? strlen(phostname) : 0) + + int olen = 3 + (pprotocol ? strlen(pprotocol) : 0) + + (phostname ? strlen(phostname) : 0) + (pdpynum ? strlen(pdpynum) : 0); if (olen > sizeof addrbuf) address = Xmalloc (olen); } @@ -564,19 +569,19 @@ _X11TransConnectDisplay ( fprintf(stderr, "_X11TransConnectDisplay: Entering connection loop.\n"); #endif for(retry=X_CONNECTION_RETRIES; retry>=0; retry-- ) - { + { #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) fprintf(stderr, "_X11TransConnectDisplay: Going to call _X11TransOpenCOTSClient(address) with address [%s].\n", address); #endif if ( (trans_conn = _X11TransOpenCOTSClient(address)) == NULL ) - { + { break; - } + } #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) fprintf(stderr, "_X11TransConnectDisplay: Going to call _X11TransConnect(trans_conn,address).\n"); #endif if ((connect_stat = _X11TransConnect(trans_conn,address)) < 0 ) - { + { #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) fprintf(stderr, "_X11TransConnectDisplay: Going to call _X11TransClose(trans_conn).\n"); #endif @@ -584,13 +589,10 @@ _X11TransConnectDisplay ( trans_conn = NULL; if (connect_stat == TRANS_TRY_CONNECT_AGAIN) - { - sleep(1); continue; - } else break; - } + } #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) fprintf(stderr, "_X11TransConnectDisplay: Going to call _X11TransGetPeerAddr(trans_conn, &family, &saddrlen, &saddr).\n"); @@ -607,20 +609,19 @@ _X11TransConnectDisplay ( fprintf(stderr, "_X11TransConnectDisplay: Going to call _X11TransConvertAddress(&family, &saddrlen, &saddr).\n"); #endif if( _X11TransConvertAddress(&family, &saddrlen, &saddr) < 0 ) - { + { _X11TransClose(trans_conn); trans_conn = NULL; - sleep(1); if (saddr) { free ((char *) saddr); saddr = NULL; } continue; - } + } break; - } + } #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) fprintf(stderr, "_X11TransConnectDisplay: Out of connection loop.\n"); @@ -642,11 +643,30 @@ _X11TransConnectDisplay ( * * [host] : [:] dpy . scr \0 */ +#if defined(LOCALCONN) || defined(TCPCONN) || defined(UNIXCONN) + /* + * If we computed the host name, get rid of it so that + * XDisplayString() and XDisplayName() agree. + */ + if (reset_hostname && (phostname != original_hostname)) { + Xfree (phostname); + phostname = original_hostname; + original_hostname = NULL; + } +#endif len = ((phostname ? strlen(phostname) : 0) + 1 + (dnet ? 1 : 0) + strlen(pdpynum) + 1 + (pscrnum ? strlen(pscrnum) : 1) + 1); *fullnamep = (char *) Xmalloc (len); if (!*fullnamep) goto bad; +#ifdef HAVE_LAUNCHD + if (phostname && strlen(phostname) > 11 && !strncmp(phostname, "/tmp/launch", 11)) + sprintf (*fullnamep, "%s%s%d", + (phostname ? phostname : ""), + (dnet ? "::" : ":"), + idisplay); + else +#endif sprintf (*fullnamep, "%s%s%d.%d", (phostname ? phostname : ""), (dnet ? "::" : ":"), @@ -658,8 +678,8 @@ _X11TransConnectDisplay ( if (phostname) Xfree (phostname); if (pdpynum) Xfree (pdpynum); if (pscrnum) Xfree (pscrnum); -#ifdef TCPCONN - if (tcphostname) Xfree (tcphostname); +#if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN) + if (original_hostname) Xfree (original_hostname); #endif GetAuthorization(trans_conn, family, (char *) saddr, saddrlen, idisplay, @@ -677,14 +697,36 @@ _X11TransConnectDisplay ( if (phostname) Xfree (phostname); if (address && address != addrbuf) { Xfree(address); address = addrbuf; } -#if defined(TCPCONN) - if (tcphostname) { - pprotocol = copystring("tcp", 3); - phostname = tcphostname; - tcphostname = NULL; - goto connect; +#if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN) + /* If connecting to the local machine, and we failed, try again with + * the next transport type available, if there is one. + */ + if (local_transport_index >= 0) { + if (local_transport[++local_transport_index] != NULL) { + pprotocol = Xstrdup(local_transport[local_transport_index]); +#ifdef TCPCONN + if (strcmp(pprotocol, "tcp") == 0) { + if (original_hostname != NULL) { + phostname = original_hostname; + original_hostname = NULL; + } else { + phostname = copystring("localhost", 9); + } + } else +#endif /* TCPCONN */ + { + if ((phostname != NULL) && (original_hostname == NULL)) { + original_hostname = phostname; + } + phostname = NULL; + } + goto connect; + } } -#endif + + /* No more to try, we've failed all available local transports */ + if (original_hostname) Xfree(original_hostname); +#endif /* LOCALCONN || UNIXCONN || TCPCONN */ if (pdpynum) Xfree (pdpynum); if (pscrnum) Xfree (pscrnum); @@ -731,14 +773,11 @@ int _XConnectDisplay ( * * *****************************************************************************/ -/* +/* * Disconnect from server. */ -int _XDisconnectDisplay (trans_conn) - -XtransConnInfo trans_conn; - +int _XDisconnectDisplay (XtransConnInfo trans_conn) { _X11TransDisconnect(trans_conn); _X11TransClose(trans_conn); @@ -748,11 +787,11 @@ XtransConnInfo trans_conn; Bool -_XSendClientPrefix (dpy, client, auth_proto, auth_string, prefix) - Display *dpy; - xConnClientPrefix *client; /* contains count for auth_* */ - char *auth_proto, *auth_string; /* NOT null-terminated */ - xConnSetupPrefix *prefix; /* prefix information */ +_XSendClientPrefix( + Display *dpy, + xConnClientPrefix *client, /* contains count for auth_* */ + char *auth_proto, char *auth_string, /* NOT null-terminated */ + xConnSetupPrefix *prefix) /* prefix information */ { int auth_length = client->nbytesAuthProto; int auth_strlen = client->nbytesAuthString; @@ -878,15 +917,15 @@ static _Xconst int default_xauth_lengths[] = { }; #define NUM_DEFAULT_AUTH (sizeof (default_xauth_names) / sizeof (default_xauth_names[0])) - + static char **xauth_names = default_xauth_names; static _Xconst int *xauth_lengths = default_xauth_lengths; static int xauth_names_length = NUM_DEFAULT_AUTH; -void XSetAuthorization (name, namelen, data, datalen) - int namelen, datalen; /* lengths of name and data */ - char *name, *data; /* NULL or arbitrary array of bytes */ +void XSetAuthorization ( + char *name, int namelen, /* *len are lengths of name and data */ + char *data, int datalen) /* name/data are NULL or arbitrary array of bytes */ { char *tmpname, *tmpdata; @@ -946,11 +985,11 @@ void XSetAuthorization (name, namelen, data, datalen) * Create a credential that we can send to the X server. */ static int -auth_ezencode(servername, window, cred_out, len) - char *servername; - int window; - char *cred_out; - int *len; +auth_ezencode( + char *servername, + int window, + char *cred_out, + int *len) { AUTH *a; XDR xdr; @@ -1308,7 +1347,7 @@ GetAuthorization( { #ifdef AF_INET case AF_INET: - { + { /* * addr will contain a sockaddr_in with all * of the members already in network byte order. @@ -1319,37 +1358,37 @@ GetAuthorization( for(i=2; i<4; i++) /* do sin_port */ xdmcp_data[j++] = ((char *)addr)[i]; break; - } + } #endif /* AF_INET */ #if defined(IPv6) && defined(AF_INET6) case AF_INET6: /* XXX This should probably never happen */ - { + { unsigned char ipv4mappedprefix[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; - - /* In the case of v4 mapped addresses send the v4 + + /* In the case of v4 mapped addresses send the v4 part of the address - addr is already in network byte order */ - if (memcmp(addr+8, ipv4mappedprefix, 12) == 0) { + if (memcmp((char*)addr+8, ipv4mappedprefix, 12) == 0) { for (i = 20 ; i < 24; i++) xdmcp_data[j++] = ((char *)addr)[i]; - + /* Port number */ for (i=2; i<4; i++) xdmcp_data[j++] = ((char *)addr)[i]; } else { - /* Fake data to keep the data aligned. Otherwise the + /* Fake data to keep the data aligned. Otherwise the the server will bail about incorrect timing data */ for (i = 0; i < 6; i++) { xdmcp_data[j++] = 0; } } break; - } + } #endif /* AF_INET6 */ #ifdef AF_UNIX case AF_UNIX: - { + { /* * We don't use the sockaddr_un for this encoding. * Instead, we create a sockaddr_in filled with @@ -1362,14 +1401,14 @@ GetAuthorization( unsigned short the_port; unsigned long the_utime; struct timeval tp; - + X_GETTIMEOFDAY(&tp); _XLockMutex(_Xglobal_lock); the_addr = unix_addr--; _XUnlockMutex(_Xglobal_lock); the_utime = (unsigned long) tp.tv_usec; the_port = getpid (); - + xdmcp_data[j++] = (the_utime >> 24) & 0xFF; xdmcp_data[j++] = (the_utime >> 16) & 0xFF; xdmcp_data[j++] = ((the_utime >> 8) & 0xF0) @@ -1378,7 +1417,7 @@ GetAuthorization( xdmcp_data[j++] = (the_port >> 8) & 0xFF; xdmcp_data[j++] = (the_port >> 0) & 0xFF; break; - } + } #endif /* AF_UNIX */ #ifdef AF_DECnet case AF_DECnet: diff --git a/nx-X11/lib/X11/IfEvent.c b/nx-X11/lib/X11/IfEvent.c index 434e815f7..1a5eef7ce 100644 --- a/nx-X11/lib/X11/IfEvent.c +++ b/nx-X11/lib/X11/IfEvent.c @@ -29,25 +29,25 @@ in this Software without prior written authorization from The Open Group. #endif #include "Xlibint.h" -/* +/* * Flush output and (wait for and) return the next event matching the * predicate in the queue. */ int -XIfEvent (dpy, event, predicate, arg) - register Display *dpy; +XIfEvent ( + register Display *dpy, + register XEvent *event, Bool (*predicate)( Display* /* display */, XEvent* /* event */, char* /* arg */ - ); /* function to call */ - register XEvent *event; - char *arg; + ), /* function to call */ + char *arg) { register _XQEvent *qelt, *prev; unsigned long qe_serial = 0; - + LockDisplay(dpy); prev = NULL; while (1) { @@ -58,6 +58,7 @@ XIfEvent (dpy, event, predicate, arg) && (*predicate)(dpy, &qelt->event, arg)) { *event = qelt->event; _XDeq(dpy, prev, qelt); + _XStoreEventCookie(dpy, event); UnlockDisplay(dpy); return 0; } diff --git a/nx-X11/lib/X11/OpenDis.c b/nx-X11/lib/X11/OpenDis.c index 6b022d409..a17b8b161 100644 --- a/nx-X11/lib/X11/OpenDis.c +++ b/nx-X11/lib/X11/OpenDis.c @@ -53,10 +53,14 @@ in this Software without prior written authorization from The Open Group. #include #endif #include "Xlibint.h" +#if USE_XCB +#include "Xxcbint.h" +#else /* !USE_XCB */ #include +#include +#endif /* USE_XCB */ #include #include -#include #include #include "Xintconn.h" @@ -68,6 +72,7 @@ in this Software without prior written authorization from The Open Group. extern void *_X11TransSocketProxyConnInfo(XtransConnInfo); #endif +#if !USE_XCB #ifdef X_NOT_POSIX #define Size_t unsigned int #else @@ -80,6 +85,7 @@ typedef struct { unsigned long seq; int opcode; } _XBigReqState; +#endif /* !USE_XCB */ #ifdef XTHREADS #include "locking.h" @@ -98,10 +104,12 @@ static xReq _dummy_request = { }; static void OutOfMemory(Display *dpy, char *setup); +#if !USE_XCB static Bool _XBigReqHandler(Display *dpy, xReply *rep, char *buf, int len, XPointer data); +#endif /* !USE_XCB */ -/* +/* * Connects to a server, creates a Display object and returns a pointer to * the newly created Display back to the caller. */ @@ -113,15 +121,19 @@ XOpenDisplay ( register int i; int j, k; /* random iterator indexes */ char *display_name; /* pointer to display name */ +#if !USE_XCB int endian; /* to determine which endian. */ xConnClientPrefix client; /* client information */ - xConnSetupPrefix prefix; /* prefix information */ - int vendorlen; /* length of vendor string */ + int idisplay; /* display number */ + int prefixread = 0; /* setup prefix already read? */ + char *conn_auth_name, *conn_auth_data; + int conn_auth_namelen, conn_auth_datalen; +#endif /* !USE_XCB */ char *setup = NULL; /* memory allocated at startup */ char *fullname = NULL; /* expanded name of display */ - int idisplay; /* display number */ int iscreen; /* screen number */ - int prefixread = 0; /* setup prefix already read? */ + xConnSetupPrefix prefix; /* prefix information */ + int vendorlen; /* length of vendor string */ union { xConnSetup *setup; char *failure; @@ -133,20 +145,20 @@ XOpenDisplay ( } u; /* proto data returned from server */ long setuplength; /* number of bytes in setup message */ long usedbytes = 0; /* number of bytes we have processed */ - char *conn_auth_name, *conn_auth_data; - int conn_auth_namelen, conn_auth_datalen; unsigned long mask; - long int conn_buf_size; - char *xlib_buffer_size; + long int conn_buf_size; + char *xlib_buffer_size; +#if !USE_XCB bzero((char *) &client, sizeof(client)); bzero((char *) &prefix, sizeof(prefix)); +#endif /* !USE_XCB */ #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) fprintf(stderr, "\nXOpenDisplay: Called with display [%s].\n", display); #endif /* - * If the display specifier string supplied as an argument to this + * If the display specifier string supplied as an argument to this * routine is NULL or a pointer to NULL, read the DISPLAY variable. */ if (display == NULL || *display == '\0') { @@ -159,6 +171,7 @@ XOpenDisplay ( /* Display is non-NULL, copy the pointer */ display_name = (char *)display; } + /* * Set the default error handlers. This allows the global variables to * default to NULL for use with shared libraries. @@ -179,6 +192,32 @@ XOpenDisplay ( * will set fullname to point to the expanded name. */ +#if USE_XCB + if(!_XConnectXCB(dpy, display, &fullname, &iscreen)) { + /* Try falling back on other transports if no transport specified */ + const char *slash = strrchr(display_name, '/'); + if(slash == NULL) { + const char *protocols[] = {"local", "unix", "tcp", "inet6", "inet", NULL}; + const char **s; + size_t buf_size = strlen(display_name) + 7; // max strlen + 2 (null + /) + char *buf = Xmalloc(buf_size * sizeof(char)); + + if(buf) { + for(s = protocols; buf && *s; s++) { + snprintf(buf, buf_size, "%s/%s", *s, display_name); + if(_XConnectXCB(dpy, buf, &fullname, &iscreen)) + goto fallback_success; + } + Xfree(buf); + } + } + + dpy->display_name = fullname; + OutOfMemory(dpy, NULL); + return NULL; + } +fallback_success: +#else /* !USE_XCB */ if ((dpy->trans_conn = _X11TransConnectDisplay ( display_name, &fullname, &idisplay, &iscreen, &conn_auth_name, @@ -189,6 +228,7 @@ XOpenDisplay ( } dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn); +#endif /* USE_XCB */ #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) fprintf(stderr, "\nXOpenDisplay: Connected display with dpy->fd = [%d].\n", dpy->fd); @@ -274,7 +314,7 @@ XOpenDisplay ( if (!_XPollfdCacheInit(dpy)) { OutOfMemory (dpy, setup); return(NULL); - } + } /* Set up the output buffers. */ #ifndef XLIBDEFAULTBUFSIZE @@ -283,23 +323,34 @@ XOpenDisplay ( #ifndef XLIBMINBUFSIZE #define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */ #endif - if ((xlib_buffer_size = getenv("XLIBBUFFERSIZE")) == NULL) - conn_buf_size = XLIBDEFAULTBUFSIZE; - else - conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10); - if (conn_buf_size < XLIBMINBUFSIZE) - conn_buf_size = XLIBMINBUFSIZE; + xlib_buffer_size = getenv("XLIBBUFFERSIZE"); + +#ifdef __sun /* Backwards compatibility for old Solaris libX11 name */ + if (xlib_buffer_size == NULL) + xlib_buffer_size = getenv("XSUNBUFFERSIZE"); +#endif + + if (xlib_buffer_size == NULL) + conn_buf_size = XLIBDEFAULTBUFSIZE; + else + conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10); + if (conn_buf_size < XLIBMINBUFSIZE) + conn_buf_size = XLIBMINBUFSIZE; #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) fprintf (stderr, "Xlib: Running with XLIBBUFFERSIZE [%d] XLIBMINBUFSIZE [%d] " "buffer size [%ld].\n", XLIBDEFAULTBUFSIZE, XLIBMINBUFSIZE, conn_buf_size); #endif - if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) { - OutOfMemory (dpy, setup); - return(NULL); - } - dpy->bufmax = dpy->buffer + conn_buf_size; - + if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) { + OutOfMemory (dpy, setup); + return(NULL); + } + dpy->bufmax = dpy->buffer + conn_buf_size; +#if USE_XCB + dpy->xcb->real_bufmax = dpy->bufmax; + dpy->bufmax = dpy->buffer; +#endif + /* Set up the input event queue and input event queue parameters. */ dpy->head = dpy->tail = NULL; dpy->qlen = 0; @@ -312,10 +363,11 @@ XOpenDisplay ( return(NULL); } +#if !USE_XCB /* * The xConnClientPrefix describes the initial connection setup information * and is followed by the authorization information. Sites that are interested - * in security are strongly encouraged to use an authentication and + * in security are strongly encouraged to use an authentication and * authorization system such as Kerberos. */ endian = 1; @@ -373,7 +425,18 @@ XOpenDisplay ( Xfree ((char *)dpy); return(NULL); } +#endif /* !USE_XCB */ +#if USE_XCB + { + const struct xcb_setup_t *xcbsetup = xcb_get_setup(dpy->xcb->connection); + memcpy(&prefix, xcbsetup, sizeof(prefix)); + setuplength = prefix.length << 2; + setup = (char *) xcbsetup; + setup += SIZEOF(xConnSetupPrefix); + u.setup = (xConnSetup *) setup; + } +#else /* !USE_XCB */ setuplength = prefix.length << 2; if ( (u.setup = (xConnSetup *) (setup = Xmalloc ((unsigned) setuplength))) == NULL) { @@ -389,7 +452,7 @@ XOpenDisplay ( */ if (prefix.success != xTrue) { /* XXX - printing messages marks a bad programming interface */ - fprintf (stderr, + fprintf (stderr, "Xlib: connection to \"%s\" refused by server\r\nXlib: ", fullname); @@ -404,6 +467,7 @@ XOpenDisplay ( OutOfMemory(dpy, setup); return (NULL); } +#endif /* USE_XCB */ /* * Check if the reply was long enough to get any information out of it. @@ -443,7 +507,7 @@ XOpenDisplay ( OutOfMemory(dpy, setup); return (NULL); } - + while (!(mask & 1)) { dpy->resource_shift++; mask = mask >> 1; @@ -480,15 +544,12 @@ XOpenDisplay ( (void) strncpy(dpy->vendor, u.vendor, vendorlen); dpy->vendor[vendorlen] = '\0'; vendorlen = (vendorlen + 3) & ~3; /* round up */ + u.vendor += vendorlen; - - memmove (setup, u.vendor + vendorlen, - (int) setuplength - sz_xConnSetup - vendorlen); - u.vendor = setup; /* * Now iterate down setup information..... */ - dpy->pixmap_format = + dpy->pixmap_format = (ScreenFormat *)Xmalloc( (unsigned) (dpy->nformats *sizeof(ScreenFormat))); if (dpy->pixmap_format == NULL) { @@ -518,7 +579,7 @@ XOpenDisplay ( /* * next the Screen structures. */ - dpy->screens = + dpy->screens = (Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen)); if (dpy->screens == NULL) { OutOfMemory (dpy, setup); @@ -539,7 +600,7 @@ XOpenDisplay ( return(NULL); } - root_visualID = u.rp->rootVisualID; + root_visualID = u.rp->rootVisualID; sp->display = dpy; sp->root = u.rp->windowId; sp->cmap = u.rp->defaultColormap; @@ -579,12 +640,12 @@ XOpenDisplay ( OutOfMemory (dpy, setup); return(NULL); } - + dp->depth = u.dp->depth; dp->nvisuals = u.dp->nVisuals; u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth); if (dp->nvisuals > 0) { - dp->visuals = + dp->visuals = (Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual)); if (dp->visuals == NULL) { OutOfMemory (dpy, setup); @@ -599,7 +660,7 @@ XOpenDisplay ( OutOfMemory (dpy, setup); return(NULL); } - + vp->visualid = u.vp->visualID; vp->class = u.vp->class; vp->bits_per_rgb= u.vp->bitsPerRGB; @@ -637,7 +698,9 @@ XOpenDisplay ( * Now start talking to the server to setup all other information... */ +#if !USE_XCB Xfree (setup); /* all finished with setup information */ +#endif /* !USE_XCB */ /* * Make sure default screen is legal. @@ -647,10 +710,18 @@ XOpenDisplay ( return(NULL); } +#if !USE_XCB /* * finished calling internal routines, now unlock for external routines */ UnlockDisplay(dpy); +#endif /* !USE_XCB */ + +#if USE_XCB + dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection); + if(dpy->bigreq_size <= dpy->max_request_size) + dpy->bigreq_size = 0; +#endif /* USE_XCB */ /* * Set up other stuff clients are always going to use. @@ -679,11 +750,12 @@ XOpenDisplay ( */ LockDisplay(dpy); { + xGetPropertyReply reply; + xGetPropertyReq *req; +#if !USE_XCB _XAsyncHandler async; _XBigReqState async_state; xQueryExtensionReq *qreq; - xGetPropertyReply reply; - xGetPropertyReq *req; xBigReqEnableReq *breq; xBigReqEnableReply brep; @@ -697,6 +769,7 @@ XOpenDisplay ( qreq->nbytes = bignamelen; qreq->length += (bignamelen+3)>>2; Data(dpy, XBigReqExtensionName, bignamelen); +#endif /* !USE_XCB */ GetReq (GetProperty, req); req->window = RootWindow(dpy, 0); @@ -717,6 +790,7 @@ XOpenDisplay ( else if (reply.propertyType != None) _XEatData(dpy, reply.nItems * (reply.format >> 3)); } +#if !USE_XCB DeqAsyncHandler(dpy, &async); if (async_state.opcode) { GetReq(BigReqEnable, breq); @@ -725,6 +799,7 @@ XOpenDisplay ( if (_XReply(dpy, (xReply *)&brep, 0, xFalse)) dpy->bigreq_size = brep.max_request_size; } +#endif /* !USE_XCB */ } UnlockDisplay(dpy); @@ -746,13 +821,14 @@ XOpenDisplay ( return(dpy); } +#if !USE_XCB static Bool -_XBigReqHandler(dpy, rep, buf, len, data) - register Display *dpy; - register xReply *rep; - char *buf; - int len; - XPointer data; +_XBigReqHandler( + register Display *dpy, + register xReply *rep, + char *buf, + int len, + XPointer data) { _XBigReqState *state; xQueryExtensionReply replbuf; @@ -771,9 +847,10 @@ _XBigReqHandler(dpy, rep, buf, len, data) state->opcode = repl->major_opcode; return True; } +#endif /* !USE_XCB */ -/* XFreeDisplayStructure frees all the storage associated with a +/* XFreeDisplayStructure frees all the storage associated with a * Display. It is used by XOpenDisplay if it runs out of memory, * and also by XCloseDisplay. It needs to check whether all pointers * are non-NULL before dereferencing them, since it may be called @@ -782,9 +859,19 @@ _XBigReqHandler(dpy, rep, buf, len, data) * before the first possible call on this. */ -void _XFreeDisplayStructure(dpy) - register Display *dpy; +void _XFreeDisplayStructure(Display *dpy) { + /* move all cookies in the EQ to the jar, then free them. */ + if (dpy->qfree) { + _XQEvent *qelt = dpy->qfree; + while (qelt) { + if (_XIsEventCookie(dpy, &qelt->event)) + _XStoreEventCookie(dpy, &qelt->event); + qelt = qelt->next; + } + } + if (dpy->cookiejar) + _XFreeEventCookies(dpy); while (dpy->ext_procs) { _XExtension *ext = dpy->ext_procs; dpy->ext_procs = ext->next; @@ -844,7 +931,7 @@ void _XFreeDisplayStructure(dpy) Xfree ((char *)dpy->screens); } - + if (dpy->pixmap_format) { register int i; @@ -898,17 +985,26 @@ void _XFreeDisplayStructure(dpy) if (dpy->filedes) Xfree (dpy->filedes); +#if USE_XCB + _XFreeX11XCBStructure(dpy); +#endif /* USE_XCB */ + Xfree ((char *)dpy); } /* OutOfMemory is called if malloc fails. XOpenDisplay returns NULL after this returns. */ -static void OutOfMemory (dpy, setup) - Display *dpy; - char *setup; +static void OutOfMemory(Display *dpy, char *setup) { +#if USE_XCB + if(dpy->xcb->connection) + xcb_disconnect(dpy->xcb->connection); +#else /* !USE_XCB */ _XDisconnectDisplay (dpy->trans_conn); +#endif /* USE_XCB */ _XFreeDisplayStructure (dpy); +#if !USE_XCB if (setup) Xfree (setup); +#endif /* !USE_XCB */ } diff --git a/nx-X11/lib/X11/PeekEvent.c b/nx-X11/lib/X11/PeekEvent.c index 218c9a6dd..ffbaa05b4 100644 --- a/nx-X11/lib/X11/PeekEvent.c +++ b/nx-X11/lib/X11/PeekEvent.c @@ -29,17 +29,18 @@ in this Software without prior written authorization from The Open Group. #endif #include "Xlibint.h" -/* +/* * Return the next event in the queue, * BUT do not remove it from the queue. * If none found, flush and wait until there is an event to peek. */ int -XPeekEvent (dpy, event) - register Display *dpy; - register XEvent *event; +XPeekEvent ( + register Display *dpy, + register XEvent *event) { + XEvent copy; LockDisplay(dpy); if (dpy->head == NULL) _XReadEvents(dpy); @@ -47,9 +48,13 @@ XPeekEvent (dpy, event) if (_XGetIOError(dpy)) { UnlockDisplay(dpy); return 1; - } + } #endif *event = (dpy->head)->event; + if (_XCopyEventCookie(dpy, &event->xcookie, ©.xcookie)) { + _XStoreEventCookie(dpy, ©); + *event = copy; + } UnlockDisplay(dpy); return 1; } diff --git a/nx-X11/lib/X11/PeekIfEv.c b/nx-X11/lib/X11/PeekIfEv.c index 593332898..f2f2cede4 100644 --- a/nx-X11/lib/X11/PeekIfEv.c +++ b/nx-X11/lib/X11/PeekIfEv.c @@ -36,15 +36,15 @@ in this Software without prior written authorization from The Open Group. */ int -XPeekIfEvent (dpy, event, predicate, arg) - register Display *dpy; - register XEvent *event; +XPeekIfEvent ( + register Display *dpy, + register XEvent *event, Bool (*predicate)( Display* /* display */, XEvent* /* event */, char* /* arg */ - ); - char *arg; + ), + char *arg) { register _XQEvent *prev, *qelt; unsigned long qe_serial = 0; @@ -57,7 +57,12 @@ XPeekIfEvent (dpy, event, predicate, arg) prev = qelt, qelt = qelt->next) { if(qelt->qserial_num > qe_serial && (*predicate)(dpy, &qelt->event, arg)) { + XEvent copy; *event = qelt->event; + if (_XCopyEventCookie(dpy, &event->xcookie, ©.xcookie)) { + _XStoreEventCookie(dpy, ©); + *event = copy; + } UnlockDisplay(dpy); return 0; } diff --git a/nx-X11/lib/X11/Pending.c b/nx-X11/lib/X11/Pending.c index 0f389a0ca..10fa82fd5 100644 --- a/nx-X11/lib/X11/Pending.c +++ b/nx-X11/lib/X11/Pending.c @@ -33,9 +33,9 @@ in this Software without prior written authorization from The Open Group. /* Read in pending events if needed and return the number of queued events. */ -int XEventsQueued (dpy, mode) - register Display *dpy; - int mode; +int XEventsQueued ( + register Display *dpy, + int mode) { int ret_val; #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) @@ -54,8 +54,7 @@ int XEventsQueued (dpy, mode) return ret_val; } -int XPending (dpy) - register Display *dpy; +int XPending (register Display *dpy) { int ret_val; LockDisplay(dpy); diff --git a/nx-X11/lib/X11/WinEvent.c b/nx-X11/lib/X11/WinEvent.c index 6adf76bb1..48801b739 100644 --- a/nx-X11/lib/X11/WinEvent.c +++ b/nx-X11/lib/X11/WinEvent.c @@ -34,7 +34,7 @@ extern long const _Xevent_to_mask[]; #define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\ Button4MotionMask|Button5MotionMask) -/* +/* * Return the next event in the queue * for the given window matching one of the events in the mask. * Events earlier in the queue are not discarded. @@ -43,23 +43,27 @@ extern long const _Xevent_to_mask[]; */ int -XWindowEvent (dpy, w, mask, event) - register Display *dpy; - Window w; /* Selected window. */ - long mask; /* Selected event mask. */ - register XEvent *event; /* XEvent to be filled in. */ +XWindowEvent ( + register Display *dpy, + Window w, /* Selected window. */ + long mask, /* Selected event mask. */ + register XEvent *event) /* XEvent to be filled in. */ { register _XQEvent *prev, *qelt; unsigned long qe_serial = 0; LockDisplay(dpy); + + /* Delete unclaimed cookies */ + _XFreeEventCookies(dpy); + prev = NULL; while (1) { for (qelt = prev ? prev->next : dpy->head; qelt; prev = qelt, qelt = qelt->next) { if ((qelt->event.xany.window == w) && - (qelt->event.type < LASTEvent) && + (qelt->event.type < GenericEvent) && (_Xevent_to_mask[qelt->event.type] & mask) && ((qelt->event.type != MotionNotify) || (mask & AllPointers) || diff --git a/nx-X11/lib/X11/Xlib.h b/nx-X11/lib/X11/Xlib.h index a7ca57796..c6851ecf8 100644 --- a/nx-X11/lib/X11/Xlib.h +++ b/nx-X11/lib/X11/Xlib.h @@ -1,4 +1,4 @@ -/* +/* Copyright 1985, 1986, 1987, 1991, 1998 The Open Group @@ -30,27 +30,12 @@ in this Software without prior written authorization from The Open Group. * interface library (Xlib) to the X Window System Protocol (V11). * Structures and symbols starting with "_" are private to the library. */ - -#if !defined(_XLIB_H_) && !defined(_X11_XLIB_H_) +#ifndef _XLIB_H_ #define _XLIB_H_ -#define _X11_XLIB_H_ #define XlibSpecificationRelease 6 -#ifdef USG -#ifndef __TYPES__ -#include /* forgot to protect it... */ -#define __TYPES__ -#endif /* __TYPES__ */ -#else -#if defined(_POSIX_SOURCE) && defined(MOTOROLA) -#undef _POSIX_SOURCE #include -#define _POSIX_SOURCE -#else -#include -#endif -#endif /* USG */ #if defined(__SCO__) || defined(__UNIXWARE__) #include @@ -62,14 +47,6 @@ in this Software without prior written authorization from The Open Group. #include #include -#ifndef X_WCHAR -#ifdef X_NOT_STDC_ENV -#ifndef ISC -#define X_WCHAR -#endif -#endif -#endif - #ifndef X_WCHAR #include #else @@ -83,7 +60,7 @@ typedef unsigned long wchar_t; #if defined(ISC) && defined(USE_XMBTOWC) #define wctomb(a,b) _Xwctomb(a,b) -#define mblen(a,b) _Xmblen(a,b) +#define mblen(a,b) _Xmblen(a,b) #ifndef USE_XWCHAR_STRING #define mbtowc(a,b,c) _Xmbtowc(a,b,c) #endif @@ -143,7 +120,11 @@ typedef char *XPointer; #define BitmapBitOrder(dpy) (((_XPrivDisplay)dpy)->bitmap_bit_order) #define BitmapPad(dpy) (((_XPrivDisplay)dpy)->bitmap_pad) #define ImageByteOrder(dpy) (((_XPrivDisplay)dpy)->byte_order) +#ifdef CRAY /* unable to get WORD64 without pulling in other symbols */ +#define NextRequest(dpy) XNextRequest(dpy) +#else #define NextRequest(dpy) (((_XPrivDisplay)dpy)->request + 1) +#endif #define LastKnownRequestProcessed(dpy) (((_XPrivDisplay)dpy)->last_request_read) /* macros for screen oriented applications (toolkit) */ @@ -212,10 +193,10 @@ typedef struct { unsigned long background;/* background pixel */ int line_width; /* line width */ int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */ - int cap_style; /* CapNotLast, CapButt, + int cap_style; /* CapNotLast, CapButt, CapRound, CapProjecting */ int join_style; /* JoinMiter, JoinRound, JoinBevel */ - int fill_style; /* FillSolid, FillTiled, + int fill_style; /* FillSolid, FillTiled, FillStippled, FillOpaeueStippled */ int fill_rule; /* EvenOddRule, WindingRule */ int arc_mode; /* ArcChord, ArcPieSlice */ @@ -266,7 +247,7 @@ typedef struct { /* * Depth structure; contains information for each possible depth. - */ + */ typedef struct { int depth; /* this depth (Z) of the depth */ int nvisuals; /* number of Visual types at this depth */ @@ -297,7 +278,7 @@ typedef struct { unsigned long black_pixel; /* White and Black pixel values */ int max_maps, min_maps; /* max and min color maps */ int backing_store; /* Never, WhenMapped, Always */ - Bool save_unders; + Bool save_unders; long root_input_mask; /* initial root input mask */ } Screen; @@ -420,7 +401,7 @@ typedef struct _XImage { } f; } XImage; -/* +/* * Data structure for XReconfigureWindow */ typedef struct { @@ -441,7 +422,7 @@ typedef struct { char pad; } XColor; -/* +/* * Data structures for graphics operations. On most machines, these are * congruent with the wire protocol structures, so reformatting the data * can be avoided on these architectures. @@ -453,12 +434,12 @@ typedef struct { typedef struct { short x, y; } XPoint; - + typedef struct { short x, y; unsigned short width, height; } XRectangle; - + typedef struct { short x, y; unsigned short width, height; @@ -517,7 +498,7 @@ typedef struct _XDisplay Display; struct _XPrivate; /* Forward declare before use for C++ */ struct _XrmHashBucketRec; -typedef struct +typedef struct #ifdef XLIB_ILLEGAL_ACCESS _XDisplay #endif @@ -572,7 +553,7 @@ _XDisplay /* there is more to this structure, but it is private to Xlib */ } #ifdef XLIB_ILLEGAL_ACCESS -Display, +Display, #endif *_XPrivDisplay; @@ -648,7 +629,7 @@ typedef struct { int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */ int detail; /* - * NotifyAncestor, NotifyVirtual, NotifyInferior, + * NotifyAncestor, NotifyVirtual, NotifyInferior, * NotifyNonlinear,NotifyNonlinearVirtual */ Bool same_screen; /* same screen flag */ @@ -668,9 +649,9 @@ typedef struct { NotifyGrab, NotifyUngrab */ int detail; /* - * NotifyAncestor, NotifyVirtual, NotifyInferior, + * NotifyAncestor, NotifyVirtual, NotifyInferior, * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer, - * NotifyPointerRoot, NotifyDetailNone + * NotifyPointerRoot, NotifyDetailNone */ } XFocusChangeEvent; typedef XFocusChangeEvent XFocusInEvent; @@ -684,7 +665,7 @@ typedef struct { Display *display; /* Display the event was read from */ Window window; char key_vector[32]; -} XKeymapEvent; +} XKeymapEvent; typedef struct { int type; @@ -966,6 +947,33 @@ typedef struct { Window window; /* window on which event was requested in event mask */ } XAnyEvent; + +/*************************************************************** + * + * GenericEvent. This event is the standard event for all newer extensions. + */ + +typedef struct + { + int type; /* of event. Always GenericEvent */ + unsigned long serial; /* # of last request processed */ + Bool send_event; /* true if from SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* major opcode of extension that caused the event */ + int evtype; /* actual event type. */ + } XGenericEvent; + +typedef struct { + int type; /* of event. Always GenericEvent */ + unsigned long serial; /* # of last request processed */ + Bool send_event; /* true if from SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* major opcode of extension that caused the event */ + int evtype; /* actual event type. */ + unsigned int cookie; + void *data; +} XGenericEventCookie; + /* * this union is defined so Xlib can always use the same sized * event structure internally, to avoid memory fragmentation. @@ -1003,6 +1011,8 @@ typedef union _XEvent { XMappingEvent xmapping; XErrorEvent xerror; XKeymapEvent xkeymap; + XGenericEvent xgeneric; + XGenericEventCookie xcookie; long pad[24]; } XEvent; #endif @@ -1243,7 +1253,7 @@ typedef struct { typedef unsigned long XIMFeedback; #define XIMReverse 1L -#define XIMUnderline (1L<<1) +#define XIMUnderline (1L<<1) #define XIMHighlight (1L<<2) #define XIMPrimary (1L<<5) #define XIMSecondary (1L<<6) @@ -1255,11 +1265,11 @@ typedef unsigned long XIMFeedback; typedef struct _XIMText { unsigned short length; XIMFeedback *feedback; - Bool encoding_is_wchar; + Bool encoding_is_wchar; union { char *multi_byte; wchar_t *wide_char; - } string; + } string; } XIMText; typedef unsigned long XIMPreeditState; @@ -1289,11 +1299,11 @@ typedef unsigned long XIMStringConversionFeedback; typedef struct _XIMStringConversionText { unsigned short length; XIMStringConversionFeedback *feedback; - Bool encoding_is_wchar; + Bool encoding_is_wchar; union { char *mbs; wchar_t *wcs; - } string; + } string; } XIMStringConversionText; typedef unsigned short XIMStringConversionPosition; @@ -1315,7 +1325,7 @@ typedef enum { XIMForwardWord, XIMBackwardWord, XIMCaretUp, XIMCaretDown, XIMNextLine, XIMPreviousLine, - XIMLineStart, XIMLineEnd, + XIMLineStart, XIMLineEnd, XIMAbsolutePosition, XIMDontChange } XIMCaretDirection; @@ -1336,7 +1346,7 @@ typedef struct _XIMPreeditDrawCallbackStruct { } XIMPreeditDrawCallbackStruct; typedef enum { - XIMIsInvisible, /* Disable caret feedback */ + XIMIsInvisible, /* Disable caret feedback */ XIMIsPrimary, /* UI defined caret feedback */ XIMIsSecondary /* UI defined caret feedback */ } XIMCaretStyle; @@ -1351,7 +1361,7 @@ typedef enum { XIMTextType, XIMBitmapType } XIMStatusDataType; - + typedef struct _XIMStatusDrawCallbackStruct { XIMStatusDataType type; union { @@ -1429,7 +1439,7 @@ extern XModifierKeymap *XInsertModifiermapEntry( #else KeyCode /* keycode_entry */, #endif - int /* modifier */ + int /* modifier */ ); extern XModifierKeymap *XNewModifiermap( @@ -1475,7 +1485,7 @@ extern XImage *XGetSubImage( int /* dest_y */ ); -/* +/* * X function declarations. */ extern Display *XOpenDisplay( @@ -1508,7 +1518,7 @@ extern Status XGetAtomNames( extern char *XGetDefault( Display* /* display */, _Xconst char* /* program */, - _Xconst char* /* option */ + _Xconst char* /* option */ ); extern char *XDisplayName( _Xconst char* /* string */ @@ -1534,7 +1544,7 @@ extern int (*XSetAfterFunction( extern Atom XInternAtom( Display* /* display */, _Xconst char* /* atom_name */, - Bool /* only_if_exists */ + Bool /* only_if_exists */ ); extern Status XInternAtoms( Display* /* dpy */, @@ -1551,7 +1561,7 @@ extern Colormap XCreateColormap( Display* /* display */, Window /* w */, Visual* /* visual */, - int /* alloc */ + int /* alloc */ ); extern Cursor XCreatePixmapCursor( Display* /* display */, @@ -1560,7 +1570,7 @@ extern Cursor XCreatePixmapCursor( XColor* /* foreground_color */, XColor* /* background_color */, unsigned int /* x */, - unsigned int /* y */ + unsigned int /* y */ ); extern Cursor XCreateGlyphCursor( Display* /* display */, @@ -1597,7 +1607,7 @@ extern Pixmap XCreatePixmap( Drawable /* d */, unsigned int /* width */, unsigned int /* height */, - unsigned int /* depth */ + unsigned int /* depth */ ); extern Pixmap XCreateBitmapFromData( Display* /* display */, @@ -1644,7 +1654,7 @@ extern Window XCreateWindow( Visual* /* visual */, unsigned long /* valuemask */, XSetWindowAttributes* /* attributes */ -); +); extern Colormap *XListInstalledColormaps( Display* /* display */, Window /* w */, @@ -1939,7 +1949,7 @@ extern int XAddHost( extern int XAddHosts( Display* /* display */, XHostAddress* /* hosts */, - int /* num_hosts */ + int /* num_hosts */ ); extern int XAddToExtensionList( @@ -2183,7 +2193,7 @@ extern int XConfigureWindow( Display* /* display */, Window /* w */, unsigned int /* value_mask */, - XWindowChanges* /* values */ + XWindowChanges* /* values */ ); extern int XConnectionNumber( @@ -2269,7 +2279,7 @@ extern int XDestroySubwindows( ); extern int XDoesBackingStore( - Screen* /* screen */ + Screen* /* screen */ ); extern Bool XDoesSaveUnders( @@ -2554,7 +2564,7 @@ extern int XFreeCursor( ); extern int XFreeExtensionList( - char** /* list */ + char** /* list */ ); extern int XFreeFont( @@ -2928,7 +2938,7 @@ extern int XPutImage( int /* dest_x */, int /* dest_y */, unsigned int /* width */, - unsigned int /* height */ + unsigned int /* height */ ); extern int XQLength( @@ -3018,7 +3028,7 @@ extern int XQueryTextExtents( int* /* direction_return */, int* /* font_ascent_return */, int* /* font_descent_return */, - XCharStruct* /* overall_return */ + XCharStruct* /* overall_return */ ); extern int XQueryTextExtents16( @@ -3083,7 +3093,7 @@ extern int XRecolorCursor( ); extern int XRefreshKeyboardMapping( - XMappingEvent* /* event_map */ + XMappingEvent* /* event_map */ ); extern int XRemoveFromSaveSet( @@ -3239,7 +3249,7 @@ extern int XSetFont( extern int XSetFontPath( Display* /* display */, char** /* directories */, - int /* ndirs */ + int /* ndirs */ ); extern int XSetForeground( @@ -3538,7 +3548,7 @@ extern int XWarpPointer( unsigned int /* src_width */, unsigned int /* src_height */, int /* dest_x */, - int /* dest_y */ + int /* dest_y */ ); extern int XWidthMMOfScreen( @@ -3563,7 +3573,7 @@ extern int XWriteBitmapFile( unsigned int /* width */, unsigned int /* height */, int /* x_hot */, - int /* y_hot */ + int /* y_hot */ ); extern Bool XSupportsLocale (void); @@ -3971,7 +3981,7 @@ typedef void (*XConnectionWatchProc)( Bool /* opening */, /* open or close flag */ XPointer* /* watch_data */ /* open sets, close uses */ ); - + extern Status XInternalConnectionNumbers( Display* /* dpy */, @@ -3998,7 +4008,7 @@ extern void XRemoveConnectionWatch( extern void XSetAuthorization( char * /* name */, - int /* namelen */, + int /* namelen */, char * /* data */, int /* datalen */ ); @@ -4019,6 +4029,16 @@ extern int _Xwctomb( wchar_t /* wc */ ); +extern Bool XGetEventData( + Display* /* dpy */, + XGenericEventCookie* /* cookie*/ +); + +extern void XFreeEventData( + Display* /* dpy */, + XGenericEventCookie* /* cookie*/ +); + _XFUNCPROTOEND #endif /* _XLIB_H_ */ diff --git a/nx-X11/lib/X11/XlibAsync.c b/nx-X11/lib/X11/XlibAsync.c index d289970ee..57cf3e199 100644 --- a/nx-X11/lib/X11/XlibAsync.c +++ b/nx-X11/lib/X11/XlibAsync.c @@ -1,28 +1,3 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder */ -/* Copyright (c) 2011-2016 Mike Gabriel */ -/* Copyright (c) 2014-2016 Mihai Moldovan */ -/* Copyright (c) 2014-2016 Ulrich Sibiller */ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* nx-X11, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE which comes in the source */ -/* distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - /* Copyright 1992, 1998 The Open Group @@ -59,12 +34,12 @@ from The Open Group. /*ARGSUSED*/ Bool -_XAsyncErrorHandler(dpy, rep, buf, len, data) - register Display *dpy; - register xReply *rep; - char *buf; - int len; - XPointer data; +_XAsyncErrorHandler( + register Display *dpy, + register xReply *rep, + char *buf, + int len, + XPointer data) { register _XAsyncErrorState *state; @@ -87,9 +62,9 @@ _XAsyncErrorHandler(dpy, rep, buf, len, data) return False; } -void _XDeqAsyncHandler(dpy, handler) - Display *dpy; - register _XAsyncHandler *handler; +void _XDeqAsyncHandler( + Display *dpy, + register _XAsyncHandler *handler) { register _XAsyncHandler **prev; register _XAsyncHandler *async; @@ -103,14 +78,14 @@ void _XDeqAsyncHandler(dpy, handler) } char * -_XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) - register Display *dpy; - register char *replbuf; /* data is read into this buffer */ - register xReply *rep; /* value passed to calling handler */ - char *buf; /* value passed to calling handler */ - int len; /* value passed to calling handler */ - int extra; /* extra words to read, ala _XReply */ - Bool discard; /* discard after extra?, ala _XReply */ +_XGetAsyncReply( + register Display *dpy, + register char *replbuf, /* data is read into this buffer */ + register xReply *rep, /* value passed to calling handler */ + char *buf, /* value passed to calling handler */ + int len, /* value passed to calling handler */ + int extra, /* extra words to read, ala _XReply */ + Bool discard) /* discard after extra?, ala _XReply */ { if (extra == 0) { if (discard && (rep->generic.length << 2) > len) @@ -125,6 +100,11 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) _XRead(dpy, replbuf + len, size - len); buf = replbuf; len = size; +#ifdef MUSTCOPY + } else { + memcpy(replbuf, buf, size); + buf = replbuf; +#endif } if (discard && rep->generic.length > extra && @@ -133,9 +113,9 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) return buf; } - /* + /* *if we get here, then extra > rep->generic.length--meaning we - * read a reply that's shorter than we expected. This is an + * read a reply that's shorter than we expected. This is an * error, but we still need to figure out how to handle it... */ if ((rep->generic.length << 2) > len) @@ -153,15 +133,15 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) } void -_XGetAsyncData(dpy, data, buf, len, skip, datalen, discardtotal) - Display *dpy; - char *data; /* data is read into this buffer */ - char *buf; /* value passed to calling handler */ - int len; /* value passed to calling handler */ - int skip; /* number of bytes already read in previous +_XGetAsyncData( + Display *dpy, + char *data, /* data is read into this buffer */ + char *buf, /* value passed to calling handler */ + int len, /* value passed to calling handler */ + int skip, /* number of bytes already read in previous _XGetAsyncReply or _XGetAsyncData calls */ - int datalen; /* size of data buffer in bytes */ - int discardtotal; /* min. bytes to consume (after skip) */ + int datalen, /* size of data buffer in bytes */ + int discardtotal) /* min. bytes to consume (after skip) */ { buf += skip; len -= skip; diff --git a/nx-X11/lib/X11/XlibInt.c b/nx-X11/lib/X11/XlibInt.c index 7c26b13cb..8a622d55d 100644 --- a/nx-X11/lib/X11/XlibInt.c +++ b/nx-X11/lib/X11/XlibInt.c @@ -63,9 +63,13 @@ from The Open Group. #include #endif #include "Xlibint.h" +#include "Xprivate.h" #include +#if !USE_XCB #include #include +#endif /* !USE_XCB */ +#include #include #ifdef WIN32 #include @@ -97,6 +101,7 @@ xthread_t (*_Xthread_self_fn)(void) = NULL; #define XThread_Self() ((*_Xthread_self_fn)()) +#if !USE_XCB #define UnlockNextReplyReader(d) if ((d)->lock) \ (*(d)->lock->pop_reader)((d),&(d)->lock->reply_awaiters,&(d)->lock->reply_awaiters_tail) @@ -104,20 +109,14 @@ xthread_t (*_Xthread_self_fn)(void) = NULL; (*(d)->lock->push_reader)(d,&(d)->lock->reply_awaiters_tail) : NULL) #define QueueEventReaderLock(d) ((d)->lock ? \ (*(d)->lock->push_reader)(d,&(d)->lock->event_awaiters_tail) : NULL) - -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) -#define InternalLockDisplay(d,wskip) if ((d)->lock) \ - (*(d)->lock->internal_lock_display)(d,wskip,__FILE__,__LINE__) -#else -#define InternalLockDisplay(d,wskip) if ((d)->lock) \ - (*(d)->lock->internal_lock_display)(d,wskip) -#endif +#endif /* !USE_XCB */ #else /* XTHREADS else */ -#define UnlockNextReplyReader(d) +#if !USE_XCB +#define UnlockNextReplyReader(d) #define UnlockNextEventReader(d) -#define InternalLockDisplay(d,wskip) +#endif /* !USE_XCB */ #endif /* XTHREADS else */ @@ -171,20 +170,20 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *); #endif /* WIN32 */ #ifdef WIN32 -#define ECHECK(err) (WSAGetLastError() == err) -#define ESET(val) WSASetLastError(val) -#else -#ifdef __UNIXOS2__ -#define ECHECK(err) (errno == err) -#define ESET(val) +# define ECHECK(err) (WSAGetLastError() == err) +# define ESET(val) WSASetLastError(val) #else -#ifdef ISC -#define ECHECK(err) ((errno == err) || ETEST()) -#else -#define ECHECK(err) (errno == err) -#endif -#define ESET(val) errno = val -#endif +# ifdef __UNIXOS2__ +# define ECHECK(err) (errno == err) +# define ESET(val) +# else +# ifdef ISC +# define ECHECK(err) ((errno == err) || ETEST()) +# else +# define ECHECK(err) (errno == err) +# endif +# define ESET(val) errno = val +# endif #endif #if defined(LOCALCONN) || defined(LACHMAN) @@ -200,11 +199,28 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *); #endif #ifdef __UNIXOS2__ +#if !USE_XCB #define select(n,r,w,x,t) os2ClientSelect(n,r,w,x,t) +#endif /* !USE_XCB */ #include #define MAX_PATH _POSIX_PATH_MAX #endif +#if !USE_XCB +#ifdef MUSTCOPY + +#define STARTITERATE(tpvar,type,start,endcond) \ + { register char *cpvar; \ + for (cpvar = (char *) (start); endcond; ) { \ + type dummy; memcpy ((char *) &dummy, cpvar, SIZEOF(type)); \ + tpvar = &dummy; +#define ITERPTR(tpvar) cpvar +#define RESETITERPTR(tpvar,type,start) cpvar = start +#define INCITERPTR(tpvar,type) cpvar += SIZEOF(type) +#define ENDITERATE }} + +#else + #define STARTITERATE(tpvar,type,start,endcond) \ for (tpvar = (type *) (start); endcond; ) #define ITERPTR(tpvar) (char *)tpvar @@ -212,6 +228,8 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *); #define INCITERPTR(tpvar,type) tpvar++ #define ENDITERATE +#endif /* MUSTCOPY */ + typedef union { xReply rep; char buf[BUFSIZE]; @@ -223,12 +241,7 @@ static char *_XAsyncReply( char *buf, register int *lenp, Bool discard); - -static void _XProcessInternalConnection( - Display *dpy, - struct _XConnectionInfo *conn_info); - -#define SEQLIMIT (65535 - (BUFSIZE / SIZEOF(xReq)) - 10) +#endif /* !USE_XCB */ /* * The following routines are internal routines used by Xlib for protocol @@ -243,11 +256,12 @@ static void _XProcessInternalConnection( * perform any operations (directly or indirectly) on the DISPLAY. * * Routines declared with a return type of 'Status' return 0 on failure, - * and non 0 on success. Routines with no declared return type don't + * and non 0 on success. Routines with no declared return type don't * return anything. Whenever possible routines that create objects return * the object they have created. */ +#if !USE_XCB static xReq _dummy_request = { 0, 0, 0 }; @@ -409,7 +423,7 @@ _XWaitForWritable( XXX - what if cv is NULL and someone else comes along after us while we are waiting? */ - + if (!dpy->lock || (!dpy->lock->event_awaiters && (!dpy->lock->reply_awaiters || @@ -417,58 +431,28 @@ _XWaitForWritable( #endif #ifndef NX_TRANS_SOCKET -#ifdef USE_POLL +# ifdef USE_POLL filedes.events = POLLIN; filedes.events |= POLLOUT; -#else +# else FD_SET(dpy->fd, &r_mask); FD_SET(dpy->fd, &w_mask); -#endif +# endif #endif /* #ifndef NX_TRANS_SOCKET */ do { -#ifdef NX_TRANS_SOCKET - /* - * Give a chance to the registered client to perform - * any needed operation before entering the select. - */ - -#ifdef NX_TRANS_TEST - fprintf(stderr, "_XWaitForWritable: WAIT! Waiting for the display to become writable.\n"); -#endif - NXTransFlush(dpy->fd); - - if (_NXDisplayBlockFunction != NULL) { - (*_NXDisplayBlockFunction)(dpy, NXBlockWrite); - } - - /* - * Need to set again the descriptors as we could have - * run multiple selects before having the possibility - * to read or write to the X connection. - */ - -#ifdef USE_POLL - filedes.events = POLLIN; - filedes.events |= POLLOUT; -#else - FD_SET(dpy->fd, &r_mask); - FD_SET(dpy->fd, &w_mask); -#endif -#endif /* #ifdef NX_TRANS_SOCKET */ - UnlockDisplay(dpy); #ifdef USE_POLL -#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) +# if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) fprintf(stderr, "_XWaitForWritable: Calling poll().\n"); -#endif +# endif nfound = poll (&filedes, 1, -1); -#else -#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) +#else /* USE_POLL */ +# if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) fprintf(stderr, "_XWaitForWritable: Calling select() after [%ld] ms.\n", NXTransTime()); -#endif -#ifdef NX_TRANS_SOCKET +# endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) */ +# ifdef NX_TRANS_SOCKET /* * Give a chance to the callback to detect * the failure of the display even if we @@ -482,10 +466,10 @@ _XWaitForWritable( } else { nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL); } -#else +# else /* NX_TRANS_SOCKET */ nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL); -#endif -#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) +# endif /* NX_TRANS_SOCKET */ +# if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) fprintf(stderr, "_XWaitForWritable: Out of select() with [%d] after [%ld] ms.\n", nfound, NXTransTime()); @@ -504,37 +488,37 @@ _XWaitForWritable( fprintf(stderr, "_XWaitForWritable: Descriptor [%d] has become writable.\n\n", dpy->fd); } -#endif -#endif +# endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) */ +#endif /* USE_POLL */ InternalLockDisplay(dpy, cv != NULL); #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE) if (_NXDisplayCongestionFunction != NULL && _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) { (*_NXDisplayCongestionFunction)(dpy, congestion); } -#endif +#endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE) */ #ifdef NX_TRANS_SOCKET if (nfound <= 0) { - if ((nfound == -1 && !ECHECK(EINTR)) || + if ((nfound == -1 && !(ECHECK(EINTR) || ETEST())) || (_NXDisplayErrorFunction != NULL && (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) { _XIOError(dpy); return; } } -#else - if (nfound < 0 && !ECHECK(EINTR)) +#else /* NX_TRANS_SOCKET */ + if (nfound < 0 && !(ECHECK(EINTR) || ETEST())) _XIOError(dpy); -#endif +#endif /* NX_TRANS_SOCKET */ } while (nfound <= 0); if ( #ifdef USE_POLL filedes.revents & POLLIN -#else +#else /* USE_POLL */ FD_ISSET(dpy->fd, &r_mask) -#endif +#endif /* USE_POLL */ ) { _XAlignedBuffer buf; @@ -550,9 +534,9 @@ _XWaitForWritable( return; } -#else +#else /* NX_TRANS_SOCKET */ _XIOError(dpy); -#endif +#endif /* NX_TRANS_SOCKET */ len = pend; /* must read at least one xEvent; if none is pending, then @@ -563,7 +547,7 @@ _XWaitForWritable( #endif ) len = SIZEOF(xReply); - + /* but we won't read more than the max buffer size */ if (len > BUFSIZE) len = BUFSIZE; @@ -609,6 +593,7 @@ _XWaitForWritable( } } } +#endif /* !USE_XCB */ #define POLLFD_CACHE_SIZE 5 @@ -666,6 +651,7 @@ void _XPollfdCacheDel( #endif } +#if !USE_XCB /* returns True iff there is an event in the queue newer than serial_num */ static Bool @@ -694,7 +680,7 @@ _XWaitForReadable( { int result; int fd = dpy->fd; - struct _XConnectionInfo *ilist; + struct _XConnectionInfo *ilist; register int saved_event_serial = 0; int in_read_events = 0; register Bool did_proc_conni = False; @@ -730,9 +716,9 @@ _XWaitForReadable( } else { filedes = (struct pollfd *)dpy->filedes; } -#else +#else /* USE_POLL */ FD_ZERO(&r_mask); -#endif +#endif /* USE_POLL */ for (;;) { #ifndef USE_POLL FD_SET(fd, &r_mask); @@ -742,7 +728,7 @@ _XWaitForReadable( if (ilist->fd > highest_fd) highest_fd = ilist->fd; } -#endif +#endif /* USE_POLL */ UnlockDisplay(dpy); #ifdef USE_POLL #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) @@ -751,7 +737,7 @@ _XWaitForReadable( result = poll(filedes, (dpy->flags & XlibDisplayProcConni) ? 1 : 1+dpy->im_fd_length, -1); -#else +#else /* USE_POLL */ #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) fprintf(stderr, "_XWaitForReadable: Calling select().\n"); #endif @@ -777,36 +763,19 @@ _XWaitForReadable( } else { result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL); } -#else +#else /* NX_TRANS_SOCKET */ result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL); -#endif -#endif +#endif /* NX_TRANS_SOCKET */ +#endif /* USE_POLL */ #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) fprintf(stderr, "_XWaitForReadable: Out of select with result [%d] and errno [%d].\n", result, (result < 0 ? errno : 0)); #endif InternalLockDisplay(dpy, dpy->flags & XlibDisplayReply); -#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE) - if (_NXDisplayCongestionFunction != NULL && - _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) { - (*_NXDisplayCongestionFunction)(dpy, congestion); - } -#endif -#ifdef NX_TRANS_SOCKET - if (result <= 0) { - if ((result == -1 && !ECHECK(EINTR)) || - (_NXDisplayErrorFunction != NULL && - (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) { - _XIOError(dpy); - return -1; - } - continue; - } -#else - if (result == -1 && !ECHECK(EINTR)) _XIOError(dpy); + if (result == -1 && !(ECHECK(EINTR) || ETEST())) _XIOError(dpy); if (result <= 0) continue; -#endif + #ifdef USE_POLL if (filedes[0].revents & (POLLIN|POLLHUP|POLLERR)) #else @@ -856,9 +825,32 @@ _XWaitForReadable( #endif return 0; } +#endif /* !USE_XCB */ + +static int sync_hazard(Display *dpy) +{ + unsigned long span = dpy->request - dpy->last_request_read; + unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10); + return span >= 65535 - hazard - 10; +} static -int _XSeqSyncFunction( +void sync_while_locked(Display *dpy) +{ +#ifdef XTHREADS + if (dpy->lock) + (*dpy->lock->user_lock_display)(dpy); +#endif + UnlockDisplay(dpy); + SyncHandle(); + InternalLockDisplay(dpy, /* don't skip user locks */ 0); +#ifdef XTHREADS + if (dpy->lock) + (*dpy->lock->user_unlock_display)(dpy); +#endif +} + +void _XSeqSyncFunction( register Display *dpy) { xGetInputFocusReply rep; @@ -868,30 +860,63 @@ int _XSeqSyncFunction( #ifdef NX_TRANS_DEBUG fprintf(stderr, "_XSeqSyncFunction: Going to synchronize the display.\n"); #endif + if (dpy->flags & XlibDisplayIOError) { #ifdef NX_TRANS_DEBUG fprintf(stderr, "_XSeqSyncFunction: Returning 0 with I/O error detected.\n"); #endif - return 0; + return; } -#endif +#endif /* NX_TRANS_SOCKET */ - LockDisplay(dpy); - if ((dpy->request - dpy->last_request_read) >= (BUFSIZE / SIZEOF(xReq))) { + if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) { GetEmptyReq(GetInputFocus, req); (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); - } - /* could get XID handler while waiting for reply in MT env */ - if (dpy->synchandler == _XSeqSyncFunction) { - dpy->synchandler = dpy->savedsynchandler; - dpy->flags &= ~XlibDisplayPrivSync; - } - UnlockDisplay(dpy); - SyncHandle(); + sync_while_locked(dpy); + } else if (sync_hazard(dpy)) + _XSetPrivSyncFunction(dpy); +} + +/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */ +static int +_XPrivSyncFunction (Display *dpy) +{ +#if XTHREADS + assert(!dpy->lock_fns); +#endif + assert(dpy->synchandler == _XPrivSyncFunction); + assert((dpy->flags & XlibDisplayPrivSync) != 0); + dpy->synchandler = dpy->savedsynchandler; + dpy->savedsynchandler = NULL; + dpy->flags &= ~XlibDisplayPrivSync; + if(dpy->synchandler) + dpy->synchandler(dpy); + _XIDHandler(dpy); + _XSeqSyncFunction(dpy); return 0; } +void _XSetPrivSyncFunction(Display *dpy) +{ +#ifdef XTHREADS + if (dpy->lock_fns) + return; +#endif + if (!(dpy->flags & XlibDisplayPrivSync)) { + dpy->savedsynchandler = dpy->synchandler; + dpy->synchandler = _XPrivSyncFunction; + dpy->flags |= XlibDisplayPrivSync; + } +} + +void _XSetSeqSyncFunction(Display *dpy) +{ + if (sync_hazard(dpy)) + _XSetPrivSyncFunction (dpy); +} + +#if !USE_XCB #ifdef XTHREADS static void _XFlushInt( register Display *dpy, @@ -936,7 +961,7 @@ static void _XFlushInt( #endif /* This fix resets the bufptr to the front of the buffer so * additional appends to the bufptr will not corrupt memory. Since - * the server is down, these appends are no-op's anyway but + * the server is down, these appends are no-op's anyway but * callers of _XFlush() are not verifying this before they call it. */ if (dpy->flags & XlibDisplayIOError) @@ -1015,7 +1040,7 @@ static void _XFlushInt( #endif #ifdef ESZTEST } else if (ESZTEST()) { - if (todo > 1) + if (todo > 1) todo >>= 1; else { _XWaitForWritable(dpy @@ -1046,12 +1071,7 @@ static void _XFlushInt( #endif } dpy->last_req = (char *)&_dummy_request; - if ((dpy->request - dpy->last_request_read) >= SEQLIMIT && - !(dpy->flags & XlibDisplayPrivSync)) { - dpy->savedsynchandler = dpy->synchandler; - dpy->synchandler = _XSeqSyncFunction; - dpy->flags |= XlibDisplayPrivSync; - } + _XSetSeqSyncFunction(dpy); dpy->bufptr = dpy->buffer; #ifdef XTHREADS dpy->flags &= ~XlibDisplayWriting; @@ -1192,7 +1212,7 @@ _XEventsQueued( } #ifdef NX_TRANS_SOCKET if (result <= 0) { - if ((result == -1 && !ECHECK(EINTR)) || + if ((result == -1 && !(ECHECK(EINTR) || ETEST())) || (_NXDisplayErrorFunction != NULL && (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) { _XIOError(dpy); @@ -1200,9 +1220,9 @@ _XEventsQueued( } } #else - else if (result < 0 && !ECHECK(EINTR)) - _XIOError(dpy); + else if (result < 0 && !(ECHECK(EINTR) || ETEST())) #endif + _XIOError(dpy); } } #endif /* XCONN_CHECK_FREQ */ @@ -1233,7 +1253,7 @@ _XEventsQueued( #endif /* XTHREADS*/ { read_buf = buf.buf; - + if (len < SIZEOF(xReply) #ifdef XTHREADS || dpy->async_handlers @@ -1249,7 +1269,7 @@ _XEventsQueued( #endif (void) _XRead (dpy, read_buf, (long) len); - + #ifdef NX_TRANS_SOCKET if (_XGetIOError(dpy)) { return(dpy->qlen); @@ -1360,7 +1380,7 @@ void _XReadEvents( return; } #else - _XIOError(dpy); + _XIOError(dpy); #endif len = pend; @@ -1462,12 +1482,22 @@ void _XReadEvents( RESETITERPTR(rep,xReply, _XAsyncReply (dpy, rep, ITERPTR(rep), &len, True)); - pend = len; + pend = len; } else { if (rep->generic.type == X_Error) _XError (dpy, (xError *) rep); else /* must be an event packet */ - _XEnq (dpy, (xEvent *)rep); + { + if (rep->generic.type == GenericEvent) + { + int evlen; + evlen = (rep->generic.length << 2); + if (_XRead(dpy, &read_buf[len], evlen) == -2) + goto got_event; /* XXX: aargh! */ + } + + _XEnq (dpy, (xEvent *)rep); + } INCITERPTR(rep,xReply); len -= SIZEOF(xReply); } @@ -1477,7 +1507,7 @@ void _XReadEvents( UnlockNextEventReader(dpy); } -/* +/* * _XRead - Read bytes from the socket taking into account incomplete * reads. This routine may have to be reworked if int < long. */ @@ -1577,6 +1607,7 @@ int _XRead( #endif /* XTHREADS*/ return 0; } +#endif /* !USE_XCB */ #ifdef LONG64 void _XRead32( @@ -1598,7 +1629,127 @@ void _XRead32( } #endif /* LONG64 */ +#ifdef WORD64 + +/* + * XXX This is a *really* stupid way of doing this.... + * PACKBUFFERSIZE must be a multiple of 4. + */ + +#define PACKBUFFERSIZE 4096 + +/* + * _XRead32 - Read bytes from the socket unpacking each 32 bits + * into a long (64 bits on a CRAY computer). + * + */ +static void _doXRead32( + register Display *dpy, + register long *data + register long size, + register char *packbuffer) +{ + long *lpack,*lp; + long mask32 = 0x00000000ffffffff; + long maskw, nwords, i, bits; + + _XReadPad (dpy, packbuffer, size); + + lp = data; + lpack = (long *) packbuffer; + nwords = size >> 2; + bits = 32; + + for(i=0;i> bits; + bits = bits ^32; + if(bits){ + lpack++; + } + } +} + +void _XRead32( + Display *dpy, + long *data, + long len) +{ + char packbuffer[PACKBUFFERSIZE]; + unsigned nunits = PACKBUFFERSIZE >> 2; + + for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { + _doXRead32 (dpy, data, PACKBUFFERSIZE, packbuffer); + } + if (len) _doXRead32 (dpy, data, len, packbuffer); +} + + + +/* + * _XRead16 - Read bytes from the socket unpacking each 16 bits + * into a long (64 bits on a CRAY computer). + * + */ +static _doXRead16( + register Display *dpy, + register short *data, + register long size, + char *packbuffer) +{ + long *lpack,*lp; + long mask16 = 0x000000000000ffff; + long maskw, nwords, i, bits; + + (void) _XRead(dpy,packbuffer,size); /* don't do a padded read... */ + + lp = (long *) data; + lpack = (long *) packbuffer; + nwords = size >> 1; /* number of 16 bit words to be unpacked */ + bits = 48; + for(i=0;i> bits; + bits -= 16; + if(bits < 0){ + lpack++; + bits = 48; + } + } +} + +void _XRead16( + Display *dpy, + short *data, + long len) +{ + char packbuffer[PACKBUFFERSIZE]; + unsigned nunits = PACKBUFFERSIZE >> 1; + + for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { + _doXRead16 (dpy, data, PACKBUFFERSIZE, packbuffer); + } + if (len) _doXRead16 (dpy, data, len, packbuffer); +} + +void _XRead16Pad( + Display *dpy, + short *data, + long size) +{ + int slop = (size & 3); + short slopbuf[3]; + + _XRead16 (dpy, data, size); + if (slop > 0) { + _XRead16 (dpy, slopbuf, 4 - slop); + } +} +#endif /* WORD64 */ + + +#if !USE_XCB /* * _XReadPad - Read bytes from the socket taking into account incomplete * reads. If the number of bytes is not 0 mod 4, read additional pad @@ -1622,7 +1773,7 @@ void _XReadPad( if ((dpy->flags & XlibDisplayIOError) || size == 0) return; iov[0].iov_len = (int)size; iov[0].iov_base = data; - /* + /* * The following hack is used to provide 32 bit long-word * aligned padding. The [1] vector is of length 0, 1, 2, or 3, * whatever is needed. @@ -1683,7 +1834,7 @@ void _XReadPad( _XIOError(dpy); #endif } - + else /* bytes_read is less than 0; presumably -1 */ { /* If it's a system call interrupt, it's not an error. */ #ifdef NX_TRANS_SOCKET @@ -1820,7 +1971,7 @@ _XSend ( InsertIOV (dpy->buffer, dbufsize) InsertIOV ((char *)data, size) InsertIOV ((char *)pad, padsize) - + ESET(0); if ((len = _X11TransWritev(dpy->trans_conn, iov, i)) >= 0) { #ifdef NX_TRANS_SOCKET @@ -1853,7 +2004,7 @@ _XSend ( #endif #ifdef ESZTEST } else if (ESZTEST()) { - if (todo > 1) + if (todo > 1) todo >>= 1; else { _XWaitForWritable(dpy @@ -1882,12 +2033,7 @@ _XSend ( #endif } dpy->last_req = (char *) & _dummy_request; - if ((dpy->request - dpy->last_request_read) >= SEQLIMIT && - !(dpy->flags & XlibDisplayPrivSync)) { - dpy->savedsynchandler = dpy->synchandler; - dpy->synchandler = _XSeqSyncFunction; - dpy->flags |= XlibDisplayPrivSync; - } + _XSetSeqSyncFunction(dpy); dpy->bufptr = dpy->buffer; #ifdef XTHREADS dpy->flags &= ~XlibDisplayWriting; @@ -1925,35 +2071,30 @@ _XGetMiscCode( } } -static int +void _XIDHandler( register Display *dpy) { xXCMiscGetXIDRangeReply grep; register xXCMiscGetXIDRangeReq *greq; - LockDisplay(dpy); - _XGetMiscCode(dpy); - if (dpy->xcmisc_opcode > 0) { - GetReq(XCMiscGetXIDRange, greq); - greq->reqType = dpy->xcmisc_opcode; - greq->miscReqType = X_XCMiscGetXIDRange; - if (_XReply (dpy, (xReply *)&grep, 0, xTrue) && grep.count) { - dpy->resource_id = ((grep.start_id - dpy->resource_base) >> - dpy->resource_shift); - dpy->resource_max = dpy->resource_id; - if (grep.count > 5) - dpy->resource_max += grep.count - 6; - dpy->resource_max <<= dpy->resource_shift; + if (dpy->resource_max == dpy->resource_mask + 1) { + _XGetMiscCode(dpy); + if (dpy->xcmisc_opcode > 0) { + GetReq(XCMiscGetXIDRange, greq); + greq->reqType = dpy->xcmisc_opcode; + greq->miscReqType = X_XCMiscGetXIDRange; + if (_XReply (dpy, (xReply *)&grep, 0, xTrue) && grep.count) { + dpy->resource_id = ((grep.start_id - dpy->resource_base) >> + dpy->resource_shift); + dpy->resource_max = dpy->resource_id; + if (grep.count > 5) + dpy->resource_max += grep.count - 6; + dpy->resource_max <<= dpy->resource_shift; + } + sync_while_locked(dpy); } } - if (dpy->flags & XlibDisplayPrivSync) { - dpy->synchandler = dpy->savedsynchandler; - dpy->flags &= ~XlibDisplayPrivSync; - } - UnlockDisplay(dpy); - SyncHandle(); - return 0; } /* @@ -1966,11 +2107,7 @@ XID _XAllocID( id = dpy->resource_id << dpy->resource_shift; if (id >= dpy->resource_max) { - if (!(dpy->flags & XlibDisplayPrivSync)) { - dpy->savedsynchandler = dpy->synchandler; - dpy->flags |= XlibDisplayPrivSync; - } - dpy->synchandler = _XIDHandler; + _XSetPrivSyncFunction(dpy); dpy->resource_max = dpy->resource_mask + 1; } if (id <= dpy->resource_mask) { @@ -2026,11 +2163,7 @@ void _XAllocIDs( dpy->resource_id = id; } if (id >= dpy->resource_max) { - if (!(dpy->flags & XlibDisplayPrivSync)) { - dpy->savedsynchandler = dpy->synchandler; - dpy->flags |= XlibDisplayPrivSync; - } - dpy->synchandler = _XIDHandler; + _XSetPrivSyncFunction(dpy); dpy->resource_max = dpy->resource_mask + 1; } } @@ -2038,6 +2171,7 @@ void _XAllocIDs( for (i = grep.count; i < count; i++) ids[i] = XAllocID(dpy); } +#endif /* !USE_XCB */ /* * The hard part about this is that we only get 16 bits from a reply. @@ -2090,7 +2224,7 @@ _XSetLastRequestRead( (void) fprintf (stderr, "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n", - newseq, dpy->request, + newseq, dpy->request, (unsigned int) rep->type); #endif /* #ifdef NX_TRANS_SOCKET */ @@ -2103,6 +2237,7 @@ _XSetLastRequestRead( return(newseq); } +#if !USE_XCB /* * _XReply - Wait for a reply packet and copy its contents into the * specified rep. Meanwhile we must handle error and event packets that @@ -2212,9 +2347,9 @@ _XReply ( } if (extra <= rep->generic.length) { if (extra > 0) - /* + /* * Read the extra data into storage immediately - * following the GenericReply structure. + * following the GenericReply structure. */ (void) _XRead (dpy, (char *) (NEXTPTR(rep,xReply)), ((long)extra) << 2); @@ -2239,9 +2374,9 @@ _XReply ( #endif return 1; } - /* + /* *if we get here, then extra > rep->generic.length--meaning we - * read a reply that's shorter than we expected. This is an + * read a reply that's shorter than we expected. This is an * error, but we still need to figure out how to handle it... */ (void) _XRead (dpy, (char *) (NEXTPTR(rep,xReply)), @@ -2290,12 +2425,12 @@ _XReply ( UnlockNextReplyReader(dpy); return (0); } - /* + /* * we better see if there is an extension who may * want to suppress the error. */ for (ext = dpy->ext_procs; !ret && ext; ext = ext->next) { - if (ext->error) + if (ext->error) ret = (*ext->error)(dpy, err, &ext->codes, &ret_code); } if (!ret) { @@ -2324,7 +2459,7 @@ _XReply ( } #endif } -} +} static char * _XAsyncReply( @@ -2355,7 +2490,7 @@ _XAsyncReply( *lenp = 0; return buf; } - + for (async = dpy->async_handlers; async; async = next) { next = async->next; if ((consumed = (*async->handler)(dpy, rep, buf, *lenp, async->data))) @@ -2364,7 +2499,7 @@ _XAsyncReply( if (!consumed) { if (!discard) return buf; - (void) fprintf(stderr, + (void) fprintf(stderr, "Xlib: unexpected async reply (sequence 0x%lx)!\n", dpy->last_request_read); #ifdef XTHREADS @@ -2415,6 +2550,7 @@ _XAsyncReply( } return nbuf; } +#endif /* !USE_XCB */ /* * Support for internal connections, such as an IM might use. @@ -2572,12 +2708,12 @@ XInternalConnectionNumbers( return 1; } -static void _XProcessInternalConnection( +void _XProcessInternalConnection( Display *dpy, struct _XConnectionInfo *conn_info) { dpy->flags |= XlibDisplayProcConni; -#ifdef XTHREADS +#if defined(XTHREADS) && !USE_XCB if (dpy->lock) { /* check cache to avoid call to thread_self */ if (xthread_have_id(dpy->lock->reading_thread)) @@ -2585,14 +2721,14 @@ static void _XProcessInternalConnection( else dpy->lock->conni_thread = XThread_Self(); } -#endif /* XTHREADS */ +#endif /* XTHREADS && !USE_XCB */ UnlockDisplay(dpy); (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data); LockDisplay(dpy); -#ifdef XTHREADS +#if defined(XTHREADS) && !USE_XCB if (dpy->lock) xthread_clear_id(dpy->lock->conni_thread); -#endif /* XTHREADS */ +#endif /* XTHREADS && !USE_XCB */ dpy->flags &= ~XlibDisplayProcConni; } @@ -2688,7 +2824,7 @@ XAddConnectionWatch( * Unregister a callback registered by XAddConnectionWatch. * Both callback and client_data must match what was passed to * XAddConnectionWatch. - */ + */ void XRemoveConnectionWatch( Display* dpy, @@ -2733,6 +2869,7 @@ XRemoveConnectionWatch( /* end of internal connections support */ +#if !USE_XCB /* Read and discard "n" 8-bit bytes of data */ void _XEatData( @@ -2753,29 +2890,128 @@ void _XEatData( } #undef SCRATCHSIZE } +#endif /* !USE_XCB */ -/* - Port from libXfixes commit - b031e3b60fa1af9e49449f23d4a84395868be3ab We need this here to - enable linking of current libXrender against libNX_X11 instead of - the system's libX11 - - The original implementation of this function (libX11 commit - 9f5d83706543696fc944c1835a403938c06f2cc5) uses xcb stuff which we - do not have in libNX_X11. So we take a workaround from another - lib. This workaround had been implemented temporarily in a couple - of X libs, see e.g. https://lists.x.org/archives/xorg-devel/2013-July/036763.html. -*/ -#include /* for LONG64 on 64-bit platforms */ -#include +/* Cookie jar implementation + dpy->cookiejar is a linked list. _XEnq receives the events but leaves + them in the normal EQ. _XStoreEvent returns the cookie event (minus + data pointer) and adds it to the cookiejar. _XDeq just removes + the entry like any other event but resets the data pointer for + cookie events (to avoid double-free, the memory is re-used by Xlib). + + _XFetchEventCookie (called from XGetEventData) removes a cookie from the + jar. _XFreeEventCookies removes all unclaimed cookies from the jar + (called by XNextEvent). + + _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the + normal EQ. + */ -void _XEatDataWords(Display *dpy, unsigned long n) +#include "utlist.h" +struct stored_event { + XGenericEventCookie ev; + struct stored_event *prev; + struct stored_event *next; +}; + +Bool +_XIsEventCookie(Display *dpy, XEvent *ev) +{ + return (ev->xcookie.type == GenericEvent && + dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL); +} + +/** + * Free all events in the event list. + */ +void +_XFreeEventCookies(Display *dpy) +{ + struct stored_event **head, *e, *tmp; + + if (!dpy->cookiejar) + return; + + head = (struct stored_event**)&dpy->cookiejar; + + DL_FOREACH_SAFE(*head, e, tmp) { + XFree(e->ev.data); + XFree(e); + if (dpy->cookiejar == e) + dpy->cookiejar = NULL; + } +} + +/** + * Add an event to the display's event list. This event must be freed on the + * next call to XNextEvent(). + */ +void +_XStoreEventCookie(Display *dpy, XEvent *event) { -#ifndef LONG64 - if (n >= (ULONG_MAX >> 2)) + XGenericEventCookie* cookie = &event->xcookie; + struct stored_event **head, *add; + + if (!_XIsEventCookie(dpy, event)) + return; + + head = (struct stored_event**)(&dpy->cookiejar); + + add = Xmalloc(sizeof(struct stored_event)); + if (!add) { + ESET(ENOMEM); _XIOError(dpy); -#endif - _XEatData (dpy, n << 2); + } + add->ev = *cookie; + DL_APPEND(*head, add); + cookie->data = NULL; /* don't return data yet, must be claimed */ +} + +/** + * Return the event with the given cookie and remove it from the list. + */ +Bool +_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev) +{ + Bool ret = False; + struct stored_event **head, *event; + head = (struct stored_event**)&dpy->cookiejar; + + if (!_XIsEventCookie(dpy, (XEvent*)ev)) + return ret; + + DL_FOREACH(*head, event) { + if (event->ev.cookie == ev->cookie && + event->ev.extension == ev->extension && + event->ev.evtype == ev->evtype) { + *ev = event->ev; + DL_DELETE(*head, event); + Xfree(event); + ret = True; + break; + } + } + + return ret; +} + +Bool +_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out) +{ + Bool ret = False; + int extension; + + if (!_XIsEventCookie(dpy, (XEvent*)in) || !out) + return ret; + + extension = in->extension & 0x7F; + + if (!dpy->generic_event_copy_vec[extension]) + return ret; + + ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out)); + out->cookie = ret ? ++dpy->next_cookie : 0; + return ret; } @@ -2789,12 +3025,13 @@ void _XEnq( register xEvent *event) { register _XQEvent *qelt; + int type, extension; if ((qelt = dpy->qfree)) { /* If dpy->qfree is non-NULL do this, else malloc a new one. */ dpy->qfree = qelt->next; } - else if ((qelt = + else if ((qelt = (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) { /* Malloc call failed! */ ESET(ENOMEM); @@ -2807,12 +3044,33 @@ void _XEnq( #endif } qelt->next = NULL; - /* go call through display to find proper event reformatter */ - if ((*dpy->event_vec[event->u.u.type & 0177])(dpy, &qelt->event, event)) { + + type = event->u.u.type & 0177; + extension = ((xGenericEvent*)event)->extension; + /* If an extension has registerd a generic_event_vec handler, then + * it can handle event cookies. Otherwise, proceed with the normal + * event handlers. + * + * If the generic_event_vec is called, qelt->event is a event cookie + * with the data pointer and the "free" pointer set. Data pointer is + * some memory allocated by the extension. + */ + if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) { + XGenericEventCookie *cookie = &qelt->event.xcookie; + (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event); + cookie->cookie = ++dpy->next_cookie; + + qelt->qserial_num = dpy->next_event_serial_num++; + if (dpy->tail) dpy->tail->next = qelt; + else dpy->head = qelt; + + dpy->tail = qelt; + dpy->qlen++; + } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) { qelt->qserial_num = dpy->next_event_serial_num++; if (dpy->tail) dpy->tail->next = qelt; else dpy->head = qelt; - + dpy->tail = qelt; dpy->qlen++; } else { @@ -2842,6 +3100,13 @@ void _XDeq( qelt->next = dpy->qfree; dpy->qfree = qelt; dpy->qlen--; + + if (_XIsEventCookie(dpy, &qelt->event)) { + XGenericEventCookie* cookie = &qelt->event.xcookie; + /* dpy->qfree is re-used, reset memory to avoid double free on + * _XFreeDisplayStructure */ + cookie->data = NULL; + } } /* @@ -2856,13 +3121,41 @@ _XUnknownWireEvent( register xEvent *event) /* wire protocol event */ { #ifdef notdef - (void) fprintf(stderr, + (void) fprintf(stderr, "Xlib: unhandled wire event! event number = %d, display = %x\n.", event->u.u.type, dpy); #endif return(False); } +Bool +_XUnknownWireEventCookie( + Display *dpy, /* pointer to display structure */ + XGenericEventCookie *re, /* pointer to where event should be reformatted */ + xEvent *event) /* wire protocol event */ +{ +#ifdef notdef + fprintf(stderr, + "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.", + ((xGenericEvent*)event)->extension, dpy); +#endif + return(False); +} + +Bool +_XUnknownCopyEventCookie( + Display *dpy, /* pointer to display structure */ + XGenericEventCookie *in, /* source */ + XGenericEventCookie *out) /* destination */ +{ +#ifdef notdef + fprintf(stderr, + "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.", + in->extension, dpy); +#endif + return(False); +} + /*ARGSUSED*/ Status _XUnknownNativeEvent( @@ -2871,7 +3164,7 @@ _XUnknownNativeEvent( register xEvent *event) /* wire protocol event */ { #ifdef notdef - (void) fprintf(stderr, + (void) fprintf(stderr, "Xlib: unhandled native event! event number = %d, display = %x\n.", re->type, dpy); #endif @@ -2892,7 +3185,7 @@ _XWireToEvent( (xGenericReply *)event); ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0); ((XAnyEvent *)re)->display = dpy; - + /* Ignore the leading bit of the event type since it is set when a client sends an event rather than the server. */ @@ -2961,7 +3254,7 @@ _XWireToEvent( ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY); ev->state = event->u.enterLeave.state; ev->mode = event->u.enterLeave.mode; - ev->same_screen = (event->u.enterLeave.flags & + ev->same_screen = (event->u.enterLeave.flags & ELFlagSameScreen) && True; ev->focus = (event->u.enterLeave.flags & ELFlagFocus) && True; @@ -3199,14 +3492,14 @@ _XWireToEvent( case ClientMessage: { register int i; - register XClientMessageEvent *ev + register XClientMessageEvent *ev = (XClientMessageEvent *) re; ev->window = event->u.clientMessage.window; ev->format = event->u.u.detail; switch (ev->format) { - case 8: + case 8: ev->message_type = event->u.clientMessage.u.b.type; - for (i = 0; i < 20; i++) + for (i = 0; i < 20; i++) ev->data.b[i] = event->u.clientMessage.u.b.bytes[i]; break; case 16: @@ -3252,7 +3545,7 @@ _XWireToEvent( /* - * _XDefaultIOError - Default fatal system error reporting routine. Called + * _XDefaultIOError - Default fatal system error reporting routine. Called * when an X internal system error is encountered. */ int _XDefaultIOError( @@ -3263,7 +3556,7 @@ int _XDefaultIOError( "X connection to %s broken (explicit kill or server shutdown).\r\n", DisplayString (dpy)); } else { - (void) fprintf (stderr, + (void) fprintf (stderr, "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n", #ifdef WIN32 WSAGetLastError(), strerror(WSAGetLastError()), @@ -3271,7 +3564,7 @@ int _XDefaultIOError( errno, strerror (errno), #endif DisplayString (dpy)); - (void) fprintf (stderr, + (void) fprintf (stderr, " after %lu requests (%lu known processed) with %d events remaining.\r\n", NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy), QLength(dpy)); @@ -3312,13 +3605,13 @@ static int _XPrintDefaultError( char buffer[BUFSIZ]; char mesg[BUFSIZ]; char number[32]; - char *mtype = "XlibMessage"; + const char *mtype = "XlibMessage"; register _XExtension *ext = (_XExtension *)NULL; _XExtension *bext = (_XExtension *)NULL; XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); (void) fprintf(fp, "%s: %s\n ", mesg, buffer); - XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", + XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", mesg, BUFSIZ); (void) fprintf(fp, mesg, event->request_code); if (event->request_code < 128) { @@ -3351,7 +3644,7 @@ static int _XPrintDefaultError( /* kludge, try to find the extension that caused it */ buffer[0] = '\0'; for (ext = dpy->ext_procs; ext; ext = ext->next) { - if (ext->error_string) + if (ext->error_string) (*ext->error_string)(dpy, event->error_code, &ext->codes, buffer, BUFSIZ); if (buffer[0]) { @@ -3362,7 +3655,7 @@ static int _XPrintDefaultError( ext->codes.first_error < (int)event->error_code && (!bext || ext->codes.first_error > bext->codes.first_error)) bext = ext; - } + } if (bext) sprintf(buffer, "%s.%d", bext->name, event->error_code - bext->codes.first_error); @@ -3402,7 +3695,7 @@ static int _XPrintDefaultError( (void) fprintf(fp, mesg, event->resourceid); fputs("\n", fp); } - XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", + XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", mesg, BUFSIZ); fputs(" ", fp); (void) fprintf(fp, mesg, event->serial); @@ -3425,10 +3718,7 @@ int _XDefaultError( } /*ARGSUSED*/ -Bool _XDefaultWireError(display, he, we) - Display *display; - XErrorEvent *he; - xError *we; +Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we) { return True; } @@ -3440,7 +3730,7 @@ int _XError ( Display *dpy, register xError *rep) { - /* + /* * X_Error packet encountered! We need to unpack the error before * giving it to the user. */ @@ -3467,23 +3757,23 @@ int _XError ( return 0; if (_XErrorFunction != NULL) { int rtn_val; -#ifdef XTHREADS +#if defined(XTHREADS) && !USE_XCB if (dpy->lock) (*dpy->lock->user_lock_display)(dpy); UnlockDisplay(dpy); -#endif /* XTHREADS */ +#endif /* XTHREADS && !USE_XCB */ rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ -#ifdef XTHREADS +#if defined(XTHREADS) && !USE_XCB LockDisplay(dpy); if (dpy->lock) (*dpy->lock->user_unlock_display)(dpy); -#endif /* XTHREADS */ +#endif /* XTHREADS && !USE_XCB */ return rtn_val; } else { return _XDefaultError(dpy, (XErrorEvent *)&event); } } - + /* * _XIOError - call user connection error handler and exit */ @@ -3496,6 +3786,16 @@ _XIOError ( errno = WSAGetLastError(); #endif + /* This assumes that the thread calling exit will call any atexit handlers. + * If this does not hold, then an alternate solution would involve + * registering an atexit handler to take over the lock, which would only + * assume that the same thread calls all the atexit handlers. */ +#ifdef XTHREADS + if (dpy->lock) + (*dpy->lock->user_lock_display)(dpy); +#endif + UnlockDisplay(dpy); + if (_XIOErrorFunction != NULL) (*_XIOErrorFunction)(dpy); else @@ -3687,6 +3987,123 @@ _XData32( } #endif /* LONG64 */ +#ifdef WORD64 + +/* + * XXX This is a *really* stupid way of doing this. It should just use + * dpy->bufptr directly, taking into account where in the word it is. + */ + +/* + * Data16 - Place 16 bit data in the buffer. + * + * "dpy" is a pointer to a Display. + * "data" is a pointer to the data. + * "len" is the length in bytes of the data. + */ + +static doData16( + register Display *dpy, + short *data, + unsigned len, + char *packbuffer) +{ + long *lp,*lpack; + long i, nwords,bits; + long mask16 = 0x000000000000ffff; + + lp = (long *)data; + lpack = (long *)packbuffer; + +/* nwords is the number of 16 bit values to be packed, + * the low order 16 bits of each word will be packed + * into 64 bit words + */ + nwords = len >> 1; + bits = 48; + + for(i=0;i> 1; + + for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { + doData16 (dpy, data, PACKBUFFERSIZE, packbuffer); + } + if (len) doData16 (dpy, data, len, packbuffer); +} + +/* + * Data32 - Place 32 bit data in the buffer. + * + * "dpy" is a pointer to a Display. + * "data" is a pointer to the data. + * "len" is the length in bytes of the data. + */ + +static doData32( + register Display *dpy + long *data, + unsigned len, + char *packbuffer) +{ + long *lp,*lpack; + long i,bits,nwords; + long mask32 = 0x00000000ffffffff; + + lpack = (long *) packbuffer; + lp = data; + +/* nwords is the number of 32 bit values to be packed + * the low order 32 bits of each word will be packed + * into 64 bit words + */ + nwords = len >> 2; + bits = 32; + + for(i=0;i> 2; + + for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { + doData32 (dpy, data, PACKBUFFERSIZE, packbuffer); + } + if (len) doData32 (dpy, data, len, packbuffer); +} + +#endif /* WORD64 */ + /* Make sure this produces the same string as DefineLocal/DefineSelf in xdm. * Otherwise, Xau will not be able to find your cookies in the Xauthority file. @@ -3696,9 +4113,13 @@ _XData32( * and so, you may be better off using gethostname (if it exists). */ -#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(USG) || defined(SVR4) +#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4) #define NEED_UTSNAME #include +#else +#ifdef HAVE_UNISTD_H +#include +#endif #endif /* @@ -3738,9 +4159,7 @@ int _XGetHostname ( * _XScreenOfWindow - get the Screen of a given window */ -Screen *_XScreenOfWindow (dpy, w) - Display *dpy; - Window w; +Screen *_XScreenOfWindow(Display *dpy, Window w) { register int i; Window root; @@ -3749,7 +4168,7 @@ Screen *_XScreenOfWindow (dpy, w) if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height, &bw, &depth) == False) { - return None; + return NULL; } for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */ if (root == RootWindow (dpy, i)) { @@ -3759,36 +4178,6 @@ Screen *_XScreenOfWindow (dpy, w) return NULL; } -/* - * WARNING: This implementation's pre-conditions and post-conditions - * must remain compatible with the old macro-based implementations of - * GetReq, GetReqExtra, GetResReq, and GetEmptyReq. The portions of the - * Display structure affected by those macros are part of libX11's - * ABI. - */ -void *_XGetRequest(Display *dpy, CARD8 type, size_t len) -{ - xReq *req; - - WORD64ALIGN - - if (dpy->bufptr + len > dpy->bufmax) - _XFlush(dpy); - - if (len % 4) - fprintf(stderr, - "Xlib: request %d length %zd not a multiple of 4.\n", - type, len); - - dpy->last_req = dpy->bufptr; - - req = (xReq*)dpy->bufptr; - req->reqType = type; - req->length = len / 4; - dpy->bufptr += len; - dpy->request++; - return req; -} #if defined(WIN32) @@ -3854,7 +4243,7 @@ static int AccessFile (path, pathbuf, len_pathbuf, pathret) return 1; } -#ifndef __UNIXOS2__ +#ifndef __UNIXOS2__ /* one last place to look */ drive = getenv ("HOMEDRIVE"); if (drive) { @@ -3912,6 +4301,26 @@ int _XOpenFile(path, flags) return ret; } +int _XOpenFileMode(path, flags, mode) + _Xconst char* path; + int flags; + mode_t mode; +{ + char buf[MAX_PATH]; + char* bufp = NULL; + int ret = -1; + UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); + + if (AccessFile (path, buf, MAX_PATH, &bufp)) + ret = open (bufp, flags, mode); + + (void) SetErrorMode (olderror); + + if (bufp != buf) Xfree (bufp); + + return ret; +} + void* _XFopenFile(path, mode) _Xconst char* path; _Xconst char* mode; diff --git a/nx-X11/lib/X11/Xlibint.h b/nx-X11/lib/X11/Xlibint.h index 15dd5cea7..20cfe1eaf 100644 --- a/nx-X11/lib/X11/Xlibint.h +++ b/nx-X11/lib/X11/Xlibint.h @@ -139,7 +139,7 @@ struct _XDisplay int nscreens; /* number of screens on this server*/ Screen *screens; /* pointer to list of screens */ unsigned long motion_buffer; /* size of motion buffer */ - unsigned long flags; /* internal connection flags */ + volatile unsigned long flags; /* internal connection flags */ int min_keycode; /* minimum defined keycode */ int max_keycode; /* maximum defined keycode */ KeySym *keysyms; /* This server's keysyms */ @@ -152,7 +152,7 @@ struct _XDisplay struct _XExten *ext_procs; /* extensions initialized on this display */ /* * the following can be fixed size, as the protocol defines how - * much address space is available. + * much address space is available. * While this could be done using the extension vector, there * may be MANY events processed, so a search through the extension * list to find the right procedure for each event might be @@ -215,10 +215,32 @@ struct _XDisplay int xcmisc_opcode; /* major opcode for XC-MISC */ struct _XkbInfoRec *xkb_info; /* XKB info */ struct _XtransConnInfo *trans_conn; /* transport connection object */ + struct _X11XCBPrivate *xcb; /* XCB glue private data */ + + /* Generic event cookie handling */ + unsigned int next_cookie; /* next event cookie */ + /* vector for wire to generic event, index is (extension - 128) */ + Bool (*generic_event_vec[128])( + Display * /* dpy */, + XGenericEventCookie * /* Xlib event */, + xEvent * /* wire event */); + /* vector for event copy, index is (extension - 128) */ + Bool (*generic_event_copy_vec[128])( + Display * /* dpy */, + XGenericEventCookie * /* in */, + XGenericEventCookie * /* out*/); + void *cookiejar; /* cookie events returned but not claimed */ }; #define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n) +/* + * define the following if you want the Data macro to be a procedure instead + */ +#ifdef CRAY +#define DataRoutineIsProcedure +#endif /* CRAY */ + #ifndef _XEVENT_ /* * _QEvent datatype for use in input queueing. @@ -420,25 +442,30 @@ extern LockInfoPtr _Xglobal_lock; * X Protocol packetizing macros. */ -/* Leftover from CRAY support - was defined empty on all non-Cray systems */ +/* Need to start requests on 64 bit word boundaries + * on a CRAY computer so add a NoOp (127) if needed. + * A character pointer on a CRAY computer will be non-zero + * after shifting right 61 bits of it is not pointing to + * a word boundary. + */ +#ifdef WORD64 +#define WORD64ALIGN if ((long)dpy->bufptr >> 61) {\ + dpy->last_req = dpy->bufptr;\ + *(dpy->bufptr) = X_NoOperation;\ + *(dpy->bufptr+1) = 0;\ + *(dpy->bufptr+2) = 0;\ + *(dpy->bufptr+3) = 1;\ + dpy->request++;\ + dpy->bufptr += 4;\ + } +#else /* else does not require alignment on 64-bit boundaries */ #define WORD64ALIGN +#endif /* WORD64 */ -/** - * Return a len-sized request buffer for the request type. This function may - * flush the output queue. - * - * @param dpy The display connection - * @param type The request type - * @param len Length of the request in bytes - * - * @returns A pointer to the request buffer with a few default values - * initialized. - */ -extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); /* * GetReq - Get the next available X request packet in the buffer and - * return it. + * return it. * * "name" is the name of the request, e.g. CreatePixmap, OpenFont, etc. * "req" is the name of the request pointer. @@ -447,10 +474,25 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); #if !defined(UNIXCPP) || defined(ANSICPP) #define GetReq(name, req) \ - req = (x##name##Req *) _XGetRequest(dpy, X_##name, SIZEOF(x##name##Req)) + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = X_##name;\ + req->length = (SIZEOF(x##name##Req))>>2;\ + dpy->bufptr += SIZEOF(x##name##Req);\ + dpy->request++ + #else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ #define GetReq(name, req) \ - req = (x/**/name/**/Req *) _XGetRequest(dpy, X_/**/name, SIZEOF(x/**/name/**/Req)) + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = X_/**/name;\ + req->length = (SIZEOF(x/**/name/**/Req))>>2;\ + dpy->bufptr += SIZEOF(x/**/name/**/Req);\ + dpy->request++ #endif /* GetReqExtra is the same as GetReq, but allocates "n" additional @@ -458,21 +500,36 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); #if !defined(UNIXCPP) || defined(ANSICPP) #define GetReqExtra(name, n, req) \ - req = (x##name##Req *) _XGetRequest(dpy, X_##name, SIZEOF(x##name##Req) + n) + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x##name##Req) + n) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = X_##name;\ + req->length = (SIZEOF(x##name##Req) + n)>>2;\ + dpy->bufptr += SIZEOF(x##name##Req) + n;\ + dpy->request++ #else #define GetReqExtra(name, n, req) \ - req = (x/**/name/**/Req *) _XGetRequest(dpy, X_/**/name, SIZEOF(x/**/name/**/Req) + n) + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x/**/name/**/Req) + n) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = X_/**/name;\ + req->length = (SIZEOF(x/**/name/**/Req) + n)>>2;\ + dpy->bufptr += SIZEOF(x/**/name/**/Req) + n;\ + dpy->request++ #endif /* - * GetResReq is for those requests that have a resource ID + * GetResReq is for those requests that have a resource ID * (Window, Pixmap, GContext, etc.) as their single argument. - * "rid" is the name of the resource. + * "rid" is the name of the resource. */ #if !defined(UNIXCPP) || defined(ANSICPP) #define GetResReq(name, rid, req) \ + WORD64ALIGN\ if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\ _XFlush(dpy);\ req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\ @@ -483,6 +540,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); dpy->request++ #else #define GetResReq(name, rid, req) \ + WORD64ALIGN\ if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\ _XFlush(dpy);\ req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\ @@ -495,10 +553,11 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); /* * GetEmptyReq is for those requests that have no arguments - * at all. + * at all. */ #if !defined(UNIXCPP) || defined(ANSICPP) #define GetEmptyReq(name, req) \ + WORD64ALIGN\ if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\ _XFlush(dpy);\ req = (xReq *) (dpy->last_req = dpy->bufptr);\ @@ -508,6 +567,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); dpy->request++ #else #define GetEmptyReq(name, req) \ + WORD64ALIGN\ if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\ _XFlush(dpy);\ req = (xReq *) (dpy->last_req = dpy->bufptr);\ @@ -517,14 +577,18 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); dpy->request++ #endif -/* - * MakeBigReq sets the CARD16 "req->length" to 0 and inserts a new CARD32 - * length, after req->length, before the data in the request. The new length - * includes the "n" extra 32-bit words. - * - * Do not use MakeBigReq if there is no data already in the request. - * req->length must already be >= 2. - */ +#ifdef WORD64 +#define MakeBigReq(req,n) \ + { \ + char _BRdat[4]; \ + unsigned long _BRlen = req->length - 1; \ + req->length = 0; \ + memcpy(_BRdat, ((char *)req) + (_BRlen << 2), 4); \ + memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ + memcpy(((char *)req) + 4, _BRdat, 4); \ + Data32(dpy, (long *)&_BRdat, 4); \ + } +#else #ifdef LONG64 #define MakeBigReq(req,n) \ { \ @@ -532,7 +596,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); CARD32 _BRlen = req->length - 1; \ req->length = 0; \ _BRdat = ((CARD32 *)req)[_BRlen]; \ - memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \ + memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ ((CARD32 *)req)[1] = _BRlen + n + 2; \ Data32(dpy, &_BRdat, 4); \ } @@ -543,19 +607,13 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); CARD32 _BRlen = req->length - 1; \ req->length = 0; \ _BRdat = ((CARD32 *)req)[_BRlen]; \ - memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \ + memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ ((CARD32 *)req)[1] = _BRlen + n + 2; \ Data32(dpy, &_BRdat, 4); \ } #endif +#endif -/* - * SetReqLen increases the count of 32-bit words in the request by "n", - * or by "badlen" if "n" is too large. - * - * Do not use SetReqLen if "req" does not already have data after the - * xReq header. req->length must already be >= 2. - */ #define SetReqLen(req,n,badlen) \ if ((req->length + n) > (unsigned)65535) { \ if (dpy->bigreq_size) { \ @@ -601,7 +659,7 @@ extern void _XFlushGCCache(Display *dpy, GC gc); * "ptr" is the pointer being assigned to. * "n" is the number of bytes to allocate. * - * Example: + * Example: * xTextElt *elt; * BufAlloc (xTextElt *, elt, nbytes) */ @@ -613,6 +671,10 @@ extern void _XFlushGCCache(Display *dpy, GC gc); (void)ptr; \ dpy->bufptr += (n); +#ifdef WORD64 +#define Data16(dpy, data, len) _XData16(dpy, (short *)data, len) +#define Data32(dpy, data, len) _XData32(dpy, (long *)data, len) +#else #define Data16(dpy, data, len) Data((dpy), (char *)(data), (len)) #define _XRead16Pad(dpy, data, len) _XReadPad((dpy), (char *)(data), (len)) #define _XRead16(dpy, data, len) _XRead((dpy), (char *)(data), (len)) @@ -632,6 +694,7 @@ extern void _XRead32( #define Data32(dpy, data, len) Data((dpy), (char *)(data), (len)) #define _XRead32(dpy, data, len) _XRead((dpy), (char *)(data), (len)) #endif +#endif /* not WORD64 */ #define PackData16(dpy,data,len) Data16 (dpy, data, len) #define PackData32(dpy,data,len) Data32 (dpy, data, len) @@ -646,7 +709,7 @@ extern void _XRead32( (((cs)->rbearing|(cs)->lbearing| \ (cs)->ascent|(cs)->descent) == 0)) -/* +/* * CI_GET_CHAR_INFO_1D - return the charinfo struct for the indicated 8bit * character. If the character is in the column and exists, then return the * appropriate metrics (note that fonts with common per-character metrics will @@ -672,7 +735,7 @@ extern void _XRead32( /* - * CI_GET_CHAR_INFO_2D - return the charinfo struct for the indicated row and + * CI_GET_CHAR_INFO_2D - return the charinfo struct for the indicated row and * column. This is used for fonts that have more than row zero. */ #define CI_GET_CHAR_INFO_2D(fs,row,col,def,cs) \ @@ -700,10 +763,20 @@ extern void _XRead32( } +#ifdef MUSTCOPY + +/* for when 32-bit alignment is not good enough */ +#define OneDataCard32(dpy,dstaddr,srcvar) \ + { dpy->bufptr -= 4; Data32 (dpy, (char *) &(srcvar), 4); } + +#else + /* srcvar must be a variable for large architecture version */ #define OneDataCard32(dpy,dstaddr,srcvar) \ { *(CARD32 *)(dstaddr) = (srcvar); } +#endif /* MUSTCOPY */ + typedef struct _XInternalAsync { struct _XInternalAsync *next; /* @@ -880,10 +953,6 @@ extern void _XEatData( Display* /* dpy */, unsigned long /* n */ ); -extern void _XEatDataWords( - Display* /* dpy */, - unsigned long /* n */ -); extern char *_XAllocScratch( Display* /* dpy */, unsigned long /* nbytes */ @@ -984,6 +1053,19 @@ extern Bool _XUnknownWireEvent( XEvent* /* re */, xEvent* /* event */ ); + +extern Bool _XUnknownWireEventCookie( + Display* /* dpy */, + XGenericEventCookie* /* re */, + xEvent* /* event */ +); + +extern Bool _XUnknownCopyEventCookie( + Display* /* dpy */, + XGenericEventCookie* /* in */, + XGenericEventCookie* /* out */ +); + extern Status _XUnknownNativeEvent( Display* /* dpy */, XEvent* /* re */, @@ -1021,7 +1103,7 @@ extern int (*XESetCopyGC( Display* /* display */, GC /* gc */, XExtCodes* /* codes */ - ) /* proc */ + ) /* proc */ ))( Display*, GC, XExtCodes* ); @@ -1033,7 +1115,7 @@ extern int (*XESetFlushGC( Display* /* display */, GC /* gc */, XExtCodes* /* codes */ - ) /* proc */ + ) /* proc */ ))( Display*, GC, XExtCodes* ); @@ -1045,7 +1127,7 @@ extern int (*XESetFreeGC( Display* /* display */, GC /* gc */, XExtCodes* /* codes */ - ) /* proc */ + ) /* proc */ ))( Display*, GC, XExtCodes* ); @@ -1057,7 +1139,7 @@ extern int (*XESetCreateFont( Display* /* display */, XFontStruct* /* fs */, XExtCodes* /* codes */ - ) /* proc */ + ) /* proc */ ))( Display*, XFontStruct*, XExtCodes* ); @@ -1069,10 +1151,10 @@ extern int (*XESetFreeFont( Display* /* display */, XFontStruct* /* fs */, XExtCodes* /* codes */ - ) /* proc */ + ) /* proc */ ))( Display*, XFontStruct*, XExtCodes* -); +); extern int (*XESetCloseDisplay( Display* /* display */, @@ -1080,7 +1162,7 @@ extern int (*XESetCloseDisplay( int (*) ( Display* /* display */, XExtCodes* /* codes */ - ) /* proc */ + ) /* proc */ ))( Display*, XExtCodes* ); @@ -1093,7 +1175,7 @@ extern int (*XESetError( xError* /* err */, XExtCodes* /* codes */, int* /* ret_code */ - ) /* proc */ + ) /* proc */ ))( Display*, xError*, XExtCodes*, int* ); @@ -1107,7 +1189,7 @@ extern char* (*XESetErrorString( XExtCodes* /* codes */, char* /* buffer */, int /* nbytes */ - ) /* proc */ + ) /* proc */ ))( Display*, int, XExtCodes*, char*, int ); @@ -1131,11 +1213,36 @@ extern Bool (*XESetWireToEvent( Display* /* display */, XEvent* /* re */, xEvent* /* event */ - ) /* proc */ + ) /* proc */ ))( Display*, XEvent*, xEvent* ); +extern Bool (*XESetWireToEventCookie( + Display* /* display */, + int /* extension */, + Bool (*) ( + Display* /* display */, + XGenericEventCookie* /* re */, + xEvent* /* event */ + ) /* proc */ +))( + Display*, XGenericEventCookie*, xEvent* +); + +extern Bool (*XESetCopyEventCookie( + Display* /* display */, + int /* extension */, + Bool (*) ( + Display* /* display */, + XGenericEventCookie* /* in */, + XGenericEventCookie* /* out */ + ) /* proc */ +))( + Display*, XGenericEventCookie*, XGenericEventCookie* +); + + extern Status (*XESetEventToWire( Display* /* display */, int /* event_number */, @@ -1143,7 +1250,7 @@ extern Status (*XESetEventToWire( Display* /* display */, XEvent* /* re */, xEvent* /* event */ - ) /* proc */ + ) /* proc */ ))( Display*, XEvent*, xEvent* ); @@ -1155,7 +1262,7 @@ extern Bool (*XESetWireToError( Display* /* display */, XErrorEvent* /* he */, xError* /* we */ - ) /* proc */ + ) /* proc */ ))( Display*, XErrorEvent*, xError* ); @@ -1168,7 +1275,7 @@ extern void (*XESetBeforeFlush( XExtCodes* /* codes */, _Xconst char* /* data */, long /* len */ - ) /* proc */ + ) /* proc */ ))( Display*, XExtCodes*, _Xconst char*, long ); @@ -1194,6 +1301,11 @@ extern void _XUnregisterInternalConnection( int /* fd */ ); +extern void _XProcessInternalConnection( + Display* /* dpy */, + struct _XConnectionInfo* /* conn_info */ +); + /* Display structure has pointers to these */ struct _XConnectionInfo { /* info from _XRegisterInternalConnection */ @@ -1235,6 +1347,12 @@ extern int _XOpenFile( int /* flags */ ); +extern int _XOpenFileMode( + _Xconst char* /* path */, + int /* flags */, + mode_t /* mode */ +); + extern void* _XFopenFile( _Xconst char* /* path */, _Xconst char* /* mode */ @@ -1245,6 +1363,7 @@ extern int _XAccessFile( ); #else #define _XOpenFile(path,flags) open(path,flags) +#define _XOpenFileMode(path,flags,mode) open(path,flags,mode) #define _XFopenFile(path,mode) fopen(path,mode) #endif @@ -1285,9 +1404,36 @@ Status _XGetWindowAttributes( XWindowAttributes *attr); int _XPutBackEvent ( - register Display *dpy, + register Display *dpy, register XEvent *event); +extern Bool _XIsEventCookie( + Display *dpy, + XEvent *ev); + +extern void _XFreeEventCookies( + Display *dpy); + +extern void _XStoreEventCookie( + Display *dpy, + XEvent *ev); + +extern Bool _XFetchEventCookie( + Display *dpy, + XGenericEventCookie *ev); + +extern Bool _XCopyEventCookie( + Display *dpy, + XGenericEventCookie *in, + XGenericEventCookie *out); + +/* lcFile.c */ + +extern void xlocaledir( + char *buf, + int buf_len +); + _XFUNCPROTOEND #endif /* _XLIBINT_H_ */ diff --git a/nx-X11/lib/X11/Xprivate.h b/nx-X11/lib/X11/Xprivate.h new file mode 100644 index 000000000..ebe51c1ed --- /dev/null +++ b/nx-X11/lib/X11/Xprivate.h @@ -0,0 +1,28 @@ +/* Copyright (C) 2008 Jamey Sharp, Josh Triplett + * This file is licensed under the MIT license. See the file COPYING. + * + * As Xlibint.h has long become effectively public API, this header exists + * for new private functions that nothing outside of libX11 should call. + */ + +#ifndef XPRIVATE_H +#define XPRIVATE_H + +extern void _XIDHandler(Display *dpy); +extern void _XSeqSyncFunction(Display *dpy); +extern void _XSetPrivSyncFunction(Display *dpy); +extern void _XSetSeqSyncFunction(Display *dpy); + +#ifdef XTHREADS +#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) +#define InternalLockDisplay(d,wskip) if ((d)->lock) \ + (*(d)->lock->internal_lock_display)(d,wskip,__FILE__,__LINE__) +#else +#define InternalLockDisplay(d,wskip) if ((d)->lock) \ + (*(d)->lock->internal_lock_display)(d,wskip) +#endif +#else /* XTHREADS else */ +#define InternalLockDisplay(d,wskip) +#endif /* XTHREADS else */ + +#endif /* XPRIVATE_H */ diff --git a/nx-X11/lib/X11/lcFile.c b/nx-X11/lib/X11/lcFile.c index 5989a9aae..50159f64b 100644 --- a/nx-X11/lib/X11/lcFile.c +++ b/nx-X11/lib/X11/lcFile.c @@ -13,7 +13,7 @@ * software without specific, written prior permission. * * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, @@ -32,11 +32,7 @@ #include "Xlibint.h" #include "XlcPubI.h" #include -#if 0 -#include /* in theory delivers getresuid/gid prototypes, - * in practice only the Linux syscall wrapper is there. */ -#endif - +#include /************************************************************************/ @@ -221,7 +217,7 @@ _XlcParsePath( #define XLOCALEDIR "/usr/lib/X11/locale" #endif -static void +void xlocaledir( char *buf, int buf_len) @@ -268,7 +264,7 @@ xlocaledir( priv = 0; } else { if (seteuid(oldeuid) == -1) { - /* XXX ouch, coudn't get back to original uid + /* XXX ouch, coudn't get back to original uid what can we do ??? */ _exit(127); } @@ -299,6 +295,84 @@ xlocaledir( buf[buf_len-1] = '\0'; } +static void +xlocalelibdir( + char *buf, + int buf_len) +{ + char *p = buf; + int len = 0; + +#ifndef NO_XLOCALEDIR + char *dir; + int priv = 1; + + dir = getenv("XLOCALELIBDIR"); + + if (dir) { +#ifndef WIN32 + /* + * Only use the user-supplied path if the process isn't priviledged. + */ + if (getuid() == geteuid() && getgid() == getegid()) { +#if defined(HASSETUGID) + priv = issetugid(); +#elif defined(HASGETRESUID) + { + uid_t ruid, euid, suid; + gid_t rgid, egid, sgid; + if ((getresuid(&ruid, &euid, &suid) == 0) && + (getresgid(&rgid, &egid, &sgid) == 0)) + priv = (euid != suid) || (egid != sgid); + } +#else + /* + * If there are saved ID's the process might still be priviledged + * even though the above test succeeded. If issetugid() and + * getresgid() aren't available, test this by trying to set + * euid to 0. + * + * Note: this only protects setuid-root clients. It doesn't + * protect other setuid or any setgid clients. If this tradeoff + * isn't acceptable, set DisableXLocaleDirEnv to YES in host.def. + */ + unsigned int oldeuid; + oldeuid = geteuid(); + if (seteuid(0) != 0) { + priv = 0; + } else { + if (seteuid(oldeuid) == -1) { + /* XXX ouch, coudn't get back to original uid + what can we do ??? */ + _exit(127); + } + priv = 1; + } +#endif + } +#else + priv = 0; +#endif + if (!priv) { + len = strlen(dir); + strncpy(p, dir, buf_len); + if (len < buf_len) { + p[len++] = LC_PATHDELIM; + p += len; + } + } + } +#endif /* NO_XLOCALEDIR */ + + if (len < buf_len) +#ifndef __UNIXOS2__ + strncpy(p, XLOCALELIBDIR, buf_len - len); +#else + strncpy(p,__XOS2RedirRoot(XLOCALELIBDIR), buf_len - len); +#endif + buf[buf_len-1] = '\0'; +} + /* Mapping direction */ typedef enum { LtoR, /* Map first field to second field */ @@ -387,11 +461,11 @@ normalize_lcname (const char *name) { char *p, *ret; const char *tmp = name; - + p = ret = Xmalloc(strlen(name) + 1); if (!p) return NULL; - + if (tmp) { while (*tmp && *tmp != '.' && *tmp != '@') *p++ = *tmp++; @@ -428,7 +502,10 @@ _XlcFileName( siname = XLC_PUBLIC(lcd, siname); - lowercase(cat, category); + if (category) + lowercase(cat, category); + else + cat[0] = '\0'; xlocaledir(dir,XLC_BUFSIZE); n = _XlcParsePath(dir, args, NUM_LOCALEDIR); for (i = 0; i < n; ++i) { @@ -483,7 +560,7 @@ _XlcResolveLocaleName( xlocaledir (dir, PATH_MAX); n = _XlcParsePath(dir, args, NUM_LOCALEDIR); for (i = 0; i < n; ++i) { - if ((2 + (args[i] ? strlen (args[i]) : 0) + + if ((2 + (args[i] ? strlen (args[i]) : 0) + strlen (locale_alias)) < PATH_MAX) { sprintf (buf, "%s/%s", args[i], locale_alias); name = resolve_name (lc_name, buf, LtoR); @@ -515,7 +592,7 @@ _XlcResolveLocaleName( return 1; } - /* + /* * pub->siname is in the format _., typical would * be "en_US.ISO8859-1", "en_US.utf8", "ru_RU.KOI-8", or ja_JP.SJIS, * although it could be ja.SJIS too. @@ -551,9 +628,7 @@ _XlcResolveLocaleName( /************************************************************************/ int -_XlcResolveI18NPath(buf, buf_len) - char *buf; - int buf_len; +_XlcResolveI18NPath(char *buf, int buf_len) { if (buf != NULL) { xlocaledir(buf, buf_len); @@ -562,10 +637,7 @@ _XlcResolveI18NPath(buf, buf_len) } char * -_XlcLocaleDirName(dir_name, dir_len, lc_name) - char *dir_name; - size_t dir_len; - char *lc_name; +_XlcLocaleDirName(char *dir_name, size_t dir_len, char *lc_name) { char dir[PATH_MAX], buf[PATH_MAX], *name = NULL; int i, n; @@ -574,12 +646,121 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name) char *target_name = (char*)0; char *target_dir = (char*)0; char *nlc_name = NULL; + static char* last_dir_name = 0; + static size_t last_dir_len = 0; + static char* last_lc_name = 0; + + if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0 + && dir_len >= last_dir_len) { + strcpy (dir_name, last_dir_name); + return dir_name; + } xlocaledir (dir, PATH_MAX); n = _XlcParsePath(dir, args, 256); for (i = 0; i < n; ++i) { - - if ((2 + (args[i] ? strlen(args[i]) : 0) + + + if ((2 + (args[i] ? strlen(args[i]) : 0) + + strlen(locale_alias)) < PATH_MAX) { + sprintf (buf, "%s/%s", args[i], locale_alias); + name = resolve_name(lc_name, buf, LtoR); + if (!name) { + if (!nlc_name) + nlc_name = normalize_lcname(lc_name); + if (nlc_name) + name = resolve_name (nlc_name, buf, LtoR); + } + } + + /* If name is not an alias, use lc_name for locale.dir search */ + if (name == NULL) + name = lc_name; + + /* look at locale.dir */ + + target_dir = args[i]; + if (!target_dir) { + /* something wrong */ + if (name != lc_name) + Xfree(name); + continue; + } + if ((1 + (target_dir ? strlen (target_dir) : 0) + + strlen("locale.dir")) < PATH_MAX) { + sprintf(buf, "%s/locale.dir", target_dir); + target_name = resolve_name(name, buf, RtoL); + } + if (name != lc_name) + Xfree(name); + if (target_name != NULL) { + char *p = 0; + if ((p = strstr(target_name, "/XLC_LOCALE"))) { + *p = '\0'; + break; + } + Xfree(target_name); + target_name = NULL; + } + name = NULL; + } + if (nlc_name) Xfree(nlc_name); + + if (target_name == NULL) { + /* vendor locale name == Xlocale name, no expansion of alias */ + target_dir = args[0]; + target_name = lc_name; + } + /* snprintf(dir_name, dir_len, "%s/%", target_dir, target_name); */ + strncpy(dir_name, target_dir, dir_len - 1); + if (strlen(target_dir) >= dir_len - 1) { + dir_name[dir_len - 1] = '\0'; + } else { + strcat(dir_name, "/"); + strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1); + if (strlen(target_name) >= dir_len - strlen(dir_name) - 1) + dir_name[dir_len - 1] = '\0'; + } + if (target_name != lc_name) + Xfree(target_name); + + if (last_dir_name != 0) + Xfree (last_dir_name); + if (last_lc_name != 0) + Xfree (last_lc_name); + last_dir_len = strlen (dir_name) + 1; + last_dir_name = Xmalloc (last_dir_len); + strcpy (last_dir_name, dir_name); + last_lc_name = Xmalloc (strlen (lc_name) + 1); + strcpy (last_lc_name, lc_name); + + return dir_name; +} + +char * +_XlcLocaleLibDirName(char *dir_name, size_t dir_len, char *lc_name) +{ + char dir[PATH_MAX], buf[PATH_MAX], *name = NULL; + int i, n; + char *args[NUM_LOCALEDIR]; + static char locale_alias[] = LOCALE_ALIAS; + char *target_name = (char*)0; + char *target_dir = (char*)0; + char *nlc_name = NULL; + static char* last_dir_name = 0; + static size_t last_dir_len = 0; + static char* last_lc_name = 0; + + if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0 + && dir_len >= last_dir_len) { + strcpy (dir_name, last_dir_name); + return dir_name; + } + + xlocalelibdir (dir, PATH_MAX); + n = _XlcParsePath(dir, args, 256); + for (i = 0; i < n; ++i) { + + if ((2 + (args[i] ? strlen(args[i]) : 0) + strlen(locale_alias)) < PATH_MAX) { sprintf (buf, "%s/%s", args[i], locale_alias); name = resolve_name(lc_name, buf, LtoR); @@ -590,13 +771,13 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name) name = resolve_name (nlc_name, buf, LtoR); } } - + /* If name is not an alias, use lc_name for locale.dir search */ if (name == NULL) name = lc_name; - + /* look at locale.dir */ - + target_dir = args[i]; if (!target_dir) { /* something wrong */ @@ -636,10 +817,21 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name) } else { strcat(dir_name, "/"); strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1); - if (strlen(target_name) >= dir_len - strlen(dir_name) - 1) + if (strlen(target_name) >= dir_len - strlen(dir_name) - 1) dir_name[dir_len - 1] = '\0'; } if (target_name != lc_name) Xfree(target_name); + + if (last_dir_name != 0) + Xfree (last_dir_name); + if (last_lc_name != 0) + Xfree (last_lc_name); + last_dir_len = strlen (dir_name) + 1; + last_dir_name = Xmalloc (last_dir_len); + strcpy (last_dir_name, dir_name); + last_lc_name = Xmalloc (strlen (lc_name) + 1); + strcpy (last_lc_name, lc_name); + return dir_name; } diff --git a/nx-X11/lib/X11/utlist.h b/nx-X11/lib/X11/utlist.h new file mode 100644 index 000000000..0ce06f2b5 --- /dev/null +++ b/nx-X11/lib/X11/utlist.h @@ -0,0 +1,115 @@ +/* +Copyright (c) 2007-2009, Troy D. Hanson +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTLIST_H +#define UTLIST_H + +#define UTLIST_VERSION 1.7 + +/* From: http://uthash.sourceforge.net/utlist.html */ +/* + * This file contains macros to manipulate singly and doubly-linked lists. + * + * 1. LL_ macros: singly-linked lists. + * 2. DL_ macros: doubly-linked lists. + * 3. CDL_ macros: circular doubly-linked lists. + * + * To use singly-linked lists, your structure must have a "next" pointer. + * To use doubly-linked lists, your structure must "prev" and "next" pointers. + * Either way, the pointer to the head of the list must be initialized to NULL. + * + * ----------------.EXAMPLE ------------------------- + * struct item { + * int id; + * struct item *prev, *next; + * } + * + * struct item *list = NULL: + * + * int main() { + * struct item *item; + * ... allocate and populate item ... + * DL_APPEND(list, item); + * } + * -------------------------------------------------- + * + * For doubly-linked lists, the append and delete macros are O(1) + * For singly-linked lists, append and delete are O(n) but prepend is O(1) + * The sort macro is O(n log(n)) for all types of single/double/circular lists. + */ + + +/****************************************************************************** + * doubly linked list macros (non-circular) * + *****************************************************************************/ +#define DL_PREPEND(head,add) \ +do { \ + (add)->next = head; \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev = (add); \ + } else { \ + (add)->prev = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define DL_APPEND(head,add) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev->next = (add); \ + (head)->prev = (add); \ + (add)->next = NULL; \ + } else { \ + (head)=(add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0); + +#define DL_DELETE(head,del) \ +do { \ + if ((del)->prev == (del)) { \ + (head)=NULL; \ + } else if ((del)==(head)) { \ + (del)->next->prev = (del)->prev; \ + (head) = (del)->next; \ + } else { \ + (del)->prev->next = (del)->next; \ + if ((del)->next) { \ + (del)->next->prev = (del)->prev; \ + } else { \ + (head)->prev = (del)->prev; \ + } \ + } \ +} while (0); + + +#define DL_FOREACH(head,el) \ + for(el=head;el;el=el->next) + +#define DL_FOREACH_SAFE(head,el,tmp) \ + for(el=head,tmp=el->next;el;el=tmp,tmp=(el) ? (el->next) : NULL) + +#endif /* UTLIST_H */ -- cgit v1.2.3