From: Peter Harris Date: Tue, 31 Aug 2010 22:33:36 +0000 (-0400) Subject: Merge branch 'master' of git://github.com/topcat/xcb-win32 X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=20da10490f8dac75ec9fe1df28cb9e862e171be5;hp=2dcf8b025be88a25d4333abdc28d425b88238d96;p=free-sw%2Fxcb%2Flibxcb Merge branch 'master' of git://github.com/topcat/xcb-win32 Conflicts: src/xcb_conn.c src/xcb_util.c Signed-off-by: Peter Harris --- diff --git a/NEWS b/NEWS index 0855448..7969813 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,20 @@ +Release 1.7 (2010-08-13) +======================== +- Always wake up readers after writing +- Get rid of PATH_MAX and MAXPATHLEN +- Add ~ operator support in code generator +- xcb_open: Improve protocol/host parsing +- xcb_connect_to_display_with_auth_info: Fix memory leak +- Report which extensions are being built + +Release 1.6 (2010-04-09) +======================== +- darwin: xnu doesn't support poll on ttys on the master side +- Fix descriptor leak on memory error path +- Support xcb_discard_reply +- Open the X11 socket with close-on-exec flag +- Fix authentication on hpux and Hurd + Release 1.5 (2009-12-03) ======================== - setsockopt(SO_KEEPALIVE) on TCP display connections diff --git a/configure.ac b/configure.ac index 23f4f22..4178989 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ(2.57) AC_INIT([libxcb], - 1.5, + 1.7, [xcb@lists.freedesktop.org]) AC_CONFIG_SRCDIR([xcb.pc.in]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) @@ -155,7 +155,7 @@ XCB_EXTENSION(XvMC, "yes") AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto]) if test "x$LAUNCHD" = xauto; then unset LAUNCHD - AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no]) + AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin]) fi if test "x$LAUNCHD" = xyes ; then @@ -212,6 +212,31 @@ echo " XDM support.........: ${have_xdmcp}" echo " Build unit tests....: ${HAVE_CHECK}" echo " XCB buffer size.....: ${xcb_queue_buffer_size}" echo "" +echo " X11 extensions" +echo " Composite...........: ${BUILD_COMPOSITE}" +echo " Damage..............: ${BUILD_DAMAGE}" +echo " Dpms................: ${BUILD_DPMS}" +echo " Dri2................: ${BUILD_DRI2}" +echo " Glx.................: ${BUILD_GLX}" +echo " Randr...............: ${BUILD_RANDR}" +echo " Record..............: ${BUILD_RECORD}" +echo " Render..............: ${BUILD_RENDER}" +echo " Resource............: ${BUILD_RESOURCE}" +echo " Screensaver.........: ${BUILD_SCREENSAVER}" +echo " selinux.............: ${BUILD_SELINUX}" +echo " Shape...............: ${BUILD_SHAPE}" +echo " Shm.................: ${BUILD_SHM}" +echo " Sync................: ${BUILD_SYNC}" +echo " Xevie...............: ${BUILD_XEVIE}" +echo " Xfixes..............: ${BUILD_XFIXES}" +echo " Xfree86-dri.........: ${BUILD_XFREE86_DRI}" +echo " xinerama............: ${BUILD_XINERAMA}" +echo " xinput..............: ${BUILD_XINPUT}" +echo " xprint..............: ${BUILD_XPRINT}" +echo " xtest...............: ${BUILD_XTEST}" +echo " xv..................: ${BUILD_XV}" +echo " xvmc................: ${BUILD_XVMC}" +echo "" echo " Used CFLAGS:" echo " CPPFLAGS............: ${CPPFLAGS}" echo " CFLAGS..............: ${CFLAGS}" diff --git a/doc/tutorial/index.html b/doc/tutorial/index.html index aa3ae17..adec0ac 100644 --- a/doc/tutorial/index.html +++ b/doc/tutorial/index.html @@ -1453,7 +1453,7 @@ typedef enum {

