Update to libxcb 1.7

This commit is contained in:
matthieu 2010-09-04 10:00:58 +00:00
parent b1cbf5b241
commit 4638a5f252
11 changed files with 190 additions and 69 deletions

9
dist/libxcb/NEWS vendored
View File

@ -1,3 +1,12 @@
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

View File

@ -3,7 +3,7 @@
AC_PREREQ(2.57)
AC_INIT([libxcb],
1.6,
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}"

View File

@ -1453,7 +1453,7 @@ typedef enum {
</pre>
<p>
If the window has already been created, we can use the
<span class="code">xcb_configure_window()</span> function to set
<span class="code">xcb_change_window_attributes()</span> function to set
the events that the window will receive. The subsection
<a href="#winconf">Configuring a window</a> 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);
</pre>
<div class="emph">
<p>

View File

@ -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 + ')'

View File

@ -89,8 +89,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;
@ -243,13 +242,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;
@ -258,24 +299,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 (getsockname(fd, sockname, &socknamelen) == -1)
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 */
}
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 */
@ -288,10 +335,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);

View File

@ -102,10 +102,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;
}
@ -313,15 +310,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);

View File

@ -69,16 +69,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;
@ -154,9 +144,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)));
@ -404,7 +392,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;
}
@ -547,7 +535,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;
}
@ -631,6 +619,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));

View File

@ -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);

View File

@ -28,6 +28,7 @@
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <limits.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
@ -63,11 +64,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) {
@ -129,7 +138,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);
static int _xcb_open_unix(char *protocol, const char *file);
#ifdef DNETCONN
static int _xcb_open_decnet(const char *host, char *protocol, const unsigned short port);
@ -138,16 +147,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;
#endif
static const char base[] = "/tmp/.X11-unix/X";
char file[sizeof(base) + 20];
int filelen;
static const char unix_base[] = "/tmp/.X11-unix/X";
const char *base = unix_base;
size_t filelen;
char *file = NULL;
int actual_filelen;
if(*host)
#ifdef HAVE_LAUNCHD
if(strncmp(host, "/tmp/launch", 11) == 0) {
base = host;
host = "";
protocol = NULL;
}
#endif
if(*host || protocol)
{
#ifdef DNETCONN
/* DECnet displays have two colons, so _xcb_parse_display will have
@ -171,19 +188,38 @@ static int _xcb_open(char *host, char *protocol, const int display)
}
}
/* display specifies Unix socket */
filelen = snprintf(file, sizeof(file), "%s%d", base, display);
if(filelen < 0)
filelen = strlen(base) + 1 + sizeof(display) * 3 + 1;
file = malloc(filelen);
if(file == NULL)
return -1;
/* display specifies Unix socket */
#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;
}
static int _xcb_socket(int family, int type, int proto)
@ -242,7 +278,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;
@ -250,8 +286,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
@ -362,13 +405,6 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname,
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) {
c = (xcb_connection_t *) &error_connection;
goto out;

View File

@ -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);

View File

@ -1,2 +1,2 @@
major=2
minor=1
minor=2