Commit 59307314 authored by Ulrich Sibiller's avatar Ulrich Sibiller

update all files with NX relevant changes to libX11 1.3.4

parent a053df0a
...@@ -23,7 +23,6 @@ used in advertising or otherwise to promote the sale, use or other dealings ...@@ -23,7 +23,6 @@ used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group. in this Software without prior written authorization from The Open Group.
*/ */
/* $XFree86$ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
...@@ -36,15 +35,15 @@ in this Software without prior written authorization from The Open Group. ...@@ -36,15 +35,15 @@ in this Software without prior written authorization from The Open Group.
* matches, return. If all else fails, tell the user no events found. * matches, return. If all else fails, tell the user no events found.
*/ */
Bool XCheckIfEvent (dpy, event, predicate, arg) Bool XCheckIfEvent (
register Display *dpy; register Display *dpy,
register XEvent *event, /* XEvent to be filled in. */
Bool (*predicate)( Bool (*predicate)(
Display* /* display */, Display* /* display */,
XEvent* /* event */, XEvent* /* event */,
char* /* arg */ char* /* arg */
); /* function to call */ ), /* function to call */
register XEvent *event; /* XEvent to be filled in. */ char *arg)
char *arg;
{ {
register _XQEvent *prev, *qelt; register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
...@@ -60,6 +59,7 @@ Bool XCheckIfEvent (dpy, event, predicate, arg) ...@@ -60,6 +59,7 @@ Bool XCheckIfEvent (dpy, event, predicate, arg)
&& (*predicate)(dpy, &qelt->event, arg)) { && (*predicate)(dpy, &qelt->event, arg)) {
*event = qelt->event; *event = qelt->event;
_XDeq(dpy, prev, qelt); _XDeq(dpy, prev, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy); UnlockDisplay(dpy);
return True; return True;
} }
...@@ -90,15 +90,16 @@ Bool XCheckIfEvent (dpy, event, predicate, arg) ...@@ -90,15 +90,16 @@ Bool XCheckIfEvent (dpy, event, predicate, arg)
* events. * events.
*/ */
Bool XCheckIfEventNoFlush (dpy, event, predicate, arg) Bool XCheckIfEventNoFlush (
register Display *dpy; register Display *dpy,
register XEvent *event, /* XEvent to be filled in. */
Bool (*predicate)( Bool (*predicate)(
Display* /* display */, Display* /* display */,
XEvent* /* event */, XEvent* /* event */,
char* /* arg */ char* /* arg */
); /* function to call */ ), /* function to call */
register XEvent *event; /* XEvent to be filled in. */ char *arg)
char *arg;
{ {
register _XQEvent *prev, *qelt; register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
...@@ -114,6 +115,7 @@ Bool XCheckIfEventNoFlush (dpy, event, predicate, arg) ...@@ -114,6 +115,7 @@ Bool XCheckIfEventNoFlush (dpy, event, predicate, arg)
&& (*predicate)(dpy, &qelt->event, arg)) { && (*predicate)(dpy, &qelt->event, arg)) {
*event = qelt->event; *event = qelt->event;
_XDeq(dpy, prev, qelt); _XDeq(dpy, prev, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy); UnlockDisplay(dpy);
return True; return True;
} }
......
...@@ -59,9 +59,12 @@ in this Software without prior written authorization from The Open Group. ...@@ -59,9 +59,12 @@ in this Software without prior written authorization from The Open Group.
#include <nx-X11/Xlibint.h> #include <nx-X11/Xlibint.h>
#include <nx-X11/Xtrans/Xtrans.h> #include <nx-X11/Xtrans/Xtrans.h>
#include <nx-X11/Xauth.h> #include <nx-X11/Xauth.h>
#ifdef HASXDMAUTH
#include <X11/Xdmcp.h> #include <X11/Xdmcp.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <unistd.h>
#if !defined(WIN32) #if !defined(WIN32)
#ifndef Lynx #ifndef Lynx
...@@ -77,10 +80,6 @@ in this Software without prior written authorization from The Open Group. ...@@ -77,10 +80,6 @@ in this Software without prior written authorization from The Open Group.
#define X_CONNECTION_RETRIES 5 #define X_CONNECTION_RETRIES 5
#endif #endif
#ifdef LOCALCONN
#include <sys/utsname.h>
#endif
#include "Xintconn.h" #include "Xintconn.h"
/* prototypes */ /* prototypes */
...@@ -96,7 +95,7 @@ static void GetAuthorization( ...@@ -96,7 +95,7 @@ static void GetAuthorization(
int *auth_datalenp); int *auth_datalenp);
/* functions */ /* functions */
static char *copystring (char *src, int len) static char *copystring (const char *src, int len)
{ {
char *dst = Xmalloc (len + 1); char *dst = Xmalloc (len + 1);
...@@ -108,6 +107,36 @@ static char *copystring (char *src, int len) ...@@ -108,6 +107,36 @@ static char *copystring (char *src, int len)
return dst; 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 * Attempts to connect to server, given display name. Returns file descriptor
...@@ -170,11 +199,11 @@ _X11TransConnectDisplay ( ...@@ -170,11 +199,11 @@ _X11TransConnectDisplay (
char* address = addrbuf; char* address = addrbuf;
XtransConnInfo trans_conn = NULL; /* transport connection object */ XtransConnInfo trans_conn = NULL; /* transport connection object */
int connect_stat; int connect_stat;
#ifdef LOCALCONN #if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN)
struct utsname sys; Bool reset_hostname = False; /* Reset hostname? */
#endif char *original_hostname = NULL;
#ifdef TCPCONN int local_transport_index = -1;
char *tcphostname = NULL; /* A place to save hostname pointer */ const char *local_transport[] = { LOCAL_TRANSPORT_LIST, NULL };
#endif #endif
p = display_name; p = display_name;
...@@ -327,23 +356,17 @@ _X11TransConnectDisplay ( ...@@ -327,23 +356,17 @@ _X11TransConnectDisplay (
p = lastc; p = lastc;
#ifdef LOCALCONN #if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN)
/* check if phostname == localnodename AND protocol not specified */ /* check if phostname == localnodename AND protocol not specified */
if (!pprotocol && phostname && uname(&sys) >= 0 && if (!pprotocol && phostname) {
!strncmp(phostname, sys.nodename, char localhostname[256];
(strlen(sys.nodename) < strlen(phostname) ?
strlen(phostname) : strlen(sys.nodename)))) if ((_XGetHostname (localhostname, sizeof localhostname) > 0)
{ && (strcmp(phostname, localhostname) == 0)) {
#ifdef TCPCONN original_hostname = phostname;
/* phostname = NULL;
* We'll first attempt to connect using the local transport. If reset_hostname = True;
* 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);
} }
#endif #endif
...@@ -490,51 +513,33 @@ _X11TransConnectDisplay ( ...@@ -490,51 +513,33 @@ _X11TransConnectDisplay (
#if defined(TCPCONN) || defined(UNIXCONN) || defined(LOCALCONN) || defined(MNX_TCPCONN) || defined(OS2PIPECONN) #if defined(TCPCONN) || defined(UNIXCONN) || defined(LOCALCONN) || defined(MNX_TCPCONN) || defined(OS2PIPECONN)
if (!pprotocol) { if (!pprotocol) {
if (!phostname) { #if defined(UNIXCONN)
#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN) if (phostname && (strcmp (phostname, "unix") == 0)) {
pprotocol = copystring ("local", 5); Xfree(pprotocol);
#if defined(TCPCONN) pprotocol = copystring ("unix", 4);
tcphostname = copystring("localhost", 9); } else
#endif #endif
#ifdef HAVE_LAUNCHD
if (phostname && phostname[0]=='/') {
pprotocol = copystring ("local", 5);
} }
else
{
#endif #endif
pprotocol = copystring ("tcp", 3); if (!phostname)
{
if (local_transport[0] != NULL) {
pprotocol = Xstrdup(local_transport[0]);
local_transport_index = 0;
} }
} }
#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) { if (!pprotocol) { /* if still not found one, tcp is our last resort */
#ifdef apollo pprotocol = copystring ("tcp", 3);
; /* 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 #endif
#if defined(TCPCONN)
connect: connect:
#endif
/* /*
* This seems kind of backwards, but we need to put the protocol, * This seems kind of backwards, but we need to put the protocol,
* host, and port back together to pass to _X11TransOpenCOTSClient(). * host, and port back together to pass to _X11TransOpenCOTSClient().
...@@ -584,10 +589,7 @@ _X11TransConnectDisplay ( ...@@ -584,10 +589,7 @@ _X11TransConnectDisplay (
trans_conn = NULL; trans_conn = NULL;
if (connect_stat == TRANS_TRY_CONNECT_AGAIN) if (connect_stat == TRANS_TRY_CONNECT_AGAIN)
{
sleep(1);
continue; continue;
}
else else
break; break;
} }
...@@ -610,7 +612,6 @@ _X11TransConnectDisplay ( ...@@ -610,7 +612,6 @@ _X11TransConnectDisplay (
{ {
_X11TransClose(trans_conn); _X11TransClose(trans_conn);
trans_conn = NULL; trans_conn = NULL;
sleep(1);
if (saddr) if (saddr)
{ {
free ((char *) saddr); free ((char *) saddr);
...@@ -642,11 +643,30 @@ _X11TransConnectDisplay ( ...@@ -642,11 +643,30 @@ _X11TransConnectDisplay (
* *
* [host] : [:] dpy . scr \0 * [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) + len = ((phostname ? strlen(phostname) : 0) + 1 + (dnet ? 1 : 0) +
strlen(pdpynum) + 1 + (pscrnum ? strlen(pscrnum) : 1) + 1); strlen(pdpynum) + 1 + (pscrnum ? strlen(pscrnum) : 1) + 1);
*fullnamep = (char *) Xmalloc (len); *fullnamep = (char *) Xmalloc (len);
if (!*fullnamep) goto bad; 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", sprintf (*fullnamep, "%s%s%d.%d",
(phostname ? phostname : ""), (phostname ? phostname : ""),
(dnet ? "::" : ":"), (dnet ? "::" : ":"),
...@@ -658,8 +678,8 @@ _X11TransConnectDisplay ( ...@@ -658,8 +678,8 @@ _X11TransConnectDisplay (
if (phostname) Xfree (phostname); if (phostname) Xfree (phostname);
if (pdpynum) Xfree (pdpynum); if (pdpynum) Xfree (pdpynum);
if (pscrnum) Xfree (pscrnum); if (pscrnum) Xfree (pscrnum);
#ifdef TCPCONN #if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN)
if (tcphostname) Xfree (tcphostname); if (original_hostname) Xfree (original_hostname);
#endif #endif
GetAuthorization(trans_conn, family, (char *) saddr, saddrlen, idisplay, GetAuthorization(trans_conn, family, (char *) saddr, saddrlen, idisplay,
...@@ -677,14 +697,36 @@ _X11TransConnectDisplay ( ...@@ -677,14 +697,36 @@ _X11TransConnectDisplay (
if (phostname) Xfree (phostname); if (phostname) Xfree (phostname);
if (address && address != addrbuf) { Xfree(address); address = addrbuf; } if (address && address != addrbuf) { Xfree(address); address = addrbuf; }
#if defined(TCPCONN) #if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN)
if (tcphostname) { /* If connecting to the local machine, and we failed, try again with
pprotocol = copystring("tcp", 3); * the next transport type available, if there is one.
phostname = tcphostname; */
tcphostname = NULL; 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; 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 (pdpynum) Xfree (pdpynum);
if (pscrnum) Xfree (pscrnum); if (pscrnum) Xfree (pscrnum);
...@@ -735,10 +777,7 @@ int _XConnectDisplay ( ...@@ -735,10 +777,7 @@ int _XConnectDisplay (
* Disconnect from server. * Disconnect from server.
*/ */
int _XDisconnectDisplay (trans_conn) int _XDisconnectDisplay (XtransConnInfo trans_conn)
XtransConnInfo trans_conn;
{ {
_X11TransDisconnect(trans_conn); _X11TransDisconnect(trans_conn);
_X11TransClose(trans_conn); _X11TransClose(trans_conn);
...@@ -748,11 +787,11 @@ XtransConnInfo trans_conn; ...@@ -748,11 +787,11 @@ XtransConnInfo trans_conn;
Bool Bool
_XSendClientPrefix (dpy, client, auth_proto, auth_string, prefix) _XSendClientPrefix(
Display *dpy; Display *dpy,
xConnClientPrefix *client; /* contains count for auth_* */ xConnClientPrefix *client, /* contains count for auth_* */
char *auth_proto, *auth_string; /* NOT null-terminated */ char *auth_proto, char *auth_string, /* NOT null-terminated */
xConnSetupPrefix *prefix; /* prefix information */ xConnSetupPrefix *prefix) /* prefix information */
{ {
int auth_length = client->nbytesAuthProto; int auth_length = client->nbytesAuthProto;
int auth_strlen = client->nbytesAuthString; int auth_strlen = client->nbytesAuthString;
...@@ -884,9 +923,9 @@ static _Xconst int *xauth_lengths = default_xauth_lengths; ...@@ -884,9 +923,9 @@ static _Xconst int *xauth_lengths = default_xauth_lengths;
static int xauth_names_length = NUM_DEFAULT_AUTH; static int xauth_names_length = NUM_DEFAULT_AUTH;
void XSetAuthorization (name, namelen, data, datalen) void XSetAuthorization (
int namelen, datalen; /* lengths of name and data */ char *name, int namelen, /* *len are lengths of name and data */
char *name, *data; /* NULL or arbitrary array of bytes */ char *data, int datalen) /* name/data are NULL or arbitrary array of bytes */
{ {
char *tmpname, *tmpdata; char *tmpname, *tmpdata;
...@@ -946,11 +985,11 @@ void XSetAuthorization (name, namelen, data, datalen) ...@@ -946,11 +985,11 @@ void XSetAuthorization (name, namelen, data, datalen)
* Create a credential that we can send to the X server. * Create a credential that we can send to the X server.
*/ */
static int static int
auth_ezencode(servername, window, cred_out, len) auth_ezencode(
char *servername; char *servername,
int window; int window,
char *cred_out; char *cred_out,
int *len; int *len)
{ {
AUTH *a; AUTH *a;
XDR xdr; XDR xdr;
...@@ -1330,7 +1369,7 @@ GetAuthorization( ...@@ -1330,7 +1369,7 @@ GetAuthorization(
/* 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 */ 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++) for (i = 20 ; i < 24; i++)
xdmcp_data[j++] = ((char *)addr)[i]; xdmcp_data[j++] = ((char *)addr)[i];
......
...@@ -35,15 +35,15 @@ in this Software without prior written authorization from The Open Group. ...@@ -35,15 +35,15 @@ in this Software without prior written authorization from The Open Group.
*/ */
int int
XIfEvent (dpy, event, predicate, arg) XIfEvent (
register Display *dpy; register Display *dpy,
register XEvent *event,
Bool (*predicate)( Bool (*predicate)(
Display* /* display */, Display* /* display */,
XEvent* /* event */, XEvent* /* event */,
char* /* arg */ char* /* arg */
); /* function to call */ ), /* function to call */
register XEvent *event; char *arg)
char *arg;
{ {
register _XQEvent *qelt, *prev; register _XQEvent *qelt, *prev;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
...@@ -58,6 +58,7 @@ XIfEvent (dpy, event, predicate, arg) ...@@ -58,6 +58,7 @@ XIfEvent (dpy, event, predicate, arg)
&& (*predicate)(dpy, &qelt->event, arg)) { && (*predicate)(dpy, &qelt->event, arg)) {
*event = qelt->event; *event = qelt->event;
_XDeq(dpy, prev, qelt); _XDeq(dpy, prev, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy); UnlockDisplay(dpy);
return 0; return 0;
} }
......
...@@ -41,21 +41,25 @@ extern long const _Xevent_to_mask[]; ...@@ -41,21 +41,25 @@ extern long const _Xevent_to_mask[];
*/ */
int int
XMaskEvent (dpy, mask, event) XMaskEvent (
register Display *dpy; register Display *dpy,
long mask; /* Selected event mask. */ long mask, /* Selected event mask. */
register XEvent *event; /* XEvent to be filled in. */ register XEvent *event) /* XEvent to be filled in. */
{ {
register _XQEvent *prev, *qelt; register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
LockDisplay(dpy); LockDisplay(dpy);
/* Delete unclaimed cookies */
_XFreeEventCookies(dpy);
prev = NULL; prev = NULL;
while (1) { while (1) {
for (qelt = prev ? prev->next : dpy->head; for (qelt = prev ? prev->next : dpy->head;
qelt; qelt;
prev = qelt, qelt = qelt->next) { prev = qelt, qelt = qelt->next) {
if ((qelt->event.type < LASTEvent) && if ((qelt->event.type < GenericEvent) &&
(_Xevent_to_mask[qelt->event.type] & mask) && (_Xevent_to_mask[qelt->event.type] & mask) &&
((qelt->event.type != MotionNotify) || ((qelt->event.type != MotionNotify) ||
(mask & AllPointers) || (mask & AllPointers) ||
......
...@@ -35,14 +35,17 @@ in this Software without prior written authorization from The Open Group. ...@@ -35,14 +35,17 @@ in this Software without prior written authorization from The Open Group.
*/ */
int int
XNextEvent (dpy, event) XNextEvent (
register Display *dpy; register Display *dpy,
register XEvent *event; register XEvent *event)
{ {
register _XQEvent *qelt; register _XQEvent *qelt;
LockDisplay(dpy); LockDisplay(dpy);
/* Delete unclaimed cookies */
_XFreeEventCookies(dpy);
if (dpy->head == NULL) if (dpy->head == NULL)
_XReadEvents(dpy); _XReadEvents(dpy);
#ifdef NX_TRANS_SOCKET #ifdef NX_TRANS_SOCKET
...@@ -54,6 +57,7 @@ XNextEvent (dpy, event) ...@@ -54,6 +57,7 @@ XNextEvent (dpy, event)
qelt = dpy->head; qelt = dpy->head;
*event = qelt->event; *event = qelt->event;
_XDeq(dpy, NULL, qelt); _XDeq(dpy, NULL, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy); UnlockDisplay(dpy);
return 0; return 0;
} }
......
...@@ -53,10 +53,14 @@ in this Software without prior written authorization from The Open Group. ...@@ -53,10 +53,14 @@ in this Software without prior written authorization from The Open Group.
#include <config.h> #include <config.h>
#endif #endif
#include "Xlibint.h" #include "Xlibint.h"
#if USE_XCB
#include "Xxcbint.h"
#else /* !USE_XCB */
#include <nx-X11/Xtrans/Xtrans.h> #include <nx-X11/Xtrans/Xtrans.h>
#include <nx-X11/extensions/bigreqstr.h>
#endif /* USE_XCB */
#include <nx-X11/Xatom.h> #include <nx-X11/Xatom.h>
#include <nx-X11/Xresource.h> #include <nx-X11/Xresource.h>
#include <nx-X11/extensions/bigreqstr.h>
#include <stdio.h> #include <stdio.h>
#include "Xintconn.h" #include "Xintconn.h"
...@@ -68,6 +72,7 @@ in this Software without prior written authorization from The Open Group. ...@@ -68,6 +72,7 @@ in this Software without prior written authorization from The Open Group.
extern void *_X11TransSocketProxyConnInfo(XtransConnInfo); extern void *_X11TransSocketProxyConnInfo(XtransConnInfo);
#endif #endif
#if !USE_XCB
#ifdef X_NOT_POSIX #ifdef X_NOT_POSIX
#define Size_t unsigned int #define Size_t unsigned int
#else #else
...@@ -80,6 +85,7 @@ typedef struct { ...@@ -80,6 +85,7 @@ typedef struct {
unsigned long seq; unsigned long seq;
int opcode; int opcode;
} _XBigReqState; } _XBigReqState;
#endif /* !USE_XCB */
#ifdef XTHREADS #ifdef XTHREADS
#include "locking.h" #include "locking.h"
...@@ -98,8 +104,10 @@ static xReq _dummy_request = { ...@@ -98,8 +104,10 @@ static xReq _dummy_request = {
}; };
static void OutOfMemory(Display *dpy, char *setup); static void OutOfMemory(Display *dpy, char *setup);
#if !USE_XCB
static Bool _XBigReqHandler(Display *dpy, xReply *rep, char *buf, int len, static Bool _XBigReqHandler(Display *dpy, xReply *rep, char *buf, int len,
XPointer data); XPointer data);
#endif /* !USE_XCB */
/* /*
* Connects to a server, creates a Display object and returns a pointer to * Connects to a server, creates a Display object and returns a pointer to
...@@ -113,15 +121,19 @@ XOpenDisplay ( ...@@ -113,15 +121,19 @@ XOpenDisplay (
register int i; register int i;
int j, k; /* random iterator indexes */ int j, k; /* random iterator indexes */
char *display_name; /* pointer to display name */ char *display_name; /* pointer to display name */
#if !USE_XCB
int endian; /* to determine which endian. */ int endian; /* to determine which endian. */
xConnClientPrefix client; /* client information */ xConnClientPrefix client; /* client information */
xConnSetupPrefix prefix; /* prefix information */ int idisplay; /* display number */
int vendorlen; /* length of vendor string */ 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 *setup = NULL; /* memory allocated at startup */
char *fullname = NULL; /* expanded name of display */ char *fullname = NULL; /* expanded name of display */
int idisplay; /* display number */
int iscreen; /* screen number */ int iscreen; /* screen number */
int prefixread = 0; /* setup prefix already read? */ xConnSetupPrefix prefix; /* prefix information */
int vendorlen; /* length of vendor string */
union { union {
xConnSetup *setup; xConnSetup *setup;
char *failure; char *failure;
...@@ -133,14 +145,14 @@ XOpenDisplay ( ...@@ -133,14 +145,14 @@ XOpenDisplay (
} u; /* proto data returned from server */ } u; /* proto data returned from server */
long setuplength; /* number of bytes in setup message */ long setuplength; /* number of bytes in setup message */
long usedbytes = 0; /* number of bytes we have processed */ 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; unsigned long mask;
long int conn_buf_size; long int conn_buf_size;
char *xlib_buffer_size; char *xlib_buffer_size;
#if !USE_XCB
bzero((char *) &client, sizeof(client)); bzero((char *) &client, sizeof(client));
bzero((char *) &prefix, sizeof(prefix)); bzero((char *) &prefix, sizeof(prefix));
#endif /* !USE_XCB */
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
fprintf(stderr, "\nXOpenDisplay: Called with display [%s].\n", display); fprintf(stderr, "\nXOpenDisplay: Called with display [%s].\n", display);
...@@ -159,6 +171,7 @@ XOpenDisplay ( ...@@ -159,6 +171,7 @@ XOpenDisplay (
/* Display is non-NULL, copy the pointer */ /* Display is non-NULL, copy the pointer */
display_name = (char *)display; display_name = (char *)display;
} }
/* /*
* Set the default error handlers. This allows the global variables to * Set the default error handlers. This allows the global variables to
* default to NULL for use with shared libraries. * default to NULL for use with shared libraries.
...@@ -179,6 +192,32 @@ XOpenDisplay ( ...@@ -179,6 +192,32 @@ XOpenDisplay (
* will set fullname to point to the expanded name. * 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 ( if ((dpy->trans_conn = _X11TransConnectDisplay (
display_name, &fullname, &idisplay, display_name, &fullname, &idisplay,
&iscreen, &conn_auth_name, &iscreen, &conn_auth_name,
...@@ -189,6 +228,7 @@ XOpenDisplay ( ...@@ -189,6 +228,7 @@ XOpenDisplay (
} }
dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn); dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn);
#endif /* USE_XCB */
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
fprintf(stderr, "\nXOpenDisplay: Connected display with dpy->fd = [%d].\n", dpy->fd); fprintf(stderr, "\nXOpenDisplay: Connected display with dpy->fd = [%d].\n", dpy->fd);
...@@ -283,7 +323,14 @@ XOpenDisplay ( ...@@ -283,7 +323,14 @@ XOpenDisplay (
#ifndef XLIBMINBUFSIZE #ifndef XLIBMINBUFSIZE
#define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */ #define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */
#endif #endif
if ((xlib_buffer_size = getenv("XLIBBUFFERSIZE")) == NULL) 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; conn_buf_size = XLIBDEFAULTBUFSIZE;
else else
conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10); conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10);
...@@ -299,6 +346,10 @@ XOpenDisplay ( ...@@ -299,6 +346,10 @@ XOpenDisplay (
return(NULL); return(NULL);
} }
dpy->bufmax = dpy->buffer + conn_buf_size; 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. */ /* Set up the input event queue and input event queue parameters. */
dpy->head = dpy->tail = NULL; dpy->head = dpy->tail = NULL;
...@@ -312,6 +363,7 @@ XOpenDisplay ( ...@@ -312,6 +363,7 @@ XOpenDisplay (
return(NULL); return(NULL);
} }
#if !USE_XCB
/* /*
* The xConnClientPrefix describes the initial connection setup information * The xConnClientPrefix describes the initial connection setup information
* and is followed by the authorization information. Sites that are interested * and is followed by the authorization information. Sites that are interested
...@@ -373,7 +425,18 @@ XOpenDisplay ( ...@@ -373,7 +425,18 @@ XOpenDisplay (
Xfree ((char *)dpy); Xfree ((char *)dpy);
return(NULL); 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; setuplength = prefix.length << 2;
if ( (u.setup = (xConnSetup *) if ( (u.setup = (xConnSetup *)
(setup = Xmalloc ((unsigned) setuplength))) == NULL) { (setup = Xmalloc ((unsigned) setuplength))) == NULL) {
...@@ -404,6 +467,7 @@ XOpenDisplay ( ...@@ -404,6 +467,7 @@ XOpenDisplay (
OutOfMemory(dpy, setup); OutOfMemory(dpy, setup);
return (NULL); return (NULL);
} }
#endif /* USE_XCB */
/* /*
* Check if the reply was long enough to get any information out of it. * Check if the reply was long enough to get any information out of it.
...@@ -480,11 +544,8 @@ XOpenDisplay ( ...@@ -480,11 +544,8 @@ XOpenDisplay (
(void) strncpy(dpy->vendor, u.vendor, vendorlen); (void) strncpy(dpy->vendor, u.vendor, vendorlen);
dpy->vendor[vendorlen] = '\0'; dpy->vendor[vendorlen] = '\0';
vendorlen = (vendorlen + 3) & ~3; /* round up */ 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..... * Now iterate down setup information.....
*/ */
...@@ -637,7 +698,9 @@ XOpenDisplay ( ...@@ -637,7 +698,9 @@ XOpenDisplay (
* Now start talking to the server to setup all other information... * Now start talking to the server to setup all other information...
*/ */
#if !USE_XCB
Xfree (setup); /* all finished with setup information */ Xfree (setup); /* all finished with setup information */
#endif /* !USE_XCB */
/* /*
* Make sure default screen is legal. * Make sure default screen is legal.
...@@ -647,10 +710,18 @@ XOpenDisplay ( ...@@ -647,10 +710,18 @@ XOpenDisplay (
return(NULL); return(NULL);
} }
#if !USE_XCB
/* /*
* finished calling internal routines, now unlock for external routines * finished calling internal routines, now unlock for external routines
*/ */
UnlockDisplay(dpy); 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. * Set up other stuff clients are always going to use.
...@@ -679,11 +750,12 @@ XOpenDisplay ( ...@@ -679,11 +750,12 @@ XOpenDisplay (
*/ */
LockDisplay(dpy); LockDisplay(dpy);
{ {
xGetPropertyReply reply;
xGetPropertyReq *req;
#if !USE_XCB
_XAsyncHandler async; _XAsyncHandler async;
_XBigReqState async_state; _XBigReqState async_state;
xQueryExtensionReq *qreq; xQueryExtensionReq *qreq;
xGetPropertyReply reply;
xGetPropertyReq *req;
xBigReqEnableReq *breq; xBigReqEnableReq *breq;
xBigReqEnableReply brep; xBigReqEnableReply brep;
...@@ -697,6 +769,7 @@ XOpenDisplay ( ...@@ -697,6 +769,7 @@ XOpenDisplay (
qreq->nbytes = bignamelen; qreq->nbytes = bignamelen;
qreq->length += (bignamelen+3)>>2; qreq->length += (bignamelen+3)>>2;
Data(dpy, XBigReqExtensionName, bignamelen); Data(dpy, XBigReqExtensionName, bignamelen);
#endif /* !USE_XCB */
GetReq (GetProperty, req); GetReq (GetProperty, req);
req->window = RootWindow(dpy, 0); req->window = RootWindow(dpy, 0);
...@@ -717,6 +790,7 @@ XOpenDisplay ( ...@@ -717,6 +790,7 @@ XOpenDisplay (
else if (reply.propertyType != None) else if (reply.propertyType != None)
_XEatData(dpy, reply.nItems * (reply.format >> 3)); _XEatData(dpy, reply.nItems * (reply.format >> 3));
} }
#if !USE_XCB
DeqAsyncHandler(dpy, &async); DeqAsyncHandler(dpy, &async);
if (async_state.opcode) { if (async_state.opcode) {
GetReq(BigReqEnable, breq); GetReq(BigReqEnable, breq);
...@@ -725,6 +799,7 @@ XOpenDisplay ( ...@@ -725,6 +799,7 @@ XOpenDisplay (
if (_XReply(dpy, (xReply *)&brep, 0, xFalse)) if (_XReply(dpy, (xReply *)&brep, 0, xFalse))
dpy->bigreq_size = brep.max_request_size; dpy->bigreq_size = brep.max_request_size;
} }
#endif /* !USE_XCB */
} }
UnlockDisplay(dpy); UnlockDisplay(dpy);
...@@ -746,13 +821,14 @@ XOpenDisplay ( ...@@ -746,13 +821,14 @@ XOpenDisplay (
return(dpy); return(dpy);
} }
#if !USE_XCB
static Bool static Bool
_XBigReqHandler(dpy, rep, buf, len, data) _XBigReqHandler(
register Display *dpy; register Display *dpy,
register xReply *rep; register xReply *rep,
char *buf; char *buf,
int len; int len,
XPointer data; XPointer data)
{ {
_XBigReqState *state; _XBigReqState *state;
xQueryExtensionReply replbuf; xQueryExtensionReply replbuf;
...@@ -771,6 +847,7 @@ _XBigReqHandler(dpy, rep, buf, len, data) ...@@ -771,6 +847,7 @@ _XBigReqHandler(dpy, rep, buf, len, data)
state->opcode = repl->major_opcode; state->opcode = repl->major_opcode;
return True; return True;
} }
#endif /* !USE_XCB */
/* XFreeDisplayStructure frees all the storage associated with a /* XFreeDisplayStructure frees all the storage associated with a
...@@ -782,9 +859,19 @@ _XBigReqHandler(dpy, rep, buf, len, data) ...@@ -782,9 +859,19 @@ _XBigReqHandler(dpy, rep, buf, len, data)
* before the first possible call on this. * before the first possible call on this.
*/ */
void _XFreeDisplayStructure(dpy) void _XFreeDisplayStructure(Display *dpy)
register 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) { while (dpy->ext_procs) {
_XExtension *ext = dpy->ext_procs; _XExtension *ext = dpy->ext_procs;
dpy->ext_procs = ext->next; dpy->ext_procs = ext->next;
...@@ -898,17 +985,26 @@ void _XFreeDisplayStructure(dpy) ...@@ -898,17 +985,26 @@ void _XFreeDisplayStructure(dpy)
if (dpy->filedes) if (dpy->filedes)
Xfree (dpy->filedes); Xfree (dpy->filedes);
#if USE_XCB
_XFreeX11XCBStructure(dpy);
#endif /* USE_XCB */
Xfree ((char *)dpy); Xfree ((char *)dpy);
} }
/* OutOfMemory is called if malloc fails. XOpenDisplay returns NULL /* OutOfMemory is called if malloc fails. XOpenDisplay returns NULL
after this returns. */ after this returns. */
static void OutOfMemory (dpy, setup) static void OutOfMemory(Display *dpy, char *setup)
Display *dpy;
char *setup;
{ {
#if USE_XCB
if(dpy->xcb->connection)
xcb_disconnect(dpy->xcb->connection);
#else /* !USE_XCB */
_XDisconnectDisplay (dpy->trans_conn); _XDisconnectDisplay (dpy->trans_conn);
#endif /* USE_XCB */
_XFreeDisplayStructure (dpy); _XFreeDisplayStructure (dpy);
#if !USE_XCB
if (setup) Xfree (setup); if (setup) Xfree (setup);
#endif /* !USE_XCB */
} }
...@@ -36,10 +36,11 @@ in this Software without prior written authorization from The Open Group. ...@@ -36,10 +36,11 @@ in this Software without prior written authorization from The Open Group.
*/ */
int int
XPeekEvent (dpy, event) XPeekEvent (
register Display *dpy; register Display *dpy,
register XEvent *event; register XEvent *event)
{ {
XEvent copy;
LockDisplay(dpy); LockDisplay(dpy);
if (dpy->head == NULL) if (dpy->head == NULL)
_XReadEvents(dpy); _XReadEvents(dpy);
...@@ -50,6 +51,10 @@ XPeekEvent (dpy, event) ...@@ -50,6 +51,10 @@ XPeekEvent (dpy, event)
} }
#endif #endif
*event = (dpy->head)->event; *event = (dpy->head)->event;
if (_XCopyEventCookie(dpy, &event->xcookie, &copy.xcookie)) {
_XStoreEventCookie(dpy, &copy);
*event = copy;
}
UnlockDisplay(dpy); UnlockDisplay(dpy);
return 1; return 1;
} }
......
...@@ -36,15 +36,15 @@ in this Software without prior written authorization from The Open Group. ...@@ -36,15 +36,15 @@ in this Software without prior written authorization from The Open Group.
*/ */
int int
XPeekIfEvent (dpy, event, predicate, arg) XPeekIfEvent (
register Display *dpy; register Display *dpy,
register XEvent *event; register XEvent *event,
Bool (*predicate)( Bool (*predicate)(
Display* /* display */, Display* /* display */,
XEvent* /* event */, XEvent* /* event */,
char* /* arg */ char* /* arg */
); ),
char *arg; char *arg)
{ {
register _XQEvent *prev, *qelt; register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
...@@ -57,7 +57,12 @@ XPeekIfEvent (dpy, event, predicate, arg) ...@@ -57,7 +57,12 @@ XPeekIfEvent (dpy, event, predicate, arg)
prev = qelt, qelt = qelt->next) { prev = qelt, qelt = qelt->next) {
if(qelt->qserial_num > qe_serial if(qelt->qserial_num > qe_serial
&& (*predicate)(dpy, &qelt->event, arg)) { && (*predicate)(dpy, &qelt->event, arg)) {
XEvent copy;
*event = qelt->event; *event = qelt->event;
if (_XCopyEventCookie(dpy, &event->xcookie, &copy.xcookie)) {
_XStoreEventCookie(dpy, &copy);
*event = copy;
}
UnlockDisplay(dpy); UnlockDisplay(dpy);
return 0; return 0;
} }
......
...@@ -33,9 +33,9 @@ in this Software without prior written authorization from The Open Group. ...@@ -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. */ /* Read in pending events if needed and return the number of queued events. */
int XEventsQueued (dpy, mode) int XEventsQueued (
register Display *dpy; register Display *dpy,
int mode; int mode)
{ {
int ret_val; int ret_val;
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
...@@ -54,8 +54,7 @@ int XEventsQueued (dpy, mode) ...@@ -54,8 +54,7 @@ int XEventsQueued (dpy, mode)
return ret_val; return ret_val;
} }
int XPending (dpy) int XPending (register Display *dpy)
register Display *dpy;
{ {
int ret_val; int ret_val;
LockDisplay(dpy); LockDisplay(dpy);
......
...@@ -43,23 +43,27 @@ extern long const _Xevent_to_mask[]; ...@@ -43,23 +43,27 @@ extern long const _Xevent_to_mask[];
*/ */
int int
XWindowEvent (dpy, w, mask, event) XWindowEvent (
register Display *dpy; register Display *dpy,
Window w; /* Selected window. */ Window w, /* Selected window. */
long mask; /* Selected event mask. */ long mask, /* Selected event mask. */
register XEvent *event; /* XEvent to be filled in. */ register XEvent *event) /* XEvent to be filled in. */
{ {
register _XQEvent *prev, *qelt; register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0; unsigned long qe_serial = 0;
LockDisplay(dpy); LockDisplay(dpy);
/* Delete unclaimed cookies */
_XFreeEventCookies(dpy);
prev = NULL; prev = NULL;
while (1) { while (1) {
for (qelt = prev ? prev->next : dpy->head; for (qelt = prev ? prev->next : dpy->head;
qelt; qelt;
prev = qelt, qelt = qelt->next) { prev = qelt, qelt = qelt->next) {
if ((qelt->event.xany.window == w) && if ((qelt->event.xany.window == w) &&
(qelt->event.type < LASTEvent) && (qelt->event.type < GenericEvent) &&
(_Xevent_to_mask[qelt->event.type] & mask) && (_Xevent_to_mask[qelt->event.type] & mask) &&
((qelt->event.type != MotionNotify) || ((qelt->event.type != MotionNotify) ||
(mask & AllPointers) || (mask & AllPointers) ||
......
...@@ -30,27 +30,12 @@ in this Software without prior written authorization from 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). * interface library (Xlib) to the X Window System Protocol (V11).
* Structures and symbols starting with "_" are private to the library. * Structures and symbols starting with "_" are private to the library.
*/ */
#ifndef _XLIB_H_
#if !defined(_XLIB_H_) && !defined(_X11_XLIB_H_)
#define _XLIB_H_ #define _XLIB_H_
#define _X11_XLIB_H_
#define XlibSpecificationRelease 6 #define XlibSpecificationRelease 6
#ifdef USG
#ifndef __TYPES__
#include <sys/types.h> /* forgot to protect it... */
#define __TYPES__
#endif /* __TYPES__ */
#else
#if defined(_POSIX_SOURCE) && defined(MOTOROLA)
#undef _POSIX_SOURCE
#include <sys/types.h>
#define _POSIX_SOURCE
#else
#include <sys/types.h> #include <sys/types.h>
#endif
#endif /* USG */
#if defined(__SCO__) || defined(__UNIXWARE__) #if defined(__SCO__) || defined(__UNIXWARE__)
#include <stdint.h> #include <stdint.h>
...@@ -63,14 +48,6 @@ in this Software without prior written authorization from The Open Group. ...@@ -63,14 +48,6 @@ in this Software without prior written authorization from The Open Group.
#include <nx-X11/Xosdefs.h> #include <nx-X11/Xosdefs.h>
#ifndef X_WCHAR #ifndef X_WCHAR
#ifdef X_NOT_STDC_ENV
#ifndef ISC
#define X_WCHAR
#endif
#endif
#endif
#ifndef X_WCHAR
#include <stddef.h> #include <stddef.h>
#else #else
#ifdef __UNIXOS2__ #ifdef __UNIXOS2__
...@@ -143,7 +120,11 @@ typedef char *XPointer; ...@@ -143,7 +120,11 @@ typedef char *XPointer;
#define BitmapBitOrder(dpy) (((_XPrivDisplay)dpy)->bitmap_bit_order) #define BitmapBitOrder(dpy) (((_XPrivDisplay)dpy)->bitmap_bit_order)
#define BitmapPad(dpy) (((_XPrivDisplay)dpy)->bitmap_pad) #define BitmapPad(dpy) (((_XPrivDisplay)dpy)->bitmap_pad)
#define ImageByteOrder(dpy) (((_XPrivDisplay)dpy)->byte_order) #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) #define NextRequest(dpy) (((_XPrivDisplay)dpy)->request + 1)
#endif
#define LastKnownRequestProcessed(dpy) (((_XPrivDisplay)dpy)->last_request_read) #define LastKnownRequestProcessed(dpy) (((_XPrivDisplay)dpy)->last_request_read)
/* macros for screen oriented applications (toolkit) */ /* macros for screen oriented applications (toolkit) */
...@@ -966,6 +947,33 @@ typedef struct { ...@@ -966,6 +947,33 @@ typedef struct {
Window window; /* window on which event was requested in event mask */ Window window; /* window on which event was requested in event mask */
} XAnyEvent; } 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 * this union is defined so Xlib can always use the same sized
* event structure internally, to avoid memory fragmentation. * event structure internally, to avoid memory fragmentation.
...@@ -1003,6 +1011,8 @@ typedef union _XEvent { ...@@ -1003,6 +1011,8 @@ typedef union _XEvent {
XMappingEvent xmapping; XMappingEvent xmapping;
XErrorEvent xerror; XErrorEvent xerror;
XKeymapEvent xkeymap; XKeymapEvent xkeymap;
XGenericEvent xgeneric;
XGenericEventCookie xcookie;
long pad[24]; long pad[24];
} XEvent; } XEvent;
#endif #endif
...@@ -4019,6 +4029,16 @@ extern int _Xwctomb( ...@@ -4019,6 +4029,16 @@ extern int _Xwctomb(
wchar_t /* wc */ wchar_t /* wc */
); );
extern Bool XGetEventData(
Display* /* dpy */,
XGenericEventCookie* /* cookie*/
);
extern void XFreeEventData(
Display* /* dpy */,
XGenericEventCookie* /* cookie*/
);
_XFUNCPROTOEND _XFUNCPROTOEND
#endif /* _XLIB_H_ */ #endif /* _XLIB_H_ */
...@@ -59,12 +59,12 @@ from The Open Group. ...@@ -59,12 +59,12 @@ from The Open Group.
/*ARGSUSED*/ /*ARGSUSED*/
Bool Bool
_XAsyncErrorHandler(dpy, rep, buf, len, data) _XAsyncErrorHandler(
register Display *dpy; register Display *dpy,
register xReply *rep; register xReply *rep,
char *buf; char *buf,
int len; int len,
XPointer data; XPointer data)
{ {
register _XAsyncErrorState *state; register _XAsyncErrorState *state;
...@@ -87,9 +87,9 @@ _XAsyncErrorHandler(dpy, rep, buf, len, data) ...@@ -87,9 +87,9 @@ _XAsyncErrorHandler(dpy, rep, buf, len, data)
return False; return False;
} }
void _XDeqAsyncHandler(dpy, handler) void _XDeqAsyncHandler(
Display *dpy; Display *dpy,
register _XAsyncHandler *handler; register _XAsyncHandler *handler)
{ {
register _XAsyncHandler **prev; register _XAsyncHandler **prev;
register _XAsyncHandler *async; register _XAsyncHandler *async;
...@@ -103,14 +103,14 @@ void _XDeqAsyncHandler(dpy, handler) ...@@ -103,14 +103,14 @@ void _XDeqAsyncHandler(dpy, handler)
} }
char * char *
_XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) _XGetAsyncReply(
register Display *dpy; register Display *dpy,
register char *replbuf; /* data is read into this buffer */ register char *replbuf, /* data is read into this buffer */
register xReply *rep; /* value passed to calling handler */ register xReply *rep, /* value passed to calling handler */
char *buf; /* value passed to calling handler */ char *buf, /* value passed to calling handler */
int len; /* value passed to calling handler */ int len, /* value passed to calling handler */
int extra; /* extra words to read, ala _XReply */ int extra, /* extra words to read, ala _XReply */
Bool discard; /* discard after extra?, ala _XReply */ Bool discard) /* discard after extra?, ala _XReply */
{ {
if (extra == 0) { if (extra == 0) {
if (discard && (rep->generic.length << 2) > len) if (discard && (rep->generic.length << 2) > len)
...@@ -125,6 +125,11 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) ...@@ -125,6 +125,11 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard)
_XRead(dpy, replbuf + len, size - len); _XRead(dpy, replbuf + len, size - len);
buf = replbuf; buf = replbuf;
len = size; len = size;
#ifdef MUSTCOPY
} else {
memcpy(replbuf, buf, size);
buf = replbuf;
#endif
} }
if (discard && rep->generic.length > extra && if (discard && rep->generic.length > extra &&
...@@ -153,15 +158,15 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard) ...@@ -153,15 +158,15 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard)
} }
void void
_XGetAsyncData(dpy, data, buf, len, skip, datalen, discardtotal) _XGetAsyncData(
Display *dpy; Display *dpy,
char *data; /* data is read into this buffer */ char *data, /* data is read into this buffer */
char *buf; /* value passed to calling handler */ char *buf, /* value passed to calling handler */
int len; /* value passed to calling handler */ int len, /* value passed to calling handler */
int skip; /* number of bytes already read in previous int skip, /* number of bytes already read in previous
_XGetAsyncReply or _XGetAsyncData calls */ _XGetAsyncReply or _XGetAsyncData calls */
int datalen; /* size of data buffer in bytes */ int datalen, /* size of data buffer in bytes */
int discardtotal; /* min. bytes to consume (after skip) */ int discardtotal) /* min. bytes to consume (after skip) */
{ {
buf += skip; buf += skip;
len -= skip; len -= skip;
......
...@@ -63,9 +63,13 @@ from The Open Group. ...@@ -63,9 +63,13 @@ from The Open Group.
#include <config.h> #include <config.h>
#endif #endif
#include "Xlibint.h" #include "Xlibint.h"
#include "Xprivate.h"
#include <nx-X11/Xpoll.h> #include <nx-X11/Xpoll.h>
#if !USE_XCB
#include <nx-X11/Xtrans/Xtrans.h> #include <nx-X11/Xtrans/Xtrans.h>
#include <nx-X11/extensions/xcmiscstr.h> #include <nx-X11/extensions/xcmiscstr.h>
#endif /* !USE_XCB */
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#ifdef WIN32 #ifdef WIN32
#include <direct.h> #include <direct.h>
...@@ -97,6 +101,7 @@ xthread_t (*_Xthread_self_fn)(void) = NULL; ...@@ -97,6 +101,7 @@ xthread_t (*_Xthread_self_fn)(void) = NULL;
#define XThread_Self() ((*_Xthread_self_fn)()) #define XThread_Self() ((*_Xthread_self_fn)())
#if !USE_XCB
#define UnlockNextReplyReader(d) if ((d)->lock) \ #define UnlockNextReplyReader(d) if ((d)->lock) \
(*(d)->lock->pop_reader)((d),&(d)->lock->reply_awaiters,&(d)->lock->reply_awaiters_tail) (*(d)->lock->pop_reader)((d),&(d)->lock->reply_awaiters,&(d)->lock->reply_awaiters_tail)
...@@ -104,25 +109,17 @@ xthread_t (*_Xthread_self_fn)(void) = NULL; ...@@ -104,25 +109,17 @@ xthread_t (*_Xthread_self_fn)(void) = NULL;
(*(d)->lock->push_reader)(d,&(d)->lock->reply_awaiters_tail) : NULL) (*(d)->lock->push_reader)(d,&(d)->lock->reply_awaiters_tail) : NULL)
#define QueueEventReaderLock(d) ((d)->lock ? \ #define QueueEventReaderLock(d) ((d)->lock ? \
(*(d)->lock->push_reader)(d,&(d)->lock->event_awaiters_tail) : NULL) (*(d)->lock->push_reader)(d,&(d)->lock->event_awaiters_tail) : NULL)
#endif /* !USE_XCB */
#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 */ #else /* XTHREADS else */
#if !USE_XCB
#define UnlockNextReplyReader(d) #define UnlockNextReplyReader(d)
#define UnlockNextEventReader(d) #define UnlockNextEventReader(d)
#define InternalLockDisplay(d,wskip) #endif /* !USE_XCB */
#endif /* XTHREADS else */ #endif /* XTHREADS else */
#include <nx/NX.h>
#ifdef NX_TRANS_SOCKET #ifdef NX_TRANS_SOCKET
#include <nx/NX.h> #include <nx/NX.h>
...@@ -142,9 +139,7 @@ static struct timeval retry; ...@@ -142,9 +139,7 @@ static struct timeval retry;
*/ */
#ifdef NX_TRANS_CHANGE #ifdef NX_TRANS_CHANGE
extern int _X11TransSocketCongestionChange(XtransConnInfo, int *); extern int _X11TransSocketCongestionChange(XtransConnInfo, int *);
#endif #endif
#endif /* #ifdef NX_TRANS_SOCKET */ #endif /* #ifdef NX_TRANS_SOCKET */
...@@ -178,11 +173,7 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *); ...@@ -178,11 +173,7 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *);
#define ECHECK(err) (errno == err) #define ECHECK(err) (errno == err)
#define ESET(val) #define ESET(val)
#else #else
#ifdef ISC
#define ECHECK(err) ((errno == err) || ETEST())
#else
#define ECHECK(err) (errno == err) #define ECHECK(err) (errno == err)
#endif
#define ESET(val) errno = val #define ESET(val) errno = val
#endif #endif
#endif #endif
...@@ -200,11 +191,28 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *); ...@@ -200,11 +191,28 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *);
#endif #endif
#ifdef __UNIXOS2__ #ifdef __UNIXOS2__
#if !USE_XCB
#define select(n,r,w,x,t) os2ClientSelect(n,r,w,x,t) #define select(n,r,w,x,t) os2ClientSelect(n,r,w,x,t)
#endif /* !USE_XCB */
#include <limits.h> #include <limits.h>
#define MAX_PATH _POSIX_PATH_MAX #define MAX_PATH _POSIX_PATH_MAX
#endif #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) \ #define STARTITERATE(tpvar,type,start,endcond) \
for (tpvar = (type *) (start); endcond; ) for (tpvar = (type *) (start); endcond; )
#define ITERPTR(tpvar) (char *)tpvar #define ITERPTR(tpvar) (char *)tpvar
...@@ -212,6 +220,8 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *); ...@@ -212,6 +220,8 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *);
#define INCITERPTR(tpvar,type) tpvar++ #define INCITERPTR(tpvar,type) tpvar++
#define ENDITERATE #define ENDITERATE
#endif /* MUSTCOPY */
typedef union { typedef union {
xReply rep; xReply rep;
char buf[BUFSIZE]; char buf[BUFSIZE];
...@@ -223,12 +233,7 @@ static char *_XAsyncReply( ...@@ -223,12 +233,7 @@ static char *_XAsyncReply(
char *buf, char *buf,
register int *lenp, register int *lenp,
Bool discard); Bool discard);
#endif /* !USE_XCB */
static void _XProcessInternalConnection(
Display *dpy,
struct _XConnectionInfo *conn_info);
#define SEQLIMIT (65535 - (BUFSIZE / SIZEOF(xReq)) - 10)
/* /*
* The following routines are internal routines used by Xlib for protocol * The following routines are internal routines used by Xlib for protocol
...@@ -248,6 +253,7 @@ static void _XProcessInternalConnection( ...@@ -248,6 +253,7 @@ static void _XProcessInternalConnection(
* the object they have created. * the object they have created.
*/ */
#if !USE_XCB
static xReq _dummy_request = { static xReq _dummy_request = {
0, 0, 0 0, 0, 0
}; };
...@@ -369,16 +375,13 @@ _XWaitForWritable( ...@@ -369,16 +375,13 @@ _XWaitForWritable(
#endif #endif
int nfound; int nfound;
#ifdef NX_TRANS_SOCKET
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
int congestion; int congestion;
#endif #endif
#ifdef NX_TRANS_SOCKET
if (_XGetIOError(dpy)) { if (_XGetIOError(dpy)) {
return; return;
} }
#endif #endif
#ifdef USE_POLL #ifdef USE_POLL
...@@ -456,18 +459,17 @@ _XWaitForWritable( ...@@ -456,18 +459,17 @@ _XWaitForWritable(
FD_SET(dpy->fd, &w_mask); FD_SET(dpy->fd, &w_mask);
#endif #endif
#endif /* #ifdef NX_TRANS_SOCKET */ #endif /* #ifdef NX_TRANS_SOCKET */
UnlockDisplay(dpy); UnlockDisplay(dpy);
#ifdef USE_POLL #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"); fprintf(stderr, "_XWaitForWritable: Calling poll().\n");
#endif #endif
nfound = poll (&filedes, 1, -1); nfound = poll (&filedes, 1, -1);
#else #else /* USE_POLL */
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XWaitForWritable: Calling select() after [%ld] ms.\n", fprintf(stderr, "_XWaitForWritable: Calling select() after [%ld] ms.\n",
NXTransTime()); NXTransTime());
#endif #endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) */
#ifdef NX_TRANS_SOCKET #ifdef NX_TRANS_SOCKET
/* /*
* Give a chance to the callback to detect * Give a chance to the callback to detect
...@@ -482,9 +484,9 @@ _XWaitForWritable( ...@@ -482,9 +484,9 @@ _XWaitForWritable(
} else { } else {
nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL); 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); nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL);
#endif #endif /* NX_TRANS_SOCKET */
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XWaitForWritable: Out of select() with [%d] after [%ld] ms.\n", fprintf(stderr, "_XWaitForWritable: Out of select() with [%d] after [%ld] ms.\n",
nfound, NXTransTime()); nfound, NXTransTime());
...@@ -504,37 +506,36 @@ _XWaitForWritable( ...@@ -504,37 +506,36 @@ _XWaitForWritable(
fprintf(stderr, "_XWaitForWritable: Descriptor [%d] has become writable.\n\n", fprintf(stderr, "_XWaitForWritable: Descriptor [%d] has become writable.\n\n",
dpy->fd); dpy->fd);
} }
#endif #endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) */
#endif #endif /* USE_POLL */
InternalLockDisplay(dpy, cv != NULL); InternalLockDisplay(dpy, cv != NULL);
#ifdef NX_TRANS_SOCKET
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
if (_NXDisplayCongestionFunction != NULL && if (_NXDisplayCongestionFunction != NULL &&
_X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) { _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
(*_NXDisplayCongestionFunction)(dpy, congestion); (*_NXDisplayCongestionFunction)(dpy, congestion);
} }
#endif #endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE) */
#ifdef NX_TRANS_SOCKET
if (nfound <= 0) { if (nfound <= 0) {
if ((nfound == -1 && !ECHECK(EINTR)) || if ((nfound == -1 && !(ECHECK(EINTR) || ETEST())) ||
(_NXDisplayErrorFunction != NULL && (_NXDisplayErrorFunction != NULL &&
(*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) { (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
_XIOError(dpy); _XIOError(dpy);
return; return;
} }
} }
#else #else /* NX_TRANS_SOCKET */
if (nfound < 0 && !ECHECK(EINTR)) if (nfound < 0 && !(ECHECK(EINTR) || ETEST()))
_XIOError(dpy); _XIOError(dpy);
#endif #endif /* NX_TRANS_SOCKET */
} while (nfound <= 0); } while (nfound <= 0);
if ( if (
#ifdef USE_POLL #ifdef USE_POLL
filedes.revents & POLLIN filedes.revents & POLLIN
#else #else /* USE_POLL */
FD_ISSET(dpy->fd, &r_mask) FD_ISSET(dpy->fd, &r_mask)
#endif #endif /* USE_POLL */
) )
{ {
_XAlignedBuffer buf; _XAlignedBuffer buf;
...@@ -550,9 +551,9 @@ _XWaitForWritable( ...@@ -550,9 +551,9 @@ _XWaitForWritable(
return; return;
} }
#else #else /* NX_TRANS_SOCKET */
_XIOError(dpy); _XIOError(dpy);
#endif #endif /* NX_TRANS_SOCKET */
len = pend; len = pend;
/* must read at least one xEvent; if none is pending, then /* must read at least one xEvent; if none is pending, then
...@@ -609,6 +610,7 @@ _XWaitForWritable( ...@@ -609,6 +610,7 @@ _XWaitForWritable(
} }
} }
} }
#endif /* !USE_XCB */
#define POLLFD_CACHE_SIZE 5 #define POLLFD_CACHE_SIZE 5
...@@ -666,6 +668,7 @@ void _XPollfdCacheDel( ...@@ -666,6 +668,7 @@ void _XPollfdCacheDel(
#endif #endif
} }
#if !USE_XCB
/* returns True iff there is an event in the queue newer than serial_num */ /* returns True iff there is an event in the queue newer than serial_num */
static Bool static Bool
...@@ -730,9 +733,9 @@ _XWaitForReadable( ...@@ -730,9 +733,9 @@ _XWaitForReadable(
} else { } else {
filedes = (struct pollfd *)dpy->filedes; filedes = (struct pollfd *)dpy->filedes;
} }
#else #else /* USE_POLL */
FD_ZERO(&r_mask); FD_ZERO(&r_mask);
#endif #endif /* USE_POLL */
for (;;) { for (;;) {
#ifndef USE_POLL #ifndef USE_POLL
FD_SET(fd, &r_mask); FD_SET(fd, &r_mask);
...@@ -742,7 +745,7 @@ _XWaitForReadable( ...@@ -742,7 +745,7 @@ _XWaitForReadable(
if (ilist->fd > highest_fd) if (ilist->fd > highest_fd)
highest_fd = ilist->fd; highest_fd = ilist->fd;
} }
#endif #endif /* USE_POLL */
UnlockDisplay(dpy); UnlockDisplay(dpy);
#ifdef USE_POLL #ifdef USE_POLL
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
...@@ -751,7 +754,7 @@ _XWaitForReadable( ...@@ -751,7 +754,7 @@ _XWaitForReadable(
result = poll(filedes, result = poll(filedes,
(dpy->flags & XlibDisplayProcConni) ? 1 : 1+dpy->im_fd_length, (dpy->flags & XlibDisplayProcConni) ? 1 : 1+dpy->im_fd_length,
-1); -1);
#else #else /* USE_POLL */
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XWaitForReadable: Calling select().\n"); fprintf(stderr, "_XWaitForReadable: Calling select().\n");
#endif #endif
...@@ -777,10 +780,10 @@ _XWaitForReadable( ...@@ -777,10 +780,10 @@ _XWaitForReadable(
} else { } else {
result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL); 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); result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL);
#endif #endif /* NX_TRANS_SOCKET */
#endif #endif /* USE_POLL */
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XWaitForReadable: Out of select with result [%d] and errno [%d].\n", fprintf(stderr, "_XWaitForReadable: Out of select with result [%d] and errno [%d].\n",
result, (result < 0 ? errno : 0)); result, (result < 0 ? errno : 0));
...@@ -794,7 +797,7 @@ _XWaitForReadable( ...@@ -794,7 +797,7 @@ _XWaitForReadable(
#endif #endif
#ifdef NX_TRANS_SOCKET #ifdef NX_TRANS_SOCKET
if (result <= 0) { if (result <= 0) {
if ((result == -1 && !ECHECK(EINTR)) || if ((result == -1 && !(ECHECK(EINTR) || ETEST())) ||
(_NXDisplayErrorFunction != NULL && (_NXDisplayErrorFunction != NULL &&
(*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) { (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
_XIOError(dpy); _XIOError(dpy);
...@@ -803,7 +806,7 @@ _XWaitForReadable( ...@@ -803,7 +806,7 @@ _XWaitForReadable(
continue; continue;
} }
#else #else
if (result == -1 && !ECHECK(EINTR)) _XIOError(dpy); if (result == -1 && !(ECHECK(EINTR) || ETEST())) _XIOError(dpy);
if (result <= 0) if (result <= 0)
continue; continue;
#endif #endif
...@@ -856,9 +859,32 @@ _XWaitForReadable( ...@@ -856,9 +859,32 @@ _XWaitForReadable(
#endif #endif
return 0; 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 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) register Display *dpy)
{ {
xGetInputFocusReply rep; xGetInputFocusReply rep;
...@@ -868,30 +894,62 @@ int _XSeqSyncFunction( ...@@ -868,30 +894,62 @@ int _XSeqSyncFunction(
#ifdef NX_TRANS_DEBUG #ifdef NX_TRANS_DEBUG
fprintf(stderr, "_XSeqSyncFunction: Going to synchronize the display.\n"); fprintf(stderr, "_XSeqSyncFunction: Going to synchronize the display.\n");
#endif #endif
if (dpy->flags & XlibDisplayIOError) if (dpy->flags & XlibDisplayIOError)
{ {
#ifdef NX_TRANS_DEBUG #ifdef NX_TRANS_DEBUG
fprintf(stderr, "_XSeqSyncFunction: Returning 0 with I/O error detected.\n"); fprintf(stderr, "_XSeqSyncFunction: Returning 0 with I/O error detected.\n");
#endif #endif
return 0; return;
} }
#endif #endif /* NX_TRANS_SOCKET */
if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) {
LockDisplay(dpy);
if ((dpy->request - dpy->last_request_read) >= (BUFSIZE / SIZEOF(xReq))) {
GetEmptyReq(GetInputFocus, req); GetEmptyReq(GetInputFocus, req);
(void) _XReply (dpy, (xReply *)&rep, 0, xTrue); (void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
} sync_while_locked(dpy);
/* could get XID handler while waiting for reply in MT env */ } else if (sync_hazard(dpy))
if (dpy->synchandler == _XSeqSyncFunction) { _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->synchandler = dpy->savedsynchandler;
dpy->savedsynchandler = NULL;
dpy->flags &= ~XlibDisplayPrivSync; dpy->flags &= ~XlibDisplayPrivSync;
} if(dpy->synchandler)
UnlockDisplay(dpy); dpy->synchandler(dpy);
SyncHandle(); _XIDHandler(dpy);
_XSeqSyncFunction(dpy);
return 0; 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 #ifdef XTHREADS
static void _XFlushInt( static void _XFlushInt(
register Display *dpy, register Display *dpy,
...@@ -1046,12 +1104,7 @@ static void _XFlushInt( ...@@ -1046,12 +1104,7 @@ static void _XFlushInt(
#endif #endif
} }
dpy->last_req = (char *)&_dummy_request; dpy->last_req = (char *)&_dummy_request;
if ((dpy->request - dpy->last_request_read) >= SEQLIMIT && _XSetSeqSyncFunction(dpy);
!(dpy->flags & XlibDisplayPrivSync)) {
dpy->savedsynchandler = dpy->synchandler;
dpy->synchandler = _XSeqSyncFunction;
dpy->flags |= XlibDisplayPrivSync;
}
dpy->bufptr = dpy->buffer; dpy->bufptr = dpy->buffer;
#ifdef XTHREADS #ifdef XTHREADS
dpy->flags &= ~XlibDisplayWriting; dpy->flags &= ~XlibDisplayWriting;
...@@ -1192,7 +1245,7 @@ _XEventsQueued( ...@@ -1192,7 +1245,7 @@ _XEventsQueued(
} }
#ifdef NX_TRANS_SOCKET #ifdef NX_TRANS_SOCKET
if (result <= 0) { if (result <= 0) {
if ((result == -1 && !ECHECK(EINTR)) || if ((result == -1 && !(ECHECK(EINTR) || ETEST())) ||
(_NXDisplayErrorFunction != NULL && (_NXDisplayErrorFunction != NULL &&
(*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) { (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
_XIOError(dpy); _XIOError(dpy);
...@@ -1200,9 +1253,9 @@ _XEventsQueued( ...@@ -1200,9 +1253,9 @@ _XEventsQueued(
} }
} }
#else #else
else if (result < 0 && !ECHECK(EINTR)) else if (result < 0 && !(ECHECK(EINTR) || ETEST()))
_XIOError(dpy);
#endif #endif
_XIOError(dpy);
} }
} }
#endif /* XCONN_CHECK_FREQ */ #endif /* XCONN_CHECK_FREQ */
...@@ -1214,7 +1267,6 @@ _XEventsQueued( ...@@ -1214,7 +1267,6 @@ _XEventsQueued(
{ {
UnlockNextEventReader(dpy); UnlockNextEventReader(dpy);
} }
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XEventsQueued: Returning [%d].\n", dpy->qlen); fprintf(stderr, "_XEventsQueued: Returning [%d].\n", dpy->qlen);
#endif #endif
...@@ -1353,15 +1405,12 @@ void _XReadEvents( ...@@ -1353,15 +1405,12 @@ void _XReadEvents(
#endif /* XTHREADS */ #endif /* XTHREADS */
/* find out how much data can be read */ /* find out how much data can be read */
if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0) if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0)
#ifdef NX_TRANS_SOCKET
{ {
_XIOError(dpy); _XIOError(dpy);
#ifdef NX_TRANS_SOCKET
return; return;
}
#else
_XIOError(dpy);
#endif #endif
}
len = pend; len = pend;
/* must read at least one xEvent; if none is pending, then /* must read at least one xEvent; if none is pending, then
...@@ -1467,7 +1516,17 @@ void _XReadEvents( ...@@ -1467,7 +1516,17 @@ void _XReadEvents(
if (rep->generic.type == X_Error) if (rep->generic.type == X_Error)
_XError (dpy, (xError *) rep); _XError (dpy, (xError *) rep);
else /* must be an event packet */ else /* must be an event packet */
{
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); _XEnq (dpy, (xEvent *)rep);
}
INCITERPTR(rep,xReply); INCITERPTR(rep,xReply);
len -= SIZEOF(xReply); len -= SIZEOF(xReply);
} }
...@@ -1577,6 +1636,7 @@ int _XRead( ...@@ -1577,6 +1636,7 @@ int _XRead(
#endif /* XTHREADS*/ #endif /* XTHREADS*/
return 0; return 0;
} }
#endif /* !USE_XCB */
#ifdef LONG64 #ifdef LONG64
void _XRead32( void _XRead32(
...@@ -1598,8 +1658,128 @@ void _XRead32( ...@@ -1598,8 +1658,128 @@ void _XRead32(
} }
#endif /* LONG64 */ #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<nwords;i++){
maskw = mask32 << bits;
*lp++ = ( *lpack & maskw ) >> 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<nwords;i++){
maskw = mask16 << bits;
*lp++ = ( *lpack & maskw ) >> 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 * _XReadPad - Read bytes from the socket taking into account incomplete
* reads. If the number of bytes is not 0 mod 4, read additional pad * reads. If the number of bytes is not 0 mod 4, read additional pad
* bytes. This routine may have to be reworked if int < long. * bytes. This routine may have to be reworked if int < long.
...@@ -1882,12 +2062,7 @@ _XSend ( ...@@ -1882,12 +2062,7 @@ _XSend (
#endif #endif
} }
dpy->last_req = (char *) & _dummy_request; dpy->last_req = (char *) & _dummy_request;
if ((dpy->request - dpy->last_request_read) >= SEQLIMIT && _XSetSeqSyncFunction(dpy);
!(dpy->flags & XlibDisplayPrivSync)) {
dpy->savedsynchandler = dpy->synchandler;
dpy->synchandler = _XSeqSyncFunction;
dpy->flags |= XlibDisplayPrivSync;
}
dpy->bufptr = dpy->buffer; dpy->bufptr = dpy->buffer;
#ifdef XTHREADS #ifdef XTHREADS
dpy->flags &= ~XlibDisplayWriting; dpy->flags &= ~XlibDisplayWriting;
...@@ -1925,14 +2100,14 @@ _XGetMiscCode( ...@@ -1925,14 +2100,14 @@ _XGetMiscCode(
} }
} }
static int void
_XIDHandler( _XIDHandler(
register Display *dpy) register Display *dpy)
{ {
xXCMiscGetXIDRangeReply grep; xXCMiscGetXIDRangeReply grep;
register xXCMiscGetXIDRangeReq *greq; register xXCMiscGetXIDRangeReq *greq;
LockDisplay(dpy); if (dpy->resource_max == dpy->resource_mask + 1) {
_XGetMiscCode(dpy); _XGetMiscCode(dpy);
if (dpy->xcmisc_opcode > 0) { if (dpy->xcmisc_opcode > 0) {
GetReq(XCMiscGetXIDRange, greq); GetReq(XCMiscGetXIDRange, greq);
...@@ -1946,14 +2121,9 @@ _XIDHandler( ...@@ -1946,14 +2121,9 @@ _XIDHandler(
dpy->resource_max += grep.count - 6; dpy->resource_max += grep.count - 6;
dpy->resource_max <<= dpy->resource_shift; 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 +2136,7 @@ XID _XAllocID( ...@@ -1966,11 +2136,7 @@ XID _XAllocID(
id = dpy->resource_id << dpy->resource_shift; id = dpy->resource_id << dpy->resource_shift;
if (id >= dpy->resource_max) { if (id >= dpy->resource_max) {
if (!(dpy->flags & XlibDisplayPrivSync)) { _XSetPrivSyncFunction(dpy);
dpy->savedsynchandler = dpy->synchandler;
dpy->flags |= XlibDisplayPrivSync;
}
dpy->synchandler = _XIDHandler;
dpy->resource_max = dpy->resource_mask + 1; dpy->resource_max = dpy->resource_mask + 1;
} }
if (id <= dpy->resource_mask) { if (id <= dpy->resource_mask) {
...@@ -2026,11 +2192,7 @@ void _XAllocIDs( ...@@ -2026,11 +2192,7 @@ void _XAllocIDs(
dpy->resource_id = id; dpy->resource_id = id;
} }
if (id >= dpy->resource_max) { if (id >= dpy->resource_max) {
if (!(dpy->flags & XlibDisplayPrivSync)) { _XSetPrivSyncFunction(dpy);
dpy->savedsynchandler = dpy->synchandler;
dpy->flags |= XlibDisplayPrivSync;
}
dpy->synchandler = _XIDHandler;
dpy->resource_max = dpy->resource_mask + 1; dpy->resource_max = dpy->resource_mask + 1;
} }
} }
...@@ -2038,6 +2200,7 @@ void _XAllocIDs( ...@@ -2038,6 +2200,7 @@ void _XAllocIDs(
for (i = grep.count; i < count; i++) for (i = grep.count; i < count; i++)
ids[i] = XAllocID(dpy); ids[i] = XAllocID(dpy);
} }
#endif /* !USE_XCB */
/* /*
* The hard part about this is that we only get 16 bits from a reply. * The hard part about this is that we only get 16 bits from a reply.
...@@ -2070,31 +2233,20 @@ _XSetLastRequestRead( ...@@ -2070,31 +2233,20 @@ _XSetLastRequestRead(
if (newseq < lastseq) { if (newseq < lastseq) {
newseq += 0x10000; newseq += 0x10000;
if (newseq > dpy->request) { if (newseq > dpy->request) {
#ifdef NX_TRANS_SOCKET #ifdef NX_TRANS_SOCKET
if (_NXLostSequenceFunction != NULL) if (_NXLostSequenceFunction != NULL)
{ {
(*_NXLostSequenceFunction)(dpy, newseq, dpy->request, (*_NXLostSequenceFunction)(dpy, newseq, dpy->request,
(unsigned int) rep->type); (unsigned int) rep->type);
} }
else else
#endif /* #ifdef NX_TRANS_SOCKET */
{ {
(void) fprintf (stderr, (void) fprintf (stderr,
"Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n", "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
newseq, dpy->request, newseq, dpy->request,
(unsigned int) rep->type); (unsigned int) rep->type);
} }
#else /* #ifdef NX_TRANS_SOCKET */
(void) fprintf (stderr,
"Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
newseq, dpy->request,
(unsigned int) rep->type);
#endif /* #ifdef NX_TRANS_SOCKET */
newseq -= 0x10000; newseq -= 0x10000;
} }
} }
...@@ -2103,6 +2255,7 @@ _XSetLastRequestRead( ...@@ -2103,6 +2255,7 @@ _XSetLastRequestRead(
return(newseq); return(newseq);
} }
#if !USE_XCB
/* /*
* _XReply - Wait for a reply packet and copy its contents into the * _XReply - Wait for a reply packet and copy its contents into the
* specified rep. Meanwhile we must handle error and event packets that * specified rep. Meanwhile we must handle error and event packets that
...@@ -2181,7 +2334,6 @@ _XReply ( ...@@ -2181,7 +2334,6 @@ _XReply (
#ifdef NX_TRANS_TEST #ifdef NX_TRANS_TEST
fprintf(stderr, "_XReply: Requesting a flush of the NX transport.\n"); fprintf(stderr, "_XReply: Requesting a flush of the NX transport.\n");
#endif #endif
NXTransFlush(dpy->fd); NXTransFlush(dpy->fd);
#endif #endif
...@@ -2415,6 +2567,7 @@ _XAsyncReply( ...@@ -2415,6 +2567,7 @@ _XAsyncReply(
} }
return nbuf; return nbuf;
} }
#endif /* !USE_XCB */
/* /*
* Support for internal connections, such as an IM might use. * Support for internal connections, such as an IM might use.
...@@ -2456,7 +2609,6 @@ _XRegisterInternalConnection( ...@@ -2456,7 +2609,6 @@ _XRegisterInternalConnection(
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XRegisterInternalConnection: Got called.\n"); fprintf(stderr, "_XRegisterInternalConnection: Got called.\n");
#endif #endif
new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo)); new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo));
if (!new_conni) if (!new_conni)
return 0; return 0;
...@@ -2507,7 +2659,6 @@ _XUnregisterInternalConnection( ...@@ -2507,7 +2659,6 @@ _XUnregisterInternalConnection(
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XUnregisterInternalConnection: Got called.\n"); fprintf(stderr, "_XUnregisterInternalConnection: Got called.\n");
#endif #endif
for (prev = &dpy->im_fd_info; (info_list = *prev); for (prev = &dpy->im_fd_info; (info_list = *prev);
prev = &info_list->next) { prev = &info_list->next) {
if (info_list->fd == fd) { if (info_list->fd == fd) {
...@@ -2550,7 +2701,6 @@ XInternalConnectionNumbers( ...@@ -2550,7 +2701,6 @@ XInternalConnectionNumbers(
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "XInternalConnectionNumbers: Got called.\n"); fprintf(stderr, "XInternalConnectionNumbers: Got called.\n");
#endif #endif
LockDisplay(dpy); LockDisplay(dpy);
count = 0; count = 0;
for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next)
...@@ -2572,12 +2722,12 @@ XInternalConnectionNumbers( ...@@ -2572,12 +2722,12 @@ XInternalConnectionNumbers(
return 1; return 1;
} }
static void _XProcessInternalConnection( void _XProcessInternalConnection(
Display *dpy, Display *dpy,
struct _XConnectionInfo *conn_info) struct _XConnectionInfo *conn_info)
{ {
dpy->flags |= XlibDisplayProcConni; dpy->flags |= XlibDisplayProcConni;
#ifdef XTHREADS #if defined(XTHREADS) && !USE_XCB
if (dpy->lock) { if (dpy->lock) {
/* check cache to avoid call to thread_self */ /* check cache to avoid call to thread_self */
if (xthread_have_id(dpy->lock->reading_thread)) if (xthread_have_id(dpy->lock->reading_thread))
...@@ -2585,14 +2735,14 @@ static void _XProcessInternalConnection( ...@@ -2585,14 +2735,14 @@ static void _XProcessInternalConnection(
else else
dpy->lock->conni_thread = XThread_Self(); dpy->lock->conni_thread = XThread_Self();
} }
#endif /* XTHREADS */ #endif /* XTHREADS && !USE_XCB */
UnlockDisplay(dpy); UnlockDisplay(dpy);
(*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data); (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data);
LockDisplay(dpy); LockDisplay(dpy);
#ifdef XTHREADS #if defined(XTHREADS) && !USE_XCB
if (dpy->lock) if (dpy->lock)
xthread_clear_id(dpy->lock->conni_thread); xthread_clear_id(dpy->lock->conni_thread);
#endif /* XTHREADS */ #endif /* XTHREADS && !USE_XCB */
dpy->flags &= ~XlibDisplayProcConni; dpy->flags &= ~XlibDisplayProcConni;
} }
...@@ -2644,7 +2794,6 @@ XAddConnectionWatch( ...@@ -2644,7 +2794,6 @@ XAddConnectionWatch(
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "XAddConnectionWatch: Got called.\n"); fprintf(stderr, "XAddConnectionWatch: Got called.\n");
#endif #endif
LockDisplay(dpy); LockDisplay(dpy);
/* allocate new watch data */ /* allocate new watch data */
...@@ -2704,7 +2853,6 @@ XRemoveConnectionWatch( ...@@ -2704,7 +2853,6 @@ XRemoveConnectionWatch(
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "XRemoveConnectionWatch: Got called.\n"); fprintf(stderr, "XRemoveConnectionWatch: Got called.\n");
#endif #endif
LockDisplay(dpy); LockDisplay(dpy);
for (watch=dpy->conn_watchers; watch; watch=watch->next) { for (watch=dpy->conn_watchers; watch; watch=watch->next) {
if (watch->fn == callback && watch->client_data == client_data) { if (watch->fn == callback && watch->client_data == client_data) {
...@@ -2733,6 +2881,7 @@ XRemoveConnectionWatch( ...@@ -2733,6 +2881,7 @@ XRemoveConnectionWatch(
/* end of internal connections support */ /* end of internal connections support */
#if !USE_XCB
/* Read and discard "n" 8-bit bytes of data */ /* Read and discard "n" 8-bit bytes of data */
void _XEatData( void _XEatData(
...@@ -2777,6 +2926,129 @@ void _XEatDataWords(Display *dpy, unsigned long n) ...@@ -2777,6 +2926,129 @@ void _XEatDataWords(Display *dpy, unsigned long n)
#endif #endif
_XEatData (dpy, n << 2); _XEatData (dpy, n << 2);
} }
#endif /* !USE_XCB */
/* 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.
*/
#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)
{
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);
}
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,6 +3061,7 @@ void _XEnq( ...@@ -2789,6 +3061,7 @@ void _XEnq(
register xEvent *event) register xEvent *event)
{ {
register _XQEvent *qelt; register _XQEvent *qelt;
int type, extension;
if ((qelt = dpy->qfree)) { if ((qelt = dpy->qfree)) {
/* If dpy->qfree is non-NULL do this, else malloc a new one. */ /* If dpy->qfree is non-NULL do this, else malloc a new one. */
...@@ -2807,8 +3080,29 @@ void _XEnq( ...@@ -2807,8 +3080,29 @@ void _XEnq(
#endif #endif
} }
qelt->next = NULL; 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++; qelt->qserial_num = dpy->next_event_serial_num++;
if (dpy->tail) dpy->tail->next = qelt; if (dpy->tail) dpy->tail->next = qelt;
else dpy->head = qelt; else dpy->head = qelt;
...@@ -2842,6 +3136,13 @@ void _XDeq( ...@@ -2842,6 +3136,13 @@ void _XDeq(
qelt->next = dpy->qfree; qelt->next = dpy->qfree;
dpy->qfree = qelt; dpy->qfree = qelt;
dpy->qlen--; 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;
}
} }
/* /*
...@@ -2863,6 +3164,34 @@ _XUnknownWireEvent( ...@@ -2863,6 +3164,34 @@ _XUnknownWireEvent(
return(False); 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*/ /*ARGSUSED*/
Status Status
_XUnknownNativeEvent( _XUnknownNativeEvent(
...@@ -3299,7 +3628,6 @@ int _XDefaultIOError( ...@@ -3299,7 +3628,6 @@ int _XDefaultIOError(
#else #else
exit(1); exit(1);
#endif /* #ifdef NX_TRANS_SOCKET */ #endif /* #ifdef NX_TRANS_SOCKET */
return(0); /* dummy - function should never return */ return(0); /* dummy - function should never return */
} }
...@@ -3312,7 +3640,7 @@ static int _XPrintDefaultError( ...@@ -3312,7 +3640,7 @@ static int _XPrintDefaultError(
char buffer[BUFSIZ]; char buffer[BUFSIZ];
char mesg[BUFSIZ]; char mesg[BUFSIZ];
char number[32]; char number[32];
char *mtype = "XlibMessage"; const char *mtype = "XlibMessage";
register _XExtension *ext = (_XExtension *)NULL; register _XExtension *ext = (_XExtension *)NULL;
_XExtension *bext = (_XExtension *)NULL; _XExtension *bext = (_XExtension *)NULL;
XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
...@@ -3425,10 +3753,7 @@ int _XDefaultError( ...@@ -3425,10 +3753,7 @@ int _XDefaultError(
} }
/*ARGSUSED*/ /*ARGSUSED*/
Bool _XDefaultWireError(display, he, we) Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we)
Display *display;
XErrorEvent *he;
xError *we;
{ {
return True; return True;
} }
...@@ -3467,17 +3792,17 @@ int _XError ( ...@@ -3467,17 +3792,17 @@ int _XError (
return 0; return 0;
if (_XErrorFunction != NULL) { if (_XErrorFunction != NULL) {
int rtn_val; int rtn_val;
#ifdef XTHREADS #if defined(XTHREADS) && !USE_XCB
if (dpy->lock) if (dpy->lock)
(*dpy->lock->user_lock_display)(dpy); (*dpy->lock->user_lock_display)(dpy);
UnlockDisplay(dpy); UnlockDisplay(dpy);
#endif /* XTHREADS */ #endif /* XTHREADS && !USE_XCB */
rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */
#ifdef XTHREADS #if defined(XTHREADS) && !USE_XCB
LockDisplay(dpy); LockDisplay(dpy);
if (dpy->lock) if (dpy->lock)
(*dpy->lock->user_unlock_display)(dpy); (*dpy->lock->user_unlock_display)(dpy);
#endif /* XTHREADS */ #endif /* XTHREADS && !USE_XCB */
return rtn_val; return rtn_val;
} else { } else {
return _XDefaultError(dpy, (XErrorEvent *)&event); return _XDefaultError(dpy, (XErrorEvent *)&event);
...@@ -3496,6 +3821,16 @@ _XIOError ( ...@@ -3496,6 +3821,16 @@ _XIOError (
errno = WSAGetLastError(); errno = WSAGetLastError();
#endif #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) if (_XIOErrorFunction != NULL)
(*_XIOErrorFunction)(dpy); (*_XIOErrorFunction)(dpy);
else else
...@@ -3687,6 +4022,123 @@ _XData32( ...@@ -3687,6 +4022,123 @@ _XData32(
} }
#endif /* LONG64 */ #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<nwords;i++){
if (bits == 48) *lpack = 0;
*lpack ^= (*lp & mask16) << bits;
bits -= 16 ;
lp++;
if(bits < 0){
lpack++;
bits = 48;
}
}
Data(dpy, packbuffer, len);
}
_XData16 (
Display *dpy,
short *data,
unsigned len)
{
char packbuffer[PACKBUFFERSIZE];
unsigned nunits = PACKBUFFERSIZE >> 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<nwords;i++){
if (bits == 32) *lpack = 0;
*lpack ^= (*lp & mask32) << bits;
bits = bits ^32;
lp++;
if(bits)
lpack++;
}
Data(dpy, packbuffer, len);
}
void _XData32(
Display *dpy,
long *data,
unsigned len)
{
char packbuffer[PACKBUFFERSIZE];
unsigned nunits = PACKBUFFERSIZE >> 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. /* 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. * Otherwise, Xau will not be able to find your cookies in the Xauthority file.
...@@ -3696,9 +4148,13 @@ _XData32( ...@@ -3696,9 +4148,13 @@ _XData32(
* and so, you may be better off using gethostname (if it exists). * 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 #define NEED_UTSNAME
#include <sys/utsname.h> #include <sys/utsname.h>
#else
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#endif #endif
/* /*
...@@ -3738,9 +4194,7 @@ int _XGetHostname ( ...@@ -3738,9 +4194,7 @@ int _XGetHostname (
* _XScreenOfWindow - get the Screen of a given window * _XScreenOfWindow - get the Screen of a given window
*/ */
Screen *_XScreenOfWindow (dpy, w) Screen *_XScreenOfWindow(Display *dpy, Window w)
Display *dpy;
Window w;
{ {
register int i; register int i;
Window root; Window root;
...@@ -3749,7 +4203,7 @@ Screen *_XScreenOfWindow (dpy, w) ...@@ -3749,7 +4203,7 @@ Screen *_XScreenOfWindow (dpy, w)
if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height, if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height,
&bw, &depth) == False) { &bw, &depth) == False) {
return None; return NULL;
} }
for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */ for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */
if (root == RootWindow (dpy, i)) { if (root == RootWindow (dpy, i)) {
...@@ -3912,6 +4366,26 @@ int _XOpenFile(path, flags) ...@@ -3912,6 +4366,26 @@ int _XOpenFile(path, flags)
return ret; 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) void* _XFopenFile(path, mode)
_Xconst char* path; _Xconst char* path;
_Xconst char* mode; _Xconst char* mode;
......
...@@ -139,7 +139,7 @@ struct _XDisplay ...@@ -139,7 +139,7 @@ struct _XDisplay
int nscreens; /* number of screens on this server*/ int nscreens; /* number of screens on this server*/
Screen *screens; /* pointer to list of screens */ Screen *screens; /* pointer to list of screens */
unsigned long motion_buffer; /* size of motion buffer */ 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 min_keycode; /* minimum defined keycode */
int max_keycode; /* maximum defined keycode */ int max_keycode; /* maximum defined keycode */
KeySym *keysyms; /* This server's keysyms */ KeySym *keysyms; /* This server's keysyms */
...@@ -215,10 +215,32 @@ struct _XDisplay ...@@ -215,10 +215,32 @@ struct _XDisplay
int xcmisc_opcode; /* major opcode for XC-MISC */ int xcmisc_opcode; /* major opcode for XC-MISC */
struct _XkbInfoRec *xkb_info; /* XKB info */ struct _XkbInfoRec *xkb_info; /* XKB info */
struct _XtransConnInfo *trans_conn; /* transport connection object */ 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 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_ #ifndef _XEVENT_
/* /*
* _QEvent datatype for use in input queueing. * _QEvent datatype for use in input queueing.
...@@ -231,9 +253,6 @@ typedef struct _XSQEvent ...@@ -231,9 +253,6 @@ typedef struct _XSQEvent
} _XQEvent; } _XQEvent;
#endif #endif
#ifdef XTHREADS /* for xReply */
#endif
#include <nx-X11/Xproto.h> #include <nx-X11/Xproto.h>
#ifdef __sgi #ifdef __sgi
#define _SGI_MP_SOURCE /* turn this on to get MP safe errno */ #define _SGI_MP_SOURCE /* turn this on to get MP safe errno */
...@@ -420,21 +439,26 @@ extern LockInfoPtr _Xglobal_lock; ...@@ -420,21 +439,26 @@ extern LockInfoPtr _Xglobal_lock;
* X Protocol packetizing macros. * 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 #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 * GetReq - Get the next available X request packet in the buffer and
...@@ -447,10 +471,25 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); ...@@ -447,10 +471,25 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len);
#if !defined(UNIXCPP) || defined(ANSICPP) #if !defined(UNIXCPP) || defined(ANSICPP)
#define GetReq(name, req) \ #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 */ #else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
#define GetReq(name, req) \ #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 #endif
/* GetReqExtra is the same as GetReq, but allocates "n" additional /* GetReqExtra is the same as GetReq, but allocates "n" additional
...@@ -458,10 +497,24 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); ...@@ -458,10 +497,24 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len);
#if !defined(UNIXCPP) || defined(ANSICPP) #if !defined(UNIXCPP) || defined(ANSICPP)
#define GetReqExtra(name, n, req) \ #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 #else
#define GetReqExtra(name, n, req) \ #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 #endif
...@@ -473,6 +526,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); ...@@ -473,6 +526,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len);
#if !defined(UNIXCPP) || defined(ANSICPP) #if !defined(UNIXCPP) || defined(ANSICPP)
#define GetResReq(name, rid, req) \ #define GetResReq(name, rid, req) \
WORD64ALIGN\
if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\ if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\
_XFlush(dpy);\ _XFlush(dpy);\
req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\ req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\
...@@ -483,6 +537,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); ...@@ -483,6 +537,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len);
dpy->request++ dpy->request++
#else #else
#define GetResReq(name, rid, req) \ #define GetResReq(name, rid, req) \
WORD64ALIGN\
if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\ if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\
_XFlush(dpy);\ _XFlush(dpy);\
req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\ req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\
...@@ -499,6 +554,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); ...@@ -499,6 +554,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len);
*/ */
#if !defined(UNIXCPP) || defined(ANSICPP) #if !defined(UNIXCPP) || defined(ANSICPP)
#define GetEmptyReq(name, req) \ #define GetEmptyReq(name, req) \
WORD64ALIGN\
if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\ if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\
_XFlush(dpy);\ _XFlush(dpy);\
req = (xReq *) (dpy->last_req = dpy->bufptr);\ req = (xReq *) (dpy->last_req = dpy->bufptr);\
...@@ -508,6 +564,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); ...@@ -508,6 +564,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len);
dpy->request++ dpy->request++
#else #else
#define GetEmptyReq(name, req) \ #define GetEmptyReq(name, req) \
WORD64ALIGN\
if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\ if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\
_XFlush(dpy);\ _XFlush(dpy);\
req = (xReq *) (dpy->last_req = dpy->bufptr);\ req = (xReq *) (dpy->last_req = dpy->bufptr);\
...@@ -517,14 +574,18 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); ...@@ -517,14 +574,18 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len);
dpy->request++ dpy->request++
#endif #endif
/* #ifdef WORD64
* MakeBigReq sets the CARD16 "req->length" to 0 and inserts a new CARD32 #define MakeBigReq(req,n) \
* length, after req->length, before the data in the request. The new length { \
* includes the "n" extra 32-bit words. char _BRdat[4]; \
* unsigned long _BRlen = req->length - 1; \
* Do not use MakeBigReq if there is no data already in the request. req->length = 0; \
* req->length must already be >= 2. 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 #ifdef LONG64
#define MakeBigReq(req,n) \ #define MakeBigReq(req,n) \
{ \ { \
...@@ -532,7 +593,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); ...@@ -532,7 +593,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len);
CARD32 _BRlen = req->length - 1; \ CARD32 _BRlen = req->length - 1; \
req->length = 0; \ req->length = 0; \
_BRdat = ((CARD32 *)req)[_BRlen]; \ _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; \ ((CARD32 *)req)[1] = _BRlen + n + 2; \
Data32(dpy, &_BRdat, 4); \ Data32(dpy, &_BRdat, 4); \
} }
...@@ -543,19 +604,13 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); ...@@ -543,19 +604,13 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len);
CARD32 _BRlen = req->length - 1; \ CARD32 _BRlen = req->length - 1; \
req->length = 0; \ req->length = 0; \
_BRdat = ((CARD32 *)req)[_BRlen]; \ _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; \ ((CARD32 *)req)[1] = _BRlen + n + 2; \
Data32(dpy, &_BRdat, 4); \ Data32(dpy, &_BRdat, 4); \
} }
#endif #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) \ #define SetReqLen(req,n,badlen) \
if ((req->length + n) > (unsigned)65535) { \ if ((req->length + n) > (unsigned)65535) { \
if (dpy->bigreq_size) { \ if (dpy->bigreq_size) { \
...@@ -613,6 +668,10 @@ extern void _XFlushGCCache(Display *dpy, GC gc); ...@@ -613,6 +668,10 @@ extern void _XFlushGCCache(Display *dpy, GC gc);
(void)ptr; \ (void)ptr; \
dpy->bufptr += (n); 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 Data16(dpy, data, len) Data((dpy), (char *)(data), (len))
#define _XRead16Pad(dpy, data, len) _XReadPad((dpy), (char *)(data), (len)) #define _XRead16Pad(dpy, data, len) _XReadPad((dpy), (char *)(data), (len))
#define _XRead16(dpy, data, len) _XRead((dpy), (char *)(data), (len)) #define _XRead16(dpy, data, len) _XRead((dpy), (char *)(data), (len))
...@@ -632,6 +691,7 @@ extern void _XRead32( ...@@ -632,6 +691,7 @@ extern void _XRead32(
#define Data32(dpy, data, len) Data((dpy), (char *)(data), (len)) #define Data32(dpy, data, len) Data((dpy), (char *)(data), (len))
#define _XRead32(dpy, data, len) _XRead((dpy), (char *)(data), (len)) #define _XRead32(dpy, data, len) _XRead((dpy), (char *)(data), (len))
#endif #endif
#endif /* not WORD64 */
#define PackData16(dpy,data,len) Data16 (dpy, data, len) #define PackData16(dpy,data,len) Data16 (dpy, data, len)
#define PackData32(dpy,data,len) Data32 (dpy, data, len) #define PackData32(dpy,data,len) Data32 (dpy, data, len)
...@@ -700,10 +760,20 @@ extern void _XRead32( ...@@ -700,10 +760,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 */ /* srcvar must be a variable for large architecture version */
#define OneDataCard32(dpy,dstaddr,srcvar) \ #define OneDataCard32(dpy,dstaddr,srcvar) \
{ *(CARD32 *)(dstaddr) = (srcvar); } { *(CARD32 *)(dstaddr) = (srcvar); }
#endif /* MUSTCOPY */
typedef struct _XInternalAsync { typedef struct _XInternalAsync {
struct _XInternalAsync *next; struct _XInternalAsync *next;
/* /*
...@@ -984,6 +1054,19 @@ extern Bool _XUnknownWireEvent( ...@@ -984,6 +1054,19 @@ extern Bool _XUnknownWireEvent(
XEvent* /* re */, XEvent* /* re */,
xEvent* /* event */ xEvent* /* event */
); );
extern Bool _XUnknownWireEventCookie(
Display* /* dpy */,
XGenericEventCookie* /* re */,
xEvent* /* event */
);
extern Bool _XUnknownCopyEventCookie(
Display* /* dpy */,
XGenericEventCookie* /* in */,
XGenericEventCookie* /* out */
);
extern Status _XUnknownNativeEvent( extern Status _XUnknownNativeEvent(
Display* /* dpy */, Display* /* dpy */,
XEvent* /* re */, XEvent* /* re */,
...@@ -1136,6 +1219,31 @@ extern Bool (*XESetWireToEvent( ...@@ -1136,6 +1219,31 @@ extern Bool (*XESetWireToEvent(
Display*, XEvent*, xEvent* 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( extern Status (*XESetEventToWire(
Display* /* display */, Display* /* display */,
int /* event_number */, int /* event_number */,
...@@ -1194,6 +1302,11 @@ extern void _XUnregisterInternalConnection( ...@@ -1194,6 +1302,11 @@ extern void _XUnregisterInternalConnection(
int /* fd */ int /* fd */
); );
extern void _XProcessInternalConnection(
Display* /* dpy */,
struct _XConnectionInfo* /* conn_info */
);
/* Display structure has pointers to these */ /* Display structure has pointers to these */
struct _XConnectionInfo { /* info from _XRegisterInternalConnection */ struct _XConnectionInfo { /* info from _XRegisterInternalConnection */
...@@ -1235,6 +1348,12 @@ extern int _XOpenFile( ...@@ -1235,6 +1348,12 @@ extern int _XOpenFile(
int /* flags */ int /* flags */
); );
extern int _XOpenFileMode(
_Xconst char* /* path */,
int /* flags */,
mode_t /* mode */
);
extern void* _XFopenFile( extern void* _XFopenFile(
_Xconst char* /* path */, _Xconst char* /* path */,
_Xconst char* /* mode */ _Xconst char* /* mode */
...@@ -1245,6 +1364,7 @@ extern int _XAccessFile( ...@@ -1245,6 +1364,7 @@ extern int _XAccessFile(
); );
#else #else
#define _XOpenFile(path,flags) open(path,flags) #define _XOpenFile(path,flags) open(path,flags)
#define _XOpenFileMode(path,flags,mode) open(path,flags,mode)
#define _XFopenFile(path,mode) fopen(path,mode) #define _XFopenFile(path,mode) fopen(path,mode)
#endif #endif
...@@ -1288,6 +1408,33 @@ int _XPutBackEvent ( ...@@ -1288,6 +1408,33 @@ int _XPutBackEvent (
register Display *dpy, register Display *dpy,
register XEvent *event); 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 _XFUNCPROTOEND
#endif /* _XLIBINT_H_ */ #endif /* _XLIBINT_H_ */
/* 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 */
...@@ -32,11 +32,7 @@ ...@@ -32,11 +32,7 @@
#include "Xlibint.h" #include "Xlibint.h"
#include "XlcPubI.h" #include "XlcPubI.h"
#include <nx-X11/Xos.h> #include <nx-X11/Xos.h>
#if 0 #include <unistd.h>
#include <unistd.h> /* in theory delivers getresuid/gid prototypes,
* in practice only the Linux syscall wrapper is there. */
#endif
/************************************************************************/ /************************************************************************/
...@@ -221,7 +217,7 @@ _XlcParsePath( ...@@ -221,7 +217,7 @@ _XlcParsePath(
#define XLOCALEDIR "/usr/lib/X11/locale" #define XLOCALEDIR "/usr/lib/X11/locale"
#endif #endif
static void void
xlocaledir( xlocaledir(
char *buf, char *buf,
int buf_len) int buf_len)
...@@ -299,6 +295,84 @@ xlocaledir( ...@@ -299,6 +295,84 @@ xlocaledir(
buf[buf_len-1] = '\0'; 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 */ /* Mapping direction */
typedef enum { typedef enum {
LtoR, /* Map first field to second field */ LtoR, /* Map first field to second field */
...@@ -428,7 +502,10 @@ _XlcFileName( ...@@ -428,7 +502,10 @@ _XlcFileName(
siname = XLC_PUBLIC(lcd, siname); siname = XLC_PUBLIC(lcd, siname);
if (category)
lowercase(cat, category); lowercase(cat, category);
else
cat[0] = '\0';
xlocaledir(dir,XLC_BUFSIZE); xlocaledir(dir,XLC_BUFSIZE);
n = _XlcParsePath(dir, args, NUM_LOCALEDIR); n = _XlcParsePath(dir, args, NUM_LOCALEDIR);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
...@@ -551,9 +628,7 @@ _XlcResolveLocaleName( ...@@ -551,9 +628,7 @@ _XlcResolveLocaleName(
/************************************************************************/ /************************************************************************/
int int
_XlcResolveI18NPath(buf, buf_len) _XlcResolveI18NPath(char *buf, int buf_len)
char *buf;
int buf_len;
{ {
if (buf != NULL) { if (buf != NULL) {
xlocaledir(buf, buf_len); xlocaledir(buf, buf_len);
...@@ -562,10 +637,7 @@ _XlcResolveI18NPath(buf, buf_len) ...@@ -562,10 +637,7 @@ _XlcResolveI18NPath(buf, buf_len)
} }
char * char *
_XlcLocaleDirName(dir_name, dir_len, lc_name) _XlcLocaleDirName(char *dir_name, size_t dir_len, char *lc_name)
char *dir_name;
size_t dir_len;
char *lc_name;
{ {
char dir[PATH_MAX], buf[PATH_MAX], *name = NULL; char dir[PATH_MAX], buf[PATH_MAX], *name = NULL;
int i, n; int i, n;
...@@ -574,6 +646,15 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name) ...@@ -574,6 +646,15 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name)
char *target_name = (char*)0; char *target_name = (char*)0;
char *target_dir = (char*)0; char *target_dir = (char*)0;
char *nlc_name = NULL; 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); xlocaledir (dir, PATH_MAX);
n = _XlcParsePath(dir, args, 256); n = _XlcParsePath(dir, args, 256);
...@@ -641,5 +722,116 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name) ...@@ -641,5 +722,116 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name)
} }
if (target_name != lc_name) if (target_name != lc_name)
Xfree(target_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);
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; return dir_name;
} }
/*
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 */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment