aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/X11/XlibInt.c
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2016-10-12 08:32:04 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2016-10-12 08:32:04 +0200
commit051d521f6e20761ba6831cecd91883da960fa931 (patch)
treeb28abba7818115d2fed80eb360a79a0f9183948e /nx-X11/lib/X11/XlibInt.c
parent6dce607bad8711dd06a5a7b69ad1930386b4123b (diff)
parentb8de7bf654929c823080b211aeac56cd213f5a32 (diff)
downloadnx-libs-051d521f6e20761ba6831cecd91883da960fa931.tar.gz
nx-libs-051d521f6e20761ba6831cecd91883da960fa931.tar.bz2
nx-libs-051d521f6e20761ba6831cecd91883da960fa931.zip
Merge branch 'uli42-pr/upgrade_libX11' into 3.6.x
Attributes GH PR #214: https://github.com/ArcticaProject/nx-libs/pull/214 Fixes ArcticaProject/nx-libs#157.
Diffstat (limited to 'nx-X11/lib/X11/XlibInt.c')
-rw-r--r--nx-X11/lib/X11/XlibInt.c644
1 files changed, 434 insertions, 210 deletions
diff --git a/nx-X11/lib/X11/XlibInt.c b/nx-X11/lib/X11/XlibInt.c
index 67483d3af..7ca1d0d01 100644
--- a/nx-X11/lib/X11/XlibInt.c
+++ b/nx-X11/lib/X11/XlibInt.c
@@ -63,9 +63,13 @@ from The Open Group.
#include <config.h>
#endif
#include "Xlibint.h"
+#include "Xprivate.h"
#include <nx-X11/Xpoll.h>
+#if !USE_XCB
#include <nx-X11/Xtrans/Xtrans.h>
#include <nx-X11/extensions/xcmiscstr.h>
+#endif /* !USE_XCB */
+#include <assert.h>
#include <stdio.h>
#ifdef WIN32
#include <direct.h>
@@ -97,6 +101,7 @@ xthread_t (*_Xthread_self_fn)(void) = NULL;
#define XThread_Self() ((*_Xthread_self_fn)())
+#if !USE_XCB
#define UnlockNextReplyReader(d) if ((d)->lock) \
(*(d)->lock->pop_reader)((d),&(d)->lock->reply_awaiters,&(d)->lock->reply_awaiters_tail)
@@ -104,24 +109,16 @@ xthread_t (*_Xthread_self_fn)(void) = NULL;
(*(d)->lock->push_reader)(d,&(d)->lock->reply_awaiters_tail) : NULL)
#define QueueEventReaderLock(d) ((d)->lock ? \
(*(d)->lock->push_reader)(d,&(d)->lock->event_awaiters_tail) : NULL)
-
-#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
-#define InternalLockDisplay(d,wskip) if ((d)->lock) \
- (*(d)->lock->internal_lock_display)(d,wskip,__FILE__,__LINE__)
-#else
-#define InternalLockDisplay(d,wskip) if ((d)->lock) \
- (*(d)->lock->internal_lock_display)(d,wskip)
-#endif
+#endif /* !USE_XCB */
#else /* XTHREADS else */
-#define UnlockNextReplyReader(d)
+#if !USE_XCB
+#define UnlockNextReplyReader(d)
#define UnlockNextEventReader(d)
-#define InternalLockDisplay(d,wskip)
+#endif /* !USE_XCB */
-#endif /* XTHREADS else */
-
-#include <nx/NX.h>
+#endif /* XTHREADS else */
#ifdef NX_TRANS_SOCKET
@@ -142,9 +139,7 @@ static struct timeval retry;
*/
#ifdef NX_TRANS_CHANGE
-
extern int _X11TransSocketCongestionChange(XtransConnInfo, int *);
-
#endif
#endif /* #ifdef NX_TRANS_SOCKET */
@@ -178,11 +173,7 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *);
#define ECHECK(err) (errno == err)
#define ESET(val)
#else
-#ifdef ISC
-#define ECHECK(err) ((errno == err) || ETEST())
-#else
#define ECHECK(err) (errno == err)
-#endif
#define ESET(val) errno = val
#endif
#endif
@@ -200,11 +191,15 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *);
#endif
#ifdef __UNIXOS2__
+#if !USE_XCB
#define select(n,r,w,x,t) os2ClientSelect(n,r,w,x,t)
+#endif /* !USE_XCB */
#include <limits.h>
#define MAX_PATH _POSIX_PATH_MAX
#endif
+#if !USE_XCB
+
#define STARTITERATE(tpvar,type,start,endcond) \
for (tpvar = (type *) (start); endcond; )
#define ITERPTR(tpvar) (char *)tpvar
@@ -212,6 +207,7 @@ extern int _X11TransSocketCongestionChange(XtransConnInfo, int *);
#define INCITERPTR(tpvar,type) tpvar++
#define ENDITERATE
+
typedef union {
xReply rep;
char buf[BUFSIZE];
@@ -223,12 +219,7 @@ static char *_XAsyncReply(
char *buf,
register int *lenp,
Bool discard);
-
-static void _XProcessInternalConnection(
- Display *dpy,
- struct _XConnectionInfo *conn_info);
-
-#define SEQLIMIT (65535 - (BUFSIZE / SIZEOF(xReq)) - 10)
+#endif /* !USE_XCB */
/*
* The following routines are internal routines used by Xlib for protocol
@@ -243,11 +234,12 @@ static void _XProcessInternalConnection(
* perform any operations (directly or indirectly) on the DISPLAY.
*
* Routines declared with a return type of 'Status' return 0 on failure,
- * and non 0 on success. Routines with no declared return type don't
+ * and non 0 on success. Routines with no declared return type don't
* return anything. Whenever possible routines that create objects return
* the object they have created.
*/
+#if !USE_XCB
static xReq _dummy_request = {
0, 0, 0
};
@@ -369,16 +361,13 @@ _XWaitForWritable(
#endif
int nfound;
-#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
+#ifdef NX_TRANS_SOCKET
+#if defined(NX_TRANS_CHANGE)
int congestion;
#endif
-
-#ifdef NX_TRANS_SOCKET
-
if (_XGetIOError(dpy)) {
return;
}
-
#endif
#ifdef USE_POLL
@@ -409,7 +398,7 @@ _XWaitForWritable(
XXX - what if cv is NULL and someone else comes along after
us while we are waiting?
*/
-
+
if (!dpy->lock ||
(!dpy->lock->event_awaiters &&
(!dpy->lock->reply_awaiters ||
@@ -456,18 +445,17 @@ _XWaitForWritable(
FD_SET(dpy->fd, &w_mask);
#endif
#endif /* #ifdef NX_TRANS_SOCKET */
-
UnlockDisplay(dpy);
#ifdef USE_POLL
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XWaitForWritable: Calling poll().\n");
#endif
nfound = poll (&filedes, 1, -1);
-#else
+#else /* USE_POLL */
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XWaitForWritable: Calling select() after [%ld] ms.\n",
NXTransTime());
-#endif
+#endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) */
#ifdef NX_TRANS_SOCKET
/*
* Give a chance to the callback to detect
@@ -482,9 +470,9 @@ _XWaitForWritable(
} else {
nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL);
}
-#else
+#else /* NX_TRANS_SOCKET */
nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL);
-#endif
+#endif /* NX_TRANS_SOCKET */
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XWaitForWritable: Out of select() with [%d] after [%ld] ms.\n",
nfound, NXTransTime());
@@ -504,37 +492,36 @@ _XWaitForWritable(
fprintf(stderr, "_XWaitForWritable: Descriptor [%d] has become writable.\n\n",
dpy->fd);
}
-#endif
-#endif
+#endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) */
+#endif /* USE_POLL */
InternalLockDisplay(dpy, cv != NULL);
+#ifdef NX_TRANS_SOCKET
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
if (_NXDisplayCongestionFunction != NULL &&
_X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
(*_NXDisplayCongestionFunction)(dpy, congestion);
}
-#endif
-
-#ifdef NX_TRANS_SOCKET
+#endif /* defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE) */
if (nfound <= 0) {
- if ((nfound == -1 && !ECHECK(EINTR)) ||
+ if ((nfound == -1 && !(ECHECK(EINTR) || ETEST())) ||
(_NXDisplayErrorFunction != NULL &&
(*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
_XIOError(dpy);
return;
}
}
-#else
- if (nfound < 0 && !ECHECK(EINTR))
+#else /* NX_TRANS_SOCKET */
+ if (nfound < 0 && !(ECHECK(EINTR) || ETEST()))
_XIOError(dpy);
-#endif
+#endif /* NX_TRANS_SOCKET */
} while (nfound <= 0);
if (
#ifdef USE_POLL
filedes.revents & POLLIN
-#else
+#else /* USE_POLL */
FD_ISSET(dpy->fd, &r_mask)
-#endif
+#endif /* USE_POLL */
)
{
_XAlignedBuffer buf;
@@ -550,9 +537,9 @@ _XWaitForWritable(
return;
}
-#else
+#else /* NX_TRANS_SOCKET */
_XIOError(dpy);
-#endif
+#endif /* NX_TRANS_SOCKET */
len = pend;
/* must read at least one xEvent; if none is pending, then
@@ -563,7 +550,7 @@ _XWaitForWritable(
#endif
)
len = SIZEOF(xReply);
-
+
/* but we won't read more than the max buffer size */
if (len > BUFSIZE) len = BUFSIZE;
@@ -609,6 +596,7 @@ _XWaitForWritable(
}
}
}
+#endif /* !USE_XCB */
#define POLLFD_CACHE_SIZE 5
@@ -666,6 +654,7 @@ void _XPollfdCacheDel(
#endif
}
+#if !USE_XCB
/* returns True iff there is an event in the queue newer than serial_num */
static Bool
@@ -694,7 +683,7 @@ _XWaitForReadable(
{
int result;
int fd = dpy->fd;
- struct _XConnectionInfo *ilist;
+ struct _XConnectionInfo *ilist;
register int saved_event_serial = 0;
int in_read_events = 0;
register Bool did_proc_conni = False;
@@ -730,9 +719,9 @@ _XWaitForReadable(
} else {
filedes = (struct pollfd *)dpy->filedes;
}
-#else
+#else /* USE_POLL */
FD_ZERO(&r_mask);
-#endif
+#endif /* USE_POLL */
for (;;) {
#ifndef USE_POLL
FD_SET(fd, &r_mask);
@@ -742,7 +731,7 @@ _XWaitForReadable(
if (ilist->fd > highest_fd)
highest_fd = ilist->fd;
}
-#endif
+#endif /* USE_POLL */
UnlockDisplay(dpy);
#ifdef USE_POLL
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
@@ -751,7 +740,7 @@ _XWaitForReadable(
result = poll(filedes,
(dpy->flags & XlibDisplayProcConni) ? 1 : 1+dpy->im_fd_length,
-1);
-#else
+#else /* USE_POLL */
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XWaitForReadable: Calling select().\n");
#endif
@@ -777,10 +766,10 @@ _XWaitForReadable(
} else {
result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL);
}
-#else
+#else /* NX_TRANS_SOCKET */
result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL);
-#endif
-#endif
+#endif /* NX_TRANS_SOCKET */
+#endif /* USE_POLL */
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XWaitForReadable: Out of select with result [%d] and errno [%d].\n",
result, (result < 0 ? errno : 0));
@@ -794,7 +783,7 @@ _XWaitForReadable(
#endif
#ifdef NX_TRANS_SOCKET
if (result <= 0) {
- if ((result == -1 && !ECHECK(EINTR)) ||
+ if ((result == -1 && !(ECHECK(EINTR) || ETEST())) ||
(_NXDisplayErrorFunction != NULL &&
(*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
_XIOError(dpy);
@@ -803,7 +792,7 @@ _XWaitForReadable(
continue;
}
#else
- if (result == -1 && !ECHECK(EINTR)) _XIOError(dpy);
+ if (result == -1 && !(ECHECK(EINTR) || ETEST())) _XIOError(dpy);
if (result <= 0)
continue;
#endif
@@ -856,9 +845,32 @@ _XWaitForReadable(
#endif
return 0;
}
+#endif /* !USE_XCB */
+
+static int sync_hazard(Display *dpy)
+{
+ unsigned long span = dpy->request - dpy->last_request_read;
+ unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10);
+ return span >= 65535 - hazard - 10;
+}
static
-int _XSeqSyncFunction(
+void sync_while_locked(Display *dpy)
+{
+#ifdef XTHREADS
+ if (dpy->lock)
+ (*dpy->lock->user_lock_display)(dpy);
+#endif
+ UnlockDisplay(dpy);
+ SyncHandle();
+ InternalLockDisplay(dpy, /* don't skip user locks */ 0);
+#ifdef XTHREADS
+ if (dpy->lock)
+ (*dpy->lock->user_unlock_display)(dpy);
+#endif
+}
+
+void _XSeqSyncFunction(
register Display *dpy)
{
xGetInputFocusReply rep;
@@ -868,30 +880,62 @@ int _XSeqSyncFunction(
#ifdef NX_TRANS_DEBUG
fprintf(stderr, "_XSeqSyncFunction: Going to synchronize the display.\n");
#endif
+
if (dpy->flags & XlibDisplayIOError)
{
#ifdef NX_TRANS_DEBUG
fprintf(stderr, "_XSeqSyncFunction: Returning 0 with I/O error detected.\n");
#endif
- return 0;
+ return;
}
-#endif
-
- LockDisplay(dpy);
- if ((dpy->request - dpy->last_request_read) >= (BUFSIZE / SIZEOF(xReq))) {
+#endif /* NX_TRANS_SOCKET */
+ if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) {
GetEmptyReq(GetInputFocus, req);
(void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
- }
- /* could get XID handler while waiting for reply in MT env */
- if (dpy->synchandler == _XSeqSyncFunction) {
- dpy->synchandler = dpy->savedsynchandler;
- dpy->flags &= ~XlibDisplayPrivSync;
- }
- UnlockDisplay(dpy);
- SyncHandle();
+ sync_while_locked(dpy);
+ } else if (sync_hazard(dpy))
+ _XSetPrivSyncFunction(dpy);
+}
+
+/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */
+static int
+_XPrivSyncFunction (Display *dpy)
+{
+#if XTHREADS
+ assert(!dpy->lock_fns);
+#endif
+ assert(dpy->synchandler == _XPrivSyncFunction);
+ assert((dpy->flags & XlibDisplayPrivSync) != 0);
+ dpy->synchandler = dpy->savedsynchandler;
+ dpy->savedsynchandler = NULL;
+ dpy->flags &= ~XlibDisplayPrivSync;
+ if(dpy->synchandler)
+ dpy->synchandler(dpy);
+ _XIDHandler(dpy);
+ _XSeqSyncFunction(dpy);
return 0;
}
+void _XSetPrivSyncFunction(Display *dpy)
+{
+#ifdef XTHREADS
+ if (dpy->lock_fns)
+ return;
+#endif
+ if (!(dpy->flags & XlibDisplayPrivSync)) {
+ dpy->savedsynchandler = dpy->synchandler;
+ dpy->synchandler = _XPrivSyncFunction;
+ dpy->flags |= XlibDisplayPrivSync;
+ }
+}
+
+void _XSetSeqSyncFunction(Display *dpy)
+{
+ if (sync_hazard(dpy))
+ _XSetPrivSyncFunction (dpy);
+}
+
+#if !USE_XCB
#ifdef XTHREADS
static void _XFlushInt(
register Display *dpy,
@@ -936,7 +980,7 @@ static void _XFlushInt(
#endif
/* This fix resets the bufptr to the front of the buffer so
* additional appends to the bufptr will not corrupt memory. Since
- * the server is down, these appends are no-op's anyway but
+ * the server is down, these appends are no-op's anyway but
* callers of _XFlush() are not verifying this before they call it.
*/
if (dpy->flags & XlibDisplayIOError)
@@ -1015,7 +1059,7 @@ static void _XFlushInt(
#endif
#ifdef ESZTEST
} else if (ESZTEST()) {
- if (todo > 1)
+ if (todo > 1)
todo >>= 1;
else {
_XWaitForWritable(dpy
@@ -1046,12 +1090,7 @@ static void _XFlushInt(
#endif
}
dpy->last_req = (char *)&_dummy_request;
- if ((dpy->request - dpy->last_request_read) >= SEQLIMIT &&
- !(dpy->flags & XlibDisplayPrivSync)) {
- dpy->savedsynchandler = dpy->synchandler;
- dpy->synchandler = _XSeqSyncFunction;
- dpy->flags |= XlibDisplayPrivSync;
- }
+ _XSetSeqSyncFunction(dpy);
dpy->bufptr = dpy->buffer;
#ifdef XTHREADS
dpy->flags &= ~XlibDisplayWriting;
@@ -1192,7 +1231,7 @@ _XEventsQueued(
}
#ifdef NX_TRANS_SOCKET
if (result <= 0) {
- if ((result == -1 && !ECHECK(EINTR)) ||
+ if ((result == -1 && !(ECHECK(EINTR) || ETEST())) ||
(_NXDisplayErrorFunction != NULL &&
(*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
_XIOError(dpy);
@@ -1200,9 +1239,9 @@ _XEventsQueued(
}
}
#else
- else if (result < 0 && !ECHECK(EINTR))
- _XIOError(dpy);
+ else if (result < 0 && !(ECHECK(EINTR) || ETEST()))
#endif
+ _XIOError(dpy);
}
}
#endif /* XCONN_CHECK_FREQ */
@@ -1214,7 +1253,6 @@ _XEventsQueued(
{
UnlockNextEventReader(dpy);
}
-
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XEventsQueued: Returning [%d].\n", dpy->qlen);
#endif
@@ -1233,7 +1271,7 @@ _XEventsQueued(
#endif /* XTHREADS*/
{
read_buf = buf.buf;
-
+
if (len < SIZEOF(xReply)
#ifdef XTHREADS
|| dpy->async_handlers
@@ -1249,7 +1287,7 @@ _XEventsQueued(
#endif
(void) _XRead (dpy, read_buf, (long) len);
-
+
#ifdef NX_TRANS_SOCKET
if (_XGetIOError(dpy)) {
return(dpy->qlen);
@@ -1353,15 +1391,12 @@ void _XReadEvents(
#endif /* XTHREADS */
/* find out how much data can be read */
if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0)
-#ifdef NX_TRANS_SOCKET
{
_XIOError(dpy);
-
+#ifdef NX_TRANS_SOCKET
return;
- }
-#else
- _XIOError(dpy);
#endif
+ }
len = pend;
/* must read at least one xEvent; if none is pending, then
@@ -1462,12 +1497,22 @@ void _XReadEvents(
RESETITERPTR(rep,xReply,
_XAsyncReply (dpy, rep,
ITERPTR(rep), &len, True));
- pend = len;
+ pend = len;
} else {
if (rep->generic.type == X_Error)
_XError (dpy, (xError *) rep);
else /* must be an event packet */
- _XEnq (dpy, (xEvent *)rep);
+ {
+ if (rep->generic.type == GenericEvent)
+ {
+ int evlen;
+ evlen = (rep->generic.length << 2);
+ if (_XRead(dpy, &read_buf[len], evlen) == -2)
+ goto got_event; /* XXX: aargh! */
+ }
+
+ _XEnq (dpy, (xEvent *)rep);
+ }
INCITERPTR(rep,xReply);
len -= SIZEOF(xReply);
}
@@ -1477,7 +1522,7 @@ void _XReadEvents(
UnlockNextEventReader(dpy);
}
-/*
+/*
* _XRead - Read bytes from the socket taking into account incomplete
* reads. This routine may have to be reworked if int < long.
*/
@@ -1577,6 +1622,7 @@ int _XRead(
#endif /* XTHREADS*/
return 0;
}
+#endif /* !USE_XCB */
#ifdef LONG64
void _XRead32(
@@ -1599,6 +1645,8 @@ void _XRead32(
#endif /* LONG64 */
+
+#if !USE_XCB
/*
* _XReadPad - Read bytes from the socket taking into account incomplete
* reads. If the number of bytes is not 0 mod 4, read additional pad
@@ -1622,7 +1670,7 @@ void _XReadPad(
if ((dpy->flags & XlibDisplayIOError) || size == 0) return;
iov[0].iov_len = (int)size;
iov[0].iov_base = data;
- /*
+ /*
* The following hack is used to provide 32 bit long-word
* aligned padding. The [1] vector is of length 0, 1, 2, or 3,
* whatever is needed.
@@ -1683,7 +1731,7 @@ void _XReadPad(
_XIOError(dpy);
#endif
}
-
+
else /* bytes_read is less than 0; presumably -1 */ {
/* If it's a system call interrupt, it's not an error. */
#ifdef NX_TRANS_SOCKET
@@ -1820,7 +1868,7 @@ _XSend (
InsertIOV (dpy->buffer, dbufsize)
InsertIOV ((char *)data, size)
InsertIOV ((char *)pad, padsize)
-
+
ESET(0);
if ((len = _X11TransWritev(dpy->trans_conn, iov, i)) >= 0) {
#ifdef NX_TRANS_SOCKET
@@ -1853,7 +1901,7 @@ _XSend (
#endif
#ifdef ESZTEST
} else if (ESZTEST()) {
- if (todo > 1)
+ if (todo > 1)
todo >>= 1;
else {
_XWaitForWritable(dpy
@@ -1882,12 +1930,7 @@ _XSend (
#endif
}
dpy->last_req = (char *) & _dummy_request;
- if ((dpy->request - dpy->last_request_read) >= SEQLIMIT &&
- !(dpy->flags & XlibDisplayPrivSync)) {
- dpy->savedsynchandler = dpy->synchandler;
- dpy->synchandler = _XSeqSyncFunction;
- dpy->flags |= XlibDisplayPrivSync;
- }
+ _XSetSeqSyncFunction(dpy);
dpy->bufptr = dpy->buffer;
#ifdef XTHREADS
dpy->flags &= ~XlibDisplayWriting;
@@ -1925,35 +1968,30 @@ _XGetMiscCode(
}
}
-static int
+void
_XIDHandler(
register Display *dpy)
{
xXCMiscGetXIDRangeReply grep;
register xXCMiscGetXIDRangeReq *greq;
- LockDisplay(dpy);
- _XGetMiscCode(dpy);
- if (dpy->xcmisc_opcode > 0) {
- GetReq(XCMiscGetXIDRange, greq);
- greq->reqType = dpy->xcmisc_opcode;
- greq->miscReqType = X_XCMiscGetXIDRange;
- if (_XReply (dpy, (xReply *)&grep, 0, xTrue) && grep.count) {
- dpy->resource_id = ((grep.start_id - dpy->resource_base) >>
- dpy->resource_shift);
- dpy->resource_max = dpy->resource_id;
- if (grep.count > 5)
- dpy->resource_max += grep.count - 6;
- dpy->resource_max <<= dpy->resource_shift;
+ if (dpy->resource_max == dpy->resource_mask + 1) {
+ _XGetMiscCode(dpy);
+ if (dpy->xcmisc_opcode > 0) {
+ GetReq(XCMiscGetXIDRange, greq);
+ greq->reqType = dpy->xcmisc_opcode;
+ greq->miscReqType = X_XCMiscGetXIDRange;
+ if (_XReply (dpy, (xReply *)&grep, 0, xTrue) && grep.count) {
+ dpy->resource_id = ((grep.start_id - dpy->resource_base) >>
+ dpy->resource_shift);
+ dpy->resource_max = dpy->resource_id;
+ if (grep.count > 5)
+ dpy->resource_max += grep.count - 6;
+ dpy->resource_max <<= dpy->resource_shift;
+ }
+ sync_while_locked(dpy);
}
}
- if (dpy->flags & XlibDisplayPrivSync) {
- dpy->synchandler = dpy->savedsynchandler;
- dpy->flags &= ~XlibDisplayPrivSync;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- return 0;
}
/*
@@ -1966,11 +2004,7 @@ XID _XAllocID(
id = dpy->resource_id << dpy->resource_shift;
if (id >= dpy->resource_max) {
- if (!(dpy->flags & XlibDisplayPrivSync)) {
- dpy->savedsynchandler = dpy->synchandler;
- dpy->flags |= XlibDisplayPrivSync;
- }
- dpy->synchandler = _XIDHandler;
+ _XSetPrivSyncFunction(dpy);
dpy->resource_max = dpy->resource_mask + 1;
}
if (id <= dpy->resource_mask) {
@@ -2026,11 +2060,7 @@ void _XAllocIDs(
dpy->resource_id = id;
}
if (id >= dpy->resource_max) {
- if (!(dpy->flags & XlibDisplayPrivSync)) {
- dpy->savedsynchandler = dpy->synchandler;
- dpy->flags |= XlibDisplayPrivSync;
- }
- dpy->synchandler = _XIDHandler;
+ _XSetPrivSyncFunction(dpy);
dpy->resource_max = dpy->resource_mask + 1;
}
}
@@ -2038,6 +2068,7 @@ void _XAllocIDs(
for (i = grep.count; i < count; i++)
ids[i] = XAllocID(dpy);
}
+#endif /* !USE_XCB */
/*
* The hard part about this is that we only get 16 bits from a reply.
@@ -2070,31 +2101,20 @@ _XSetLastRequestRead(
if (newseq < lastseq) {
newseq += 0x10000;
if (newseq > dpy->request) {
-
#ifdef NX_TRANS_SOCKET
-
if (_NXLostSequenceFunction != NULL)
{
(*_NXLostSequenceFunction)(dpy, newseq, dpy->request,
(unsigned int) rep->type);
}
else
+#endif /* #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);
}
-
-#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;
}
}
@@ -2103,6 +2123,7 @@ _XSetLastRequestRead(
return(newseq);
}
+#if !USE_XCB
/*
* _XReply - Wait for a reply packet and copy its contents into the
* specified rep. Meanwhile we must handle error and event packets that
@@ -2181,7 +2202,6 @@ _XReply (
#ifdef NX_TRANS_TEST
fprintf(stderr, "_XReply: Requesting a flush of the NX transport.\n");
#endif
-
NXTransFlush(dpy->fd);
#endif
@@ -2212,9 +2232,9 @@ _XReply (
}
if (extra <= rep->generic.length) {
if (extra > 0)
- /*
+ /*
* Read the extra data into storage immediately
- * following the GenericReply structure.
+ * following the GenericReply structure.
*/
(void) _XRead (dpy, (char *) (NEXTPTR(rep,xReply)),
((long)extra) << 2);
@@ -2239,9 +2259,9 @@ _XReply (
#endif
return 1;
}
- /*
+ /*
*if we get here, then extra > rep->generic.length--meaning we
- * read a reply that's shorter than we expected. This is an
+ * read a reply that's shorter than we expected. This is an
* error, but we still need to figure out how to handle it...
*/
(void) _XRead (dpy, (char *) (NEXTPTR(rep,xReply)),
@@ -2290,12 +2310,12 @@ _XReply (
UnlockNextReplyReader(dpy);
return (0);
}
- /*
+ /*
* we better see if there is an extension who may
* want to suppress the error.
*/
for (ext = dpy->ext_procs; !ret && ext; ext = ext->next) {
- if (ext->error)
+ if (ext->error)
ret = (*ext->error)(dpy, err, &ext->codes, &ret_code);
}
if (!ret) {
@@ -2324,7 +2344,7 @@ _XReply (
}
#endif
}
-}
+}
static char *
_XAsyncReply(
@@ -2355,7 +2375,7 @@ _XAsyncReply(
*lenp = 0;
return buf;
}
-
+
for (async = dpy->async_handlers; async; async = next) {
next = async->next;
if ((consumed = (*async->handler)(dpy, rep, buf, *lenp, async->data)))
@@ -2364,7 +2384,7 @@ _XAsyncReply(
if (!consumed) {
if (!discard)
return buf;
- (void) fprintf(stderr,
+ (void) fprintf(stderr,
"Xlib: unexpected async reply (sequence 0x%lx)!\n",
dpy->last_request_read);
#ifdef XTHREADS
@@ -2415,6 +2435,7 @@ _XAsyncReply(
}
return nbuf;
}
+#endif /* !USE_XCB */
/*
* Support for internal connections, such as an IM might use.
@@ -2456,7 +2477,6 @@ _XRegisterInternalConnection(
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XRegisterInternalConnection: Got called.\n");
#endif
-
new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo));
if (!new_conni)
return 0;
@@ -2507,7 +2527,6 @@ _XUnregisterInternalConnection(
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "_XUnregisterInternalConnection: Got called.\n");
#endif
-
for (prev = &dpy->im_fd_info; (info_list = *prev);
prev = &info_list->next) {
if (info_list->fd == fd) {
@@ -2550,7 +2569,6 @@ XInternalConnectionNumbers(
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "XInternalConnectionNumbers: Got called.\n");
#endif
-
LockDisplay(dpy);
count = 0;
for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next)
@@ -2572,12 +2590,12 @@ XInternalConnectionNumbers(
return 1;
}
-static void _XProcessInternalConnection(
+void _XProcessInternalConnection(
Display *dpy,
struct _XConnectionInfo *conn_info)
{
dpy->flags |= XlibDisplayProcConni;
-#ifdef XTHREADS
+#if defined(XTHREADS) && !USE_XCB
if (dpy->lock) {
/* check cache to avoid call to thread_self */
if (xthread_have_id(dpy->lock->reading_thread))
@@ -2585,14 +2603,14 @@ static void _XProcessInternalConnection(
else
dpy->lock->conni_thread = XThread_Self();
}
-#endif /* XTHREADS */
+#endif /* XTHREADS && !USE_XCB */
UnlockDisplay(dpy);
(*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data);
LockDisplay(dpy);
-#ifdef XTHREADS
+#if defined(XTHREADS) && !USE_XCB
if (dpy->lock)
xthread_clear_id(dpy->lock->conni_thread);
-#endif /* XTHREADS */
+#endif /* XTHREADS && !USE_XCB */
dpy->flags &= ~XlibDisplayProcConni;
}
@@ -2644,7 +2662,6 @@ XAddConnectionWatch(
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "XAddConnectionWatch: Got called.\n");
#endif
-
LockDisplay(dpy);
/* allocate new watch data */
@@ -2688,7 +2705,7 @@ XAddConnectionWatch(
* Unregister a callback registered by XAddConnectionWatch.
* Both callback and client_data must match what was passed to
* XAddConnectionWatch.
- */
+ */
void
XRemoveConnectionWatch(
Display* dpy,
@@ -2704,7 +2721,6 @@ XRemoveConnectionWatch(
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
fprintf(stderr, "XRemoveConnectionWatch: Got called.\n");
#endif
-
LockDisplay(dpy);
for (watch=dpy->conn_watchers; watch; watch=watch->next) {
if (watch->fn == callback && watch->client_data == client_data) {
@@ -2733,6 +2749,7 @@ XRemoveConnectionWatch(
/* end of internal connections support */
+#if !USE_XCB
/* Read and discard "n" 8-bit bytes of data */
void _XEatData(
@@ -2766,7 +2783,7 @@ void _XEatData(
lib. This workaround had been implemented temporarily in a couple
of X libs, see e.g. https://lists.x.org/archives/xorg-devel/2013-July/036763.html.
*/
-#include <X11/Xmd.h> /* for LONG64 on 64-bit platforms */
+#include <nx-X11/Xmd.h> /* for LONG64 on 64-bit platforms */
#include <limits.h>
void _XEatDataWords(Display *dpy, unsigned long n)
@@ -2777,6 +2794,129 @@ void _XEatDataWords(Display *dpy, unsigned long n)
#endif
_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,12 +2929,13 @@ void _XEnq(
register xEvent *event)
{
register _XQEvent *qelt;
+ int type, extension;
if ((qelt = dpy->qfree)) {
/* If dpy->qfree is non-NULL do this, else malloc a new one. */
dpy->qfree = qelt->next;
}
- else if ((qelt =
+ else if ((qelt =
(_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) {
/* Malloc call failed! */
ESET(ENOMEM);
@@ -2807,12 +2948,33 @@ void _XEnq(
#endif
}
qelt->next = NULL;
- /* go call through display to find proper event reformatter */
- if ((*dpy->event_vec[event->u.u.type & 0177])(dpy, &qelt->event, event)) {
+
+ type = event->u.u.type & 0177;
+ extension = ((xGenericEvent*)event)->extension;
+ /* If an extension has registerd a generic_event_vec handler, then
+ * it can handle event cookies. Otherwise, proceed with the normal
+ * event handlers.
+ *
+ * If the generic_event_vec is called, qelt->event is a event cookie
+ * with the data pointer and the "free" pointer set. Data pointer is
+ * some memory allocated by the extension.
+ */
+ if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) {
+ XGenericEventCookie *cookie = &qelt->event.xcookie;
+ (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event);
+ cookie->cookie = ++dpy->next_cookie;
+
+ qelt->qserial_num = dpy->next_event_serial_num++;
+ if (dpy->tail) dpy->tail->next = qelt;
+ else dpy->head = qelt;
+
+ dpy->tail = qelt;
+ dpy->qlen++;
+ } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) {
qelt->qserial_num = dpy->next_event_serial_num++;
if (dpy->tail) dpy->tail->next = qelt;
else dpy->head = qelt;
-
+
dpy->tail = qelt;
dpy->qlen++;
} else {
@@ -2842,6 +3004,13 @@ void _XDeq(
qelt->next = dpy->qfree;
dpy->qfree = qelt;
dpy->qlen--;
+
+ if (_XIsEventCookie(dpy, &qelt->event)) {
+ XGenericEventCookie* cookie = &qelt->event.xcookie;
+ /* dpy->qfree is re-used, reset memory to avoid double free on
+ * _XFreeDisplayStructure */
+ cookie->data = NULL;
+ }
}
/*
@@ -2856,13 +3025,41 @@ _XUnknownWireEvent(
register xEvent *event) /* wire protocol event */
{
#ifdef notdef
- (void) fprintf(stderr,
+ (void) fprintf(stderr,
"Xlib: unhandled wire event! event number = %d, display = %x\n.",
event->u.u.type, dpy);
#endif
return(False);
}
+Bool
+_XUnknownWireEventCookie(
+ Display *dpy, /* pointer to display structure */
+ XGenericEventCookie *re, /* pointer to where event should be reformatted */
+ xEvent *event) /* wire protocol event */
+{
+#ifdef notdef
+ fprintf(stderr,
+ "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.",
+ ((xGenericEvent*)event)->extension, dpy);
+#endif
+ return(False);
+}
+
+Bool
+_XUnknownCopyEventCookie(
+ Display *dpy, /* pointer to display structure */
+ XGenericEventCookie *in, /* source */
+ XGenericEventCookie *out) /* destination */
+{
+#ifdef notdef
+ fprintf(stderr,
+ "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.",
+ in->extension, dpy);
+#endif
+ return(False);
+}
+
/*ARGSUSED*/
Status
_XUnknownNativeEvent(
@@ -2871,7 +3068,7 @@ _XUnknownNativeEvent(
register xEvent *event) /* wire protocol event */
{
#ifdef notdef
- (void) fprintf(stderr,
+ (void) fprintf(stderr,
"Xlib: unhandled native event! event number = %d, display = %x\n.",
re->type, dpy);
#endif
@@ -2892,7 +3089,7 @@ _XWireToEvent(
(xGenericReply *)event);
((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0);
((XAnyEvent *)re)->display = dpy;
-
+
/* Ignore the leading bit of the event type since it is set when a
client sends an event rather than the server. */
@@ -2961,7 +3158,7 @@ _XWireToEvent(
ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY);
ev->state = event->u.enterLeave.state;
ev->mode = event->u.enterLeave.mode;
- ev->same_screen = (event->u.enterLeave.flags &
+ ev->same_screen = (event->u.enterLeave.flags &
ELFlagSameScreen) && True;
ev->focus = (event->u.enterLeave.flags &
ELFlagFocus) && True;
@@ -3199,14 +3396,14 @@ _XWireToEvent(
case ClientMessage:
{
register int i;
- register XClientMessageEvent *ev
+ register XClientMessageEvent *ev
= (XClientMessageEvent *) re;
ev->window = event->u.clientMessage.window;
ev->format = event->u.u.detail;
switch (ev->format) {
- case 8:
+ case 8:
ev->message_type = event->u.clientMessage.u.b.type;
- for (i = 0; i < 20; i++)
+ for (i = 0; i < 20; i++)
ev->data.b[i] = event->u.clientMessage.u.b.bytes[i];
break;
case 16:
@@ -3252,7 +3449,7 @@ _XWireToEvent(
/*
- * _XDefaultIOError - Default fatal system error reporting routine. Called
+ * _XDefaultIOError - Default fatal system error reporting routine. Called
* when an X internal system error is encountered.
*/
int _XDefaultIOError(
@@ -3263,7 +3460,7 @@ int _XDefaultIOError(
"X connection to %s broken (explicit kill or server shutdown).\r\n",
DisplayString (dpy));
} else {
- (void) fprintf (stderr,
+ (void) fprintf (stderr,
"XIO: fatal IO error %d (%s) on X server \"%s\"\r\n",
#ifdef WIN32
WSAGetLastError(), strerror(WSAGetLastError()),
@@ -3271,7 +3468,7 @@ int _XDefaultIOError(
errno, strerror (errno),
#endif
DisplayString (dpy));
- (void) fprintf (stderr,
+ (void) fprintf (stderr,
" after %lu requests (%lu known processed) with %d events remaining.\r\n",
NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy),
QLength(dpy));
@@ -3299,7 +3496,6 @@ int _XDefaultIOError(
#else
exit(1);
#endif /* #ifdef NX_TRANS_SOCKET */
-
return(0); /* dummy - function should never return */
}
@@ -3312,13 +3508,13 @@ static int _XPrintDefaultError(
char buffer[BUFSIZ];
char mesg[BUFSIZ];
char number[32];
- char *mtype = "XlibMessage";
+ const char *mtype = "XlibMessage";
register _XExtension *ext = (_XExtension *)NULL;
_XExtension *bext = (_XExtension *)NULL;
XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
(void) fprintf(fp, "%s: %s\n ", mesg, buffer);
- XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
+ XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
mesg, BUFSIZ);
(void) fprintf(fp, mesg, event->request_code);
if (event->request_code < 128) {
@@ -3351,7 +3547,7 @@ static int _XPrintDefaultError(
/* kludge, try to find the extension that caused it */
buffer[0] = '\0';
for (ext = dpy->ext_procs; ext; ext = ext->next) {
- if (ext->error_string)
+ if (ext->error_string)
(*ext->error_string)(dpy, event->error_code, &ext->codes,
buffer, BUFSIZ);
if (buffer[0]) {
@@ -3362,7 +3558,7 @@ static int _XPrintDefaultError(
ext->codes.first_error < (int)event->error_code &&
(!bext || ext->codes.first_error > bext->codes.first_error))
bext = ext;
- }
+ }
if (bext)
sprintf(buffer, "%s.%d", bext->name,
event->error_code - bext->codes.first_error);
@@ -3402,7 +3598,7 @@ static int _XPrintDefaultError(
(void) fprintf(fp, mesg, event->resourceid);
fputs("\n", fp);
}
- XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
+ XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
mesg, BUFSIZ);
fputs(" ", fp);
(void) fprintf(fp, mesg, event->serial);
@@ -3425,10 +3621,7 @@ int _XDefaultError(
}
/*ARGSUSED*/
-Bool _XDefaultWireError(display, he, we)
- Display *display;
- XErrorEvent *he;
- xError *we;
+Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we)
{
return True;
}
@@ -3440,7 +3633,7 @@ int _XError (
Display *dpy,
register xError *rep)
{
- /*
+ /*
* X_Error packet encountered! We need to unpack the error before
* giving it to the user.
*/
@@ -3467,23 +3660,23 @@ int _XError (
return 0;
if (_XErrorFunction != NULL) {
int rtn_val;
-#ifdef XTHREADS
+#if defined(XTHREADS) && !USE_XCB
if (dpy->lock)
(*dpy->lock->user_lock_display)(dpy);
UnlockDisplay(dpy);
-#endif /* XTHREADS */
+#endif /* XTHREADS && !USE_XCB */
rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */
-#ifdef XTHREADS
+#if defined(XTHREADS) && !USE_XCB
LockDisplay(dpy);
if (dpy->lock)
(*dpy->lock->user_unlock_display)(dpy);
-#endif /* XTHREADS */
+#endif /* XTHREADS && !USE_XCB */
return rtn_val;
} else {
return _XDefaultError(dpy, (XErrorEvent *)&event);
}
}
-
+
/*
* _XIOError - call user connection error handler and exit
*/
@@ -3496,6 +3689,16 @@ _XIOError (
errno = WSAGetLastError();
#endif
+ /* This assumes that the thread calling exit will call any atexit handlers.
+ * If this does not hold, then an alternate solution would involve
+ * registering an atexit handler to take over the lock, which would only
+ * assume that the same thread calls all the atexit handlers. */
+#ifdef XTHREADS
+ if (dpy->lock)
+ (*dpy->lock->user_lock_display)(dpy);
+#endif
+ UnlockDisplay(dpy);
+
if (_XIOErrorFunction != NULL)
(*_XIOErrorFunction)(dpy);
else
@@ -3688,6 +3891,7 @@ _XData32(
#endif /* LONG64 */
+
/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm.
* Otherwise, Xau will not be able to find your cookies in the Xauthority file.
*
@@ -3696,9 +3900,13 @@ _XData32(
* and so, you may be better off using gethostname (if it exists).
*/
-#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(USG) || defined(SVR4)
+#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4)
#define NEED_UTSNAME
#include <sys/utsname.h>
+#else
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#endif
/*
@@ -3738,9 +3946,7 @@ int _XGetHostname (
* _XScreenOfWindow - get the Screen of a given window
*/
-Screen *_XScreenOfWindow (dpy, w)
- Display *dpy;
- Window w;
+Screen *_XScreenOfWindow(Display *dpy, Window w)
{
register int i;
Window root;
@@ -3749,7 +3955,7 @@ Screen *_XScreenOfWindow (dpy, w)
if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height,
&bw, &depth) == False) {
- return None;
+ return NULL;
}
for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */
if (root == RootWindow (dpy, i)) {
@@ -3770,8 +3976,6 @@ void *_XGetRequest(Display *dpy, CARD8 type, size_t len)
{
xReq *req;
- WORD64ALIGN
-
if (dpy->bufptr + len > dpy->bufmax)
_XFlush(dpy);
@@ -3854,7 +4058,7 @@ static int AccessFile (path, pathbuf, len_pathbuf, pathret)
return 1;
}
-#ifndef __UNIXOS2__
+#ifndef __UNIXOS2__
/* one last place to look */
drive = getenv ("HOMEDRIVE");
if (drive) {
@@ -3912,6 +4116,26 @@ int _XOpenFile(path, flags)
return ret;
}
+int _XOpenFileMode(path, flags, mode)
+ _Xconst char* path;
+ int flags;
+ mode_t mode;
+{
+ char buf[MAX_PATH];
+ char* bufp = NULL;
+ int ret = -1;
+ UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
+
+ if (AccessFile (path, buf, MAX_PATH, &bufp))
+ ret = open (bufp, flags, mode);
+
+ (void) SetErrorMode (olderror);
+
+ if (bufp != buf) Xfree (bufp);
+
+ return ret;
+}
+
void* _XFopenFile(path, mode)
_Xconst char* path;
_Xconst char* mode;