If the window has already been created, we can use the - xcb_configure_window() function to set + xcb_change_window_attributes() function to set the events that the window will receive. The subsection Configuring a window shows its prototype. As an example, here is a piece of code that @@ -1466,7 +1466,7 @@ const static uint32_t values[] = { XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTT /* The connection c and the window win are supposed to be defined */ -xcb_configure_window (c, win, XCB_CW_EVENT_MASK, values); +xcb_change_window_attributes (c, win, XCB_CW_EVENT_MASK, values);

diff --git a/src/c_client.py b/src/c_client.py index d86d05e..4f3b089 100755 --- a/src/c_client.py +++ b/src/c_client.py @@ -448,7 +448,9 @@ def _c_accessor_get_expr(expr, prefix=''): ''' lenexp = _c_accessor_get_length(expr, prefix) - if expr.op != None: + if expr.op == '~': + return '(' + '~' + _c_accessor_get_expr(expr.rhs, prefix) + ')' + elif expr.op != None: return '(' + _c_accessor_get_expr(expr.lhs, prefix) + ' ' + expr.op + ' ' + _c_accessor_get_expr(expr.rhs, prefix) + ')' elif expr.bitfield: return 'xcb_popcount(' + lenexp + ')' diff --git a/src/xcb_auth.c b/src/xcb_auth.c index 8fcfafd..1af27fc 100644 --- a/src/xcb_auth.c +++ b/src/xcb_auth.c @@ -94,8 +94,7 @@ static int authname_match(enum auth_protos kind, char *name, size_t namelen) #define SIN6_ADDR(s) (&((struct sockaddr_in6 *)s)->sin6_addr) -static Xauth *get_authptr(struct sockaddr *sockname, unsigned int socknamelen, - int display) +static Xauth *get_authptr(struct sockaddr *sockname, int display) { char *addr = 0; int addrlen = 0; @@ -248,13 +247,55 @@ static int compute_auth(xcb_auth_info_t *info, Xauth *authptr, struct sockaddr * return 0; /* Unknown authorization type */ } +/* `sockaddr_un.sun_path' typical size usually ranges between 92 and 108 */ +#define INITIAL_SOCKNAME_SLACK 108 + +/* Return a dynamically allocated socket address structure according + to the value returned by either getpeername() or getsockname() + (according to POSIX, applications should not assume a particular + length for `sockaddr_un.sun_path') */ +static struct sockaddr *get_peer_sock_name(int (*socket_func)(int, + struct sockaddr *, + socklen_t *), + int fd) +{ + socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK; + socklen_t actual_socknamelen = socknamelen; + struct sockaddr *sockname = malloc(socknamelen), *new_sockname = NULL; + + if (sockname == NULL) + return NULL; + + /* Both getpeername() and getsockname() truncates sockname if + there is not enough space and set the required length in + actual_socknamelen */ + if (socket_func(fd, sockname, &actual_socknamelen) == -1) + goto sock_or_realloc_error; + + if (actual_socknamelen > socknamelen) + { + socknamelen = actual_socknamelen; + + if ((new_sockname = realloc(sockname, actual_socknamelen)) == NULL || + socket_func(fd, new_sockname, &actual_socknamelen) == -1 || + actual_socknamelen > socknamelen) + goto sock_or_realloc_error; + + sockname = new_sockname; + } + + return sockname; + + sock_or_realloc_error: + free(sockname); + return NULL; +} + int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display) { /* code adapted from Xlib/ConnDis.c, xtrans/Xtranssocket.c, xtrans/Xtransutils.c */ - char sockbuf[sizeof(struct sockaddr) + MAXPATHLEN]; - unsigned int socknamelen = sizeof(sockbuf); /* need extra space */ - struct sockaddr *sockname = (struct sockaddr *) &sockbuf; + struct sockaddr *sockname = NULL; int gotsockname = 0; Xauth *authptr = 0; int ret = 1; @@ -263,24 +304,30 @@ int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display) * for UNIX Domain Sockets, but this is irrelevant, * since compute_auth() ignores the peer name in this * case anyway.*/ - if (getpeername(fd, sockname, &socknamelen) == -1) + if ((sockname = get_peer_sock_name(getpeername, fd)) == NULL) { + if ((sockname = get_peer_sock_name(getsockname, fd)) == NULL) + return 0; /* can only authenticate sockets */ if (sockname->sa_family != AF_UNIX) + { + free(sockname); return 0; /* except for AF_UNIX, sockets should have peernames */ - if (getsockname(fd, sockname, &socknamelen) == -1) - return 0; /* can only authenticate sockets */ + } gotsockname = 1; } - authptr = get_authptr(sockname, socknamelen, display); + authptr = get_authptr(sockname, display); if (authptr == 0) + { + free(sockname); return 0; /* cannot find good auth data */ + } info->namelen = memdup(&info->name, authptr->name, authptr->name_length); if (!info->namelen) goto no_auth; /* out of memory */ - if (!gotsockname && getsockname(fd, sockname, &socknamelen) == -1) + if (!gotsockname && (sockname = get_peer_sock_name(getsockname, fd)) == NULL) { free(info->name); goto no_auth; /* can only authenticate sockets */ @@ -293,10 +340,15 @@ int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display) goto no_auth; /* cannot build auth record */ } + free(sockname); + sockname = NULL; + XauDisposeAuth(authptr); return ret; no_auth: + free(sockname); + info->name = 0; info->namelen = 0; XauDisposeAuth(authptr); diff --git a/src/xcb_conn.c b/src/xcb_conn.c index 870c438..ebaa6e2 100644 --- a/src/xcb_conn.c +++ b/src/xcb_conn.c @@ -47,6 +47,11 @@ #include #endif /* _WIN32 */ +/* SHUT_RDWR is fairly recent and is not available on all platforms */ +#if !defined(SHUT_RDWR) +#define SHUT_RDWR 2 +#endif + typedef struct { uint8_t status; uint8_t pad0[5]; @@ -119,10 +124,7 @@ static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info) assert(count <= (int) (sizeof(parts) / sizeof(*parts))); pthread_mutex_lock(&c->iolock); - { - struct iovec *parts_ptr = parts; - ret = _xcb_out_send(c, &parts_ptr, &count); - } + ret = _xcb_out_send(c, parts, count); pthread_mutex_unlock(&c->iolock); return ret; } @@ -255,6 +257,14 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info) { xcb_connection_t* c; +#ifndef USE_POLL + if(fd >= FD_SETSIZE) /* would overflow in FD_SET */ + { + close(fd); + return (xcb_connection_t *) &error_connection; + } +#endif + c = calloc(1, sizeof(xcb_connection_t)); if(!c) { close(fd); @@ -287,6 +297,9 @@ void xcb_disconnect(xcb_connection_t *c) return; free(c->setup); + + /* disallow further sends and receives */ + shutdown(c->fd, SHUT_RDWR); close(c->fd); pthread_mutex_destroy(&c->iolock); @@ -350,15 +363,15 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec pthread_mutex_unlock(&c->iolock); do { #if USE_POLL - ret = poll(&fd, 1, -1); + ret = poll(&fd, 1, -1); #else - ret = select(c->fd + 1, &rfds, &wfds, 0, 0); + ret = select(c->fd + 1, &rfds, &wfds, 0, 0); #endif } while (ret == -1 && errno == EINTR); - if (ret < 0) + if(ret < 0) { _xcb_conn_shutdown(c); - ret = 0; + ret = 0; } pthread_mutex_lock(&c->iolock); diff --git a/src/xcb_in.c b/src/xcb_in.c index e2f9936..57d7e01 100644 --- a/src/xcb_in.c +++ b/src/xcb_in.c @@ -37,7 +37,8 @@ #include "xcbint.h" #if USE_POLL #include -#elif !defined _WIN32 +#endif +#ifndef _WIN32 #include #include #endif @@ -79,16 +80,6 @@ typedef struct reader_list { struct reader_list *next; } reader_list; -static void wake_up_next_reader(xcb_connection_t *c) -{ - int pthreadret; - if(c->in.readers) - pthreadret = pthread_cond_signal(c->in.readers->data); - else - pthreadret = pthread_cond_signal(&c->in.event_cond); - assert(pthreadret == 0); -} - static int read_packet(xcb_connection_t *c) { xcb_generic_reply_t genrep; @@ -164,9 +155,7 @@ static int read_packet(xcb_connection_t *c) /* XGE events may have sizes > 32 */ if (genrep.response_type == XCB_XGE_EVENT) - { - eventlength = ((xcb_ge_event_t*)&genrep)->length * 4; - } + eventlength = genrep.length * 4; buf = malloc(length + eventlength + (genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t))); @@ -421,7 +410,7 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_ pthread_cond_destroy(&cond); } - wake_up_next_reader(c); + _xcb_in_wake_up_next_reader(c); pthread_mutex_unlock(&c->iolock); return ret; } @@ -564,7 +553,7 @@ xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c) if(!_xcb_conn_wait(c, &c->in.event_cond, 0, 0)) break; - wake_up_next_reader(c); + _xcb_in_wake_up_next_reader(c); pthread_mutex_unlock(&c->iolock); return ret; } @@ -593,7 +582,7 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co void *reply; if(c->has_error) return 0; - if(XCB_SEQUENCE_COMPARE_32(cookie.sequence,>,c->in.request_expected) + if(XCB_SEQUENCE_COMPARE_32(cookie.sequence,>=,c->in.request_expected) && XCB_SEQUENCE_COMPARE_32(cookie.sequence,>,c->in.request_completed)) { free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), &ret)); @@ -648,6 +637,16 @@ void _xcb_in_destroy(_xcb_in *in) } } +void _xcb_in_wake_up_next_reader(xcb_connection_t *c) +{ + int pthreadret; + if(c->in.readers) + pthreadret = pthread_cond_signal(c->in.readers->data); + else + pthreadret = pthread_cond_signal(&c->in.event_cond); + assert(pthreadret == 0); +} + int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags) { pending_reply *pend = malloc(sizeof(pending_reply)); diff --git a/src/xcb_out.c b/src/xcb_out.c index b3050fe..fbce7a0 100644 --- a/src/xcb_out.c +++ b/src/xcb_out.c @@ -52,7 +52,7 @@ static int write_block(xcb_connection_t *c, struct iovec *vector, int count) vector[0].iov_base = c->out.queue; vector[0].iov_len = c->out.queue_len; c->out.queue_len = 0; - return _xcb_out_send(c, &vector, &count); + return _xcb_out_send(c, vector, count); } static void get_socket_back(xcb_connection_t *c) @@ -283,7 +283,7 @@ int xcb_writev(xcb_connection_t *c, struct iovec *vector, int count, uint64_t re return 0; pthread_mutex_lock(&c->iolock); c->out.request += requests; - ret = _xcb_out_send(c, &vector, &count); + ret = _xcb_out_send(c, vector, count); pthread_mutex_unlock(&c->iolock); return ret; } @@ -331,13 +331,14 @@ void _xcb_out_destroy(_xcb_out *out) pthread_mutex_destroy(&out->reqlenlock); } -int _xcb_out_send(xcb_connection_t *c, struct iovec **vector, int *count) +int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count) { int ret = 1; - while(ret && *count) - ret = _xcb_conn_wait(c, &c->out.cond, vector, count); + while(ret && count) + ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count); c->out.request_written = c->out.request; pthread_cond_broadcast(&c->out.cond); + _xcb_in_wake_up_next_reader(c); return ret; } @@ -348,12 +349,11 @@ int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request) return 1; if(c->out.queue_len) { - struct iovec vec, *vec_ptr = &vec; - int count = 1; + struct iovec vec; vec.iov_base = c->out.queue; vec.iov_len = c->out.queue_len; c->out.queue_len = 0; - return _xcb_out_send(c, &vec_ptr, &count); + return _xcb_out_send(c, &vec, 1); } while(c->out.writing) pthread_cond_wait(&c->out.cond, &c->iolock); diff --git a/src/xcb_util.c b/src/xcb_util.c index e08a320..0e3728a 100644 --- a/src/xcb_util.c +++ b/src/xcb_util.c @@ -27,6 +27,7 @@ #include #include +#include #ifdef DNETCONN #include #include @@ -68,11 +69,19 @@ static int _xcb_parse_display(const char *name, char **host, char **protocol, { int len, display, screen; char *slash, *colon, *dot, *end; + if(!name || !*name) name = getenv("DISPLAY"); if(!name) return 0; + +#ifdef HAVE_LAUNCHD + if(strncmp(name, "/tmp/launch", 11) == 0) + slash = NULL; + else +#endif slash = strrchr(name, '/'); + if (slash) { len = slash - name; if (protocol) { @@ -89,35 +98,43 @@ static int _xcb_parse_display(const char *name, char **host, char **protocol, colon = strrchr(name, ':'); if(!colon) - return 0; + goto error_out; len = colon - name; ++colon; display = strtoul(colon, &dot, 10); if(dot == colon) - return 0; + goto error_out; if(*dot == '\0') screen = 0; else { if(*dot != '.') - return 0; + goto error_out; ++dot; screen = strtoul(dot, &end, 10); if(end == dot || *end != '\0') - return 0; + goto error_out; } /* At this point, the display string is fully parsed and valid, but * the caller's memory is untouched. */ *host = malloc(len + 1); if(!*host) - return 0; + goto error_out; memcpy(*host, name, len); (*host)[len] = '\0'; *displayp = display; if(screenp) *screenp = screen; return 1; + +error_out: + if (protocol) { + free(*protocol); + *protocol = NULL; + } + + return 0; } int xcb_parse_display(const char *name, char **host, int *displayp, @@ -126,7 +143,7 @@ int xcb_parse_display(const char *name, char **host, int *displayp, return _xcb_parse_display(name, host, NULL, displayp, screenp); } -static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port); +static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port); #ifndef _WIN32 static int _xcb_open_unix(char *protocol, const char *file); #endif /* !WIN32 */ @@ -137,16 +154,24 @@ static int _xcb_open_decnet(const char *host, char *protocol, const unsigned sho static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen); #endif -static int _xcb_open(char *host, char *protocol, const int display) +static int _xcb_open(const char *host, char *protocol, const int display) { -#ifdef HAVE_ABSTRACT_SOCKETS int fd; + static const char unix_base[] = "/tmp/.X11-unix/X"; + const char *base = unix_base; + size_t filelen; + char *file = NULL; + int actual_filelen; + +#ifdef HAVE_LAUNCHD + if(strncmp(host, "/tmp/launch", 11) == 0) { + base = host; + host = ""; + protocol = NULL; + } #endif - static const char base[] = "/tmp/.X11-unix/X"; - char file[sizeof(base) + 20]; - int filelen; - if(*host) + if(*host || protocol) { #ifdef DNETCONN /* DECnet displays have two colons, so _xcb_parse_display will have @@ -169,19 +194,40 @@ static int _xcb_open(char *host, char *protocol, const int display) return _xcb_open_tcp(host, protocol, port); } } + #ifndef _WIN32 + filelen = strlen(base) + 1 + sizeof(display) * 3 + 1; + file = malloc(filelen); + if(file == NULL) + return -1; + /* display specifies Unix socket */ - filelen = snprintf(file, sizeof(file), "%s%d", base, display); - if(filelen < 0) +#ifdef HAVE_LAUNCHD + if(strncmp(base, "/tmp/launch", 11) == 0) + actual_filelen = snprintf(file, filelen, "%s:%d", base, display); + else +#endif + actual_filelen = snprintf(file, filelen, "%s%d", base, display); + if(actual_filelen < 0) + { + free(file); return -1; + } /* snprintf may truncate the file */ - filelen = MIN(filelen, sizeof(file) - 1); + filelen = MIN(actual_filelen, filelen - 1); #ifdef HAVE_ABSTRACT_SOCKETS fd = _xcb_open_abstract(protocol, file, filelen); if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED)) + { + free(file); return fd; + } + #endif - return _xcb_open_unix(protocol, file); + fd = _xcb_open_unix(protocol, file); + free(file); + + return fd; #endif /* !_WIN32 */ return -1; /* if control reaches here then something has gone wrong */ } @@ -244,7 +290,7 @@ static int _xcb_open_decnet(const char *host, const char *protocol, const unsign } #endif -static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port) +static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port) { int fd = -1; struct addrinfo hints; @@ -252,8 +298,15 @@ static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port) struct addrinfo *results, *addr; char *bracket; - if (protocol && strcmp("tcp",protocol)) + if (protocol && strcmp("tcp",protocol) && strcmp("inet",protocol) +#ifdef AF_INET6 + && strcmp("inet6",protocol) +#endif + ) return -1; + + if (*host == '\0') + host = "localhost"; memset(&hints, 0, sizeof(hints)); #ifdef AI_ADDRCONFIG @@ -359,31 +412,28 @@ xcb_connection_t *xcb_connect(const char *displayname, int *screenp) xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname, xcb_auth_info_t *auth, int *screenp) { int fd, display = 0; - char *host; - char *protocol; + char *host = NULL; + char *protocol = NULL; xcb_auth_info_t ourauth; xcb_connection_t *c; int parsed = _xcb_parse_display(displayname, &host, &protocol, &display, screenp); -#ifdef HAVE_LAUNCHD - if(!displayname) - displayname = getenv("DISPLAY"); - if(displayname && strlen(displayname)>11 && !strncmp(displayname, "/tmp/launch", 11)) - fd = _xcb_open_unix(NULL, displayname); - else -#endif - if(!parsed) - return (xcb_connection_t *) &error_connection; - else + if(!parsed) { + c = (xcb_connection_t *) &error_connection; + goto out; + } else fd = _xcb_open(host, protocol, display); - free(host); - if(fd == -1) - return (xcb_connection_t *) &error_connection; + if(fd == -1) { + c = (xcb_connection_t *) &error_connection; + goto out; + } - if(auth) - return xcb_connect_to_fd(fd, auth); + if(auth) { + c = xcb_connect_to_fd(fd, auth); + goto out; + } if(_xcb_get_auth_info(fd, &ourauth, display)) { @@ -394,5 +444,8 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname, else c = xcb_connect_to_fd(fd, 0); +out: + free(host); + free(protocol); return c; } diff --git a/src/xcbint.h b/src/xcbint.h index 154cca0..f07add8 100644 --- a/src/xcbint.h +++ b/src/xcbint.h @@ -106,7 +106,7 @@ typedef struct _xcb_out { int _xcb_out_init(_xcb_out *out); void _xcb_out_destroy(_xcb_out *out); -int _xcb_out_send(xcb_connection_t *c, struct iovec **vector, int *count); +int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count); int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request); @@ -137,6 +137,8 @@ typedef struct _xcb_in { int _xcb_in_init(_xcb_in *in); void _xcb_in_destroy(_xcb_in *in); +void _xcb_in_wake_up_next_reader(xcb_connection_t *c); + int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags); void _xcb_in_replies_done(xcb_connection_t *c);