Compare commits

..

No commits in common. "master" and "libxcb-1.13" have entirely different histories.

27 changed files with 228 additions and 686 deletions

3
.gitignore vendored
View File

@ -23,6 +23,3 @@ mkinstalldirs
stamp-h1 stamp-h1
ChangeLog ChangeLog
INSTALL INSTALL
check-pc-requires.log
check-pc-requires.trs
test-suite.log

View File

@ -1,123 +0,0 @@
# vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0 filetype=yaml:
#
# This CI uses the freedesktop.org ci-templates.
# Please see the ci-templates documentation for details:
# https://freedesktop.pages.freedesktop.org/ci-templates/
.templates_sha: &template_sha b791bd48996e3ced9ca13f1c5ee82be8540b8adb # see https://docs.gitlab.com/ee/ci/yaml/#includefile
include:
# Arch container builder template
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/arch.yml'
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/ci-fairy.yml'
- template: Security/SAST.gitlab-ci.yml
stages:
- prep # prep work like rebuilding the container images if there is a change
- install xcbproto
- build # for actually building and testing things in a container
- test
- deploy
variables:
FDO_UPSTREAM_REPO: 'xorg/lib/libxcb'
# The tag should be updated each time the list of packages is updated.
# Changing a tag forces the associated image to be rebuilt.
# Note: the tag has no meaning, we use a date format purely for readability
FDO_DISTRIBUTION_TAG: '2023-08-21.0'
FDO_DISTRIBUTION_PACKAGES: 'git gcc pkgconf autoconf automake libtool make xorg-util-macros python doxygen graphviz check libxslt libxau libxdmcp'
#
# Verify that commit messages are as expected
#
check-commits:
extends:
- .fdo.ci-fairy
stage: prep
script:
- ci-fairy check-commits --junit-xml=results.xml
except:
- master@xorg/lib/libxcb
variables:
GIT_DEPTH: 100
artifacts:
reports:
junit: results.xml
#
# Verify that the merge request has the allow-collaboration checkbox ticked
#
check-merge-request:
extends:
- .fdo.ci-fairy
stage: deploy
script:
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
artifacts:
when: on_failure
reports:
junit: results.xml
allow_failure: true
#
# Build a container with the given tag and the packages pre-installed.
# This only happens if/when the tag changes, otherwise the existing image is
# re-used.
#
container-prep:
extends:
- .fdo.container-build@arch
stage: prep
variables:
GIT_STRATEGY: none
#
# Build latest xcbproto from git, instead of relying on the container
# to package a new enough version.
#
xcbproto-build:
extends:
- .fdo.distribution-image@arch
stage: install xcbproto
script:
- export INSTDIR="$PWD/_inst"
- git clone --depth=1 https://gitlab.freedesktop.org/xorg/proto/xcbproto
- pushd xcbproto > /dev/null
- mkdir _builddir
- pushd _builddir > /dev/null
- ../autogen.sh --disable-silent-rules --prefix="$INSTDIR"
- make -j${FDO_CI_CONCURRENT:-4} install
- popd > /dev/null
- popd > /dev/null
variables:
artifacts:
paths:
- _inst
#
# The default build, runs on the image built above.
#
build:
stage: build
extends:
- .fdo.distribution-image@arch
script:
- export INSTDIR="$PWD/_inst"
- export PKG_CONFIG_PATH=$(find $INSTDIR/ -name '*.pc' -printf "%h:")
- autoreconf -ivf
- mkdir _builddir
- pushd _builddir > /dev/null
- ../configure --disable-silent-rules --enable-devel-docs --with-doxygen
- make
- make check
- make distcheck
- popd > /dev/null

View File

@ -12,9 +12,6 @@ endif
if BUILD_DAMAGE if BUILD_DAMAGE
pkgconfig_DATA += xcb-damage.pc pkgconfig_DATA += xcb-damage.pc
endif endif
if BUILD_DBE
pkgconfig_DATA += xcb-dbe.pc
endif
if BUILD_DPMS if BUILD_DPMS
pkgconfig_DATA += xcb-dpms.pc pkgconfig_DATA += xcb-dpms.pc
endif endif
@ -102,7 +99,6 @@ tools/README \
tools/api_conv.pl \ tools/api_conv.pl \
tools/constants \ tools/constants \
autogen.sh \ autogen.sh \
README.md \
$(TESTS) $(TESTS)
MAINTAINERCLEANFILES = ChangeLog INSTALL MAINTAINERCLEANFILES = ChangeLog INSTALL

11
NEWS
View File

@ -1,14 +1,3 @@
Release 1.14 (2020-02-22)
=========================
* Add xcb_total_read() and xcb_total_written() API
* Support check >= 0.13 API (for make check)
* Bug fix to handle EINTR from recvmsg
* Only require pthread-stubs on non-Linux platforms
Release 1.13.1 (2018-09-27)
===========================
* Don't flag extra reply in xcb_take_socket
Release 1.13 (2018-02-28) Release 1.13 (2018-02-28)
========================= =========================
* Add support for variable-sized lists of FDs * Add support for variable-sized lists of FDs

View File

@ -2,7 +2,7 @@ About libxcb
============ ============
libxcb provides an interface to the X Window System protocol, which libxcb provides an interface to the X Window System protocol, which
replaces the traditional Xlib interface. It has several advantages over replaces the current Xlib interface. It has several advantages over
Xlib, including: Xlib, including:
- size: small, simple library, and lower memory footprint - size: small, simple library, and lower memory footprint
- latency hiding: batch several requests and wait for the replies later - latency hiding: batch several requests and wait for the replies later
@ -10,32 +10,27 @@ Xlib, including:
- proven thread support: transparently access XCB from multiple threads - proven thread support: transparently access XCB from multiple threads
- easy extension implementation: interfaces auto-generated from XML-XCB - easy extension implementation: interfaces auto-generated from XML-XCB
Xlib also uses XCB as a transport layer, allowing software to make Xlib can also use XCB as a transport layer, allowing software to make
requests and receive responses with both, which eases porting to XCB. requests and receive responses with both, which eases porting to XCB.
However, client programs, libraries, and toolkits will gain the most However, client programs, libraries, and toolkits will gain the most
benefit from a native XCB port. benefit from a native XCB port.
More information about xcb is available from our website:
https://xcb.freedesktop.org/ Please report any issues you find to the freedesktop.org bug tracker,
at:
Please report any issues you find to the freedesktop.org bug tracker at: <https://bugs.freedesktop.org/enter_bug.cgi?product=XCB>
https://gitlab.freedesktop.org/xorg/lib/libxcb/issues
Discussion about XCB occurs on the XCB mailing list: Discussion about XCB occurs on the XCB mailing list:
https://lists.freedesktop.org/mailman/listinfo/xcb <mailto:xcb at lists.freedesktop.org>
<http://lists.freedesktop.org/mailman/listinfo/xcb>
You can obtain the latest development versions of XCB using GIT from You can obtain the latest development versions of XCB using GIT.
the libxcb code repository at: For anonymous checkouts, use:
https://gitlab.freedesktop.org/xorg/lib/libxcb git clone git://anongit.freedesktop.org/git/xcb/libxcb
For anonymous checkouts, use: For developers, use:
git clone https://gitlab.freedesktop.org/xorg/lib/libxcb.git git clone git+ssh://git.freedesktop.org/git/xcb/libxcb
For developers, use:
git clone git@gitlab.freedesktop.org:xorg/lib/libxcb.git

View File

@ -1,17 +1,14 @@
#! /bin/sh #! /bin/sh
srcdir=`dirname "$0"` srcdir=`dirname $0`
test -z "$srcdir" && srcdir=. test -z "$srcdir" && srcdir=.
ORIGDIR=`pwd` ORIGDIR=`pwd`
cd "$srcdir" cd $srcdir
autoreconf -v --install || exit 1 autoreconf -v --install || exit 1
cd "$ORIGDIR" || exit $? cd $ORIGDIR || exit $?
git config --local --get format.subjectPrefix >/dev/null 2>&1 ||
git config --local format.subjectPrefix "PATCH libxcb"
if test -z "$NOCONFIGURE"; then if test -z "$NOCONFIGURE"; then
exec "$srcdir"/configure "$@" $srcdir/configure "$@"
fi fi

View File

@ -2,8 +2,8 @@ dnl Process this file with autoconf to produce a configure script.
# Initialize Autoconf # Initialize Autoconf
AC_PREREQ([2.60]) AC_PREREQ([2.60])
AC_INIT([libxcb],[1.17.0], AC_INIT([libxcb],[1.13],
[https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues], [https://bugs.freedesktop.org/enter_bug.cgi?product=xcb],
[libxcb]) [libxcb])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
@ -11,14 +11,13 @@ AC_CONFIG_SRCDIR([xcb.pc.in])
AC_CONFIG_HEADERS([src/config.h]) AC_CONFIG_HEADERS([src/config.h])
# Initialize Automake # Initialize Automake
AM_INIT_AUTOMAKE([foreign dist-xz]) AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_PATH_PYTHON([3.0]) AM_PATH_PYTHON([2.6])
# Set common system defines for POSIX extensions, such as _GNU_SOURCE # Set common system defines for POSIX extensions, such as _GNU_SOURCE
# Must be called before any macros that run the compiler (like AC_PROG_LIBTOOL) # Must be called before any macros that run the compiler (like AC_PROG_LIBTOOL)
# to avoid autoconf errors. # to avoid autoconf errors.
AC_USE_SYSTEM_EXTENSIONS AC_USE_SYSTEM_EXTENSIONS
AC_SYS_LARGEFILE
# Initialize libtool # Initialize libtool
LT_PREREQ([2.2]) LT_PREREQ([2.2])
@ -37,7 +36,7 @@ if test x"$HAVE_DOT" = xno; then
AC_MSG_WARN([dot not found - doxygen targets will be skipped]) AC_MSG_WARN([dot not found - doxygen targets will be skipped])
fi fi
PKG_CHECK_MODULES(CHECK, [check >= 0.9.6], [HAVE_CHECK=yes], [HAVE_CHECK=no]) PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=yes], [HAVE_CHECK=no])
AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes) AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes)
XSLTPROC=no XSLTPROC=no
@ -51,12 +50,8 @@ fi
AC_SUBST(HTML_CHECK_RESULT) AC_SUBST(HTML_CHECK_RESULT)
# Checks for pkg-config packages # Checks for pkg-config packages
PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.17.0) PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.13)
NEEDED="xau >= 0.99.2" NEEDED="pthread-stubs xau >= 0.99.2"
case $host_os in
linux*|darwin*|solaris*|dragonfly*|freebsd*|netbsd*) ;;
*) NEEDED="$NEEDED pthread-stubs" ;;
esac
PKG_CHECK_MODULES(NEEDED, $NEEDED) PKG_CHECK_MODULES(NEEDED, $NEEDED)
have_xdmcp="no" have_xdmcp="no"
@ -91,6 +86,7 @@ XCBPROTO_XCBPYTHONDIR=`$PKG_CONFIG --variable=pythondir xcb-proto`
AC_MSG_RESULT($XCBPROTO_XCBPYTHONDIR) AC_MSG_RESULT($XCBPROTO_XCBPYTHONDIR)
AC_SUBST(XCBPROTO_XCBPYTHONDIR) AC_SUBST(XCBPROTO_XCBPYTHONDIR)
AC_HEADER_STDC
AC_SEARCH_LIBS(getaddrinfo, socket) AC_SEARCH_LIBS(getaddrinfo, socket)
AC_SEARCH_LIBS(connect, socket) AC_SEARCH_LIBS(connect, socket)
@ -221,7 +217,6 @@ esac
XCB_EXTENSION(Composite, yes) XCB_EXTENSION(Composite, yes)
XCB_EXTENSION(Damage, yes) XCB_EXTENSION(Damage, yes)
XCB_EXTENSION(Dbe, yes)
XCB_EXTENSION(DPMS, yes) XCB_EXTENSION(DPMS, yes)
XCB_EXTENSION(DRI2, yes) XCB_EXTENSION(DRI2, yes)
XCB_EXTENSION(DRI3, $have_sendmsg) XCB_EXTENSION(DRI3, $have_sendmsg)
@ -248,6 +243,16 @@ XCB_EXTENSION(XTest, yes)
XCB_EXTENSION(Xv, yes) XCB_EXTENSION(Xv, yes)
XCB_EXTENSION(XvMC, yes) 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], [$PATH$PATH_SEPARATOR/sbin])
fi
if test "x$LAUNCHD" = xyes ; then
AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available])
fi
AC_ARG_WITH(serverside-support, AS_HELP_STRING([--with-serverside-support], [Build with support for server-side usage of xcb. This is still EXPERIMENTAL! ABI/API may change! (default: no)]), [XCB_SERVERSIDE_SUPPORT=$withval], [XCB_SERVERSIDE_SUPPORT=no]) AC_ARG_WITH(serverside-support, AS_HELP_STRING([--with-serverside-support], [Build with support for server-side usage of xcb. This is still EXPERIMENTAL! ABI/API may change! (default: no)]), [XCB_SERVERSIDE_SUPPORT=$withval], [XCB_SERVERSIDE_SUPPORT=no])
AM_CONDITIONAL(XCB_SERVERSIDE_SUPPORT, test "x$XCB_SERVERSIDE_SUPPORT" = "xyes") AM_CONDITIONAL(XCB_SERVERSIDE_SUPPORT, test "x$XCB_SERVERSIDE_SUPPORT" = "xyes")
@ -264,7 +269,6 @@ AC_CONFIG_FILES([
xcb.pc xcb.pc
xcb-composite.pc xcb-composite.pc
xcb-damage.pc xcb-damage.pc
xcb-dbe.pc
xcb-dpms.pc xcb-dpms.pc
xcb-dri2.pc xcb-dri2.pc
xcb-dri3.pc xcb-dri3.pc
@ -313,7 +317,6 @@ echo ""
echo " X11 extensions" echo " X11 extensions"
echo " Composite...........: ${BUILD_COMPOSITE}" echo " Composite...........: ${BUILD_COMPOSITE}"
echo " Damage..............: ${BUILD_DAMAGE}" echo " Damage..............: ${BUILD_DAMAGE}"
echo " Dbe.................: ${BUILD_DBE}"
echo " Dpms................: ${BUILD_DPMS}" echo " Dpms................: ${BUILD_DPMS}"
echo " Dri2................: ${BUILD_DRI2}" echo " Dri2................: ${BUILD_DRI2}"
echo " Dri3................: ${BUILD_DRI3}" echo " Dri3................: ${BUILD_DRI3}"

View File

@ -2297,7 +2297,9 @@ int main ()
values[0] = screen->white_pixel; values[0] = screen->white_pixel;
values[1] = values[1] =
XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_KEY_RELEASE |
XCB_EVENT_MASK_EXPOSURE; XCB_EVENT_MASK_BUTTON_PRESS |
XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_POINTER_MOTION;
cookie_window = xcb_create_window_checked (c, cookie_window = xcb_create_window_checked (c,
screen->root_depth, screen->root_depth,
window, screen->root, window, screen->root,

View File

@ -1,4 +0,0 @@
[wrap-git]
url = https://gitea.gigo-games.dk/frederik/libxcb.git
revision = HEAD
depth = 1

2
src/.gitignore vendored
View File

@ -1,11 +1,9 @@
bigreq.* bigreq.*
composite.* composite.*
damage.* damage.*
dbe.*
dpms.* dpms.*
dri2.* dri2.*
dri3.* dri3.*
ge.*
glx.* glx.*
present.* present.*
randr.* randr.*

View File

@ -40,14 +40,6 @@ libxcb_damage_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_damage_la_SOURCES = damage.c damage.h nodist_libxcb_damage_la_SOURCES = damage.c damage.h
endif endif
EXTSOURCES += dbe.c
if BUILD_DBE
lib_LTLIBRARIES += libxcb-dbe.la
libxcb_dbe_la_LDFLAGS = -version-info 0:0:0 -no-undefined @lt_enable_auto_import@
libxcb_dbe_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_dbe_la_SOURCES = dbe.c dbe.h
endif
EXTSOURCES += dpms.c EXTSOURCES += dpms.c
if BUILD_DPMS if BUILD_DPMS
lib_LTLIBRARIES += libxcb-dpms.la lib_LTLIBRARIES += libxcb-dpms.la
@ -67,7 +59,7 @@ endif
EXTSOURCES += dri3.c EXTSOURCES += dri3.c
if BUILD_DRI3 if BUILD_DRI3
lib_LTLIBRARIES += libxcb-dri3.la lib_LTLIBRARIES += libxcb-dri3.la
libxcb_dri3_la_LDFLAGS = -version-info 1:0:1 -no-undefined @lt_enable_auto_import@ libxcb_dri3_la_LDFLAGS = -version-info 0:0:0 -no-undefined @lt_enable_auto_import@
libxcb_dri3_la_LIBADD = $(XCB_LIBS) libxcb_dri3_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_dri3_la_SOURCES = dri3.c dri3.h nodist_libxcb_dri3_la_SOURCES = dri3.c dri3.h
endif endif

View File

@ -331,7 +331,7 @@ def c_close(self):
_h(' */') _h(' */')
# Write header file # Write header file
hfile = open('%s.h' % _ns.header, 'w', encoding='UTF-8') hfile = open('%s.h' % _ns.header, 'w')
for list in _hlines: for list in _hlines:
for line in list: for line in list:
hfile.write(line) hfile.write(line)
@ -339,7 +339,7 @@ def c_close(self):
hfile.close() hfile.close()
# Write source file # Write source file
cfile = open('%s.c' % _ns.header, 'w', encoding='UTF-8') cfile = open('%s.c' % _ns.header, 'w')
for list in _clines: for list in _clines:
for line in list: for line in list:
cfile.write(line) cfile.write(line)
@ -649,42 +649,39 @@ def _c_helper_resolve_field_names (prefix):
return all_fields return all_fields
def get_expr_field_names(expr):
"""
returns a list of field names referenced in an expression
"""
if expr.op is None or expr.op == 'calculate_len':
if expr.lenfield_name is not None:
return [expr.lenfield_name]
# constant value expr
return []
if expr.op == '~':
return get_expr_field_names(expr.rhs)
if expr.op == 'popcount':
return get_expr_field_names(expr.rhs)
if expr.op == 'sumof':
# sumof expr references another list,
# we need that list's length field here
field = None
for f in expr.lenfield_parent.fields:
if f.field_name == expr.lenfield_name:
field = f
break
if field is None:
raise Exception("list field '%s' referenced by sumof not found" % expr.lenfield_name)
# referenced list + its length field
return [expr.lenfield_name] + get_expr_field_names(field.type.expr)
if expr.op == 'enumref':
return []
return get_expr_field_names(expr.lhs) + get_expr_field_names(expr.rhs)
def get_expr_fields(self): def get_expr_fields(self):
""" """
get the Fields referenced by switch or list expression get the Fields referenced by switch or list expression
""" """
def get_expr_field_names(expr):
if expr.op is None or expr.op == 'calculate_len':
if expr.lenfield_name is not None:
return [expr.lenfield_name]
else:
# constant value expr
return []
else:
if expr.op == '~':
return get_expr_field_names(expr.rhs)
elif expr.op == 'popcount':
return get_expr_field_names(expr.rhs)
elif expr.op == 'sumof':
# sumof expr references another list,
# we need that list's length field here
field = None
for f in expr.lenfield_parent.fields:
if f.field_name == expr.lenfield_name:
field = f
break
if field is None:
raise Exception("list field '%s' referenced by sumof not found" % expr.lenfield_name)
# referenced list + its length field
return [expr.lenfield_name] + get_expr_field_names(field.type.expr)
elif expr.op == 'enumref':
return []
else:
return get_expr_field_names(expr.lhs) + get_expr_field_names(expr.rhs)
# get_expr_field_names()
# resolve the field names with the parent structure(s) # resolve the field names with the parent structure(s)
unresolved_fields_names = get_expr_field_names(self.expr) unresolved_fields_names = get_expr_field_names(self.expr)
@ -966,15 +963,18 @@ def _c_get_additional_type_params(type):
param_fields, wire_fields, params = get_serialize_params('sizeof', type) param_fields, wire_fields, params = get_serialize_params('sizeof', type)
return params[1:] return params[1:]
def _c_serialize_helper_list_field(context, self, field,
def _c_get_field_mapping_for_expr(self, expr, prefix): code_lines, temp_vars,
space, prefix):
""" """
helper function to get field mapping of a particular expression. helper function to cope with lists of variable length
""" """
expr = field.type.expr
prefix_str = _c_helper_fieldaccess_expr(prefix)
param_fields, wire_fields, params = get_serialize_params('sizeof', self) param_fields, wire_fields, params = get_serialize_params('sizeof', self)
param_names = [p[2] for p in params] param_names = [p[2] for p in params]
expr_fields_names = get_expr_field_names(expr) expr_fields_names = [f.field_name for f in get_expr_fields(field.type)]
resolved = [x for x in expr_fields_names if x in param_names] resolved = [x for x in expr_fields_names if x in param_names]
unresolved = [x for x in expr_fields_names if x not in param_names] unresolved = [x for x in expr_fields_names if x not in param_names]
@ -993,21 +993,6 @@ def _c_get_field_mapping_for_expr(self, expr, prefix):
unresolved = [x for x in unresolved if x not in field_mapping] unresolved = [x for x in unresolved if x not in field_mapping]
if len(unresolved)>0: if len(unresolved)>0:
raise Exception('could not resolve the length fields required for list %s' % field.c_field_name) raise Exception('could not resolve the length fields required for list %s' % field.c_field_name)
return field_mapping
def _c_serialize_helper_list_field(context, self, field,
code_lines, temp_vars,
space, prefix):
"""
helper function to cope with lists of variable length
"""
expr = field.type.expr
prefix_str = _c_helper_fieldaccess_expr(prefix)
field_mapping = _c_get_field_mapping_for_expr(self, field.type.expr, prefix)
if expr.op == 'calculate_len': if expr.op == 'calculate_len':
list_length = field.type.expr.lenfield_name list_length = field.type.expr.lenfield_name
else: else:
@ -1417,16 +1402,6 @@ def _c_serialize(context, self):
elif 'sizeof' == context: elif 'sizeof' == context:
param_names = [p[2] for p in params] param_names = [p[2] for p in params]
if self.length_expr is not None:
_c(' const %s *_aux = (%s *)_buffer;', self.c_type, self.c_type)
prefix = [('_aux', '->', self)]
field_mapping = _c_get_field_mapping_for_expr(self, self.length_expr, prefix)
_c(' return %s;', _c_accessor_get_expr(self.length_expr, field_mapping))
_c('}')
_c_pre.redirect_end()
return
if self.is_switch: if self.is_switch:
# switch: call _unpack() # switch: call _unpack()
_c(' %s _aux;', self.c_type) _c(' %s _aux;', self.c_type)
@ -1958,7 +1933,7 @@ def _c_accessors_list(self, field):
else: else:
# use the accessor to get the start of the list, then # use the accessor to get the start of the list, then
# compute the length of it by subtracting it from # compute the length of it by subtracting it from
# the address of the first byte after the end of the # the adress of the first byte after the end of the
# request # request
after_end_of_request = '(((char*)R) + R->length * 4)' after_end_of_request = '(((char*)R) + R->length * 4)'
start_of_list = '%s(R)' % (field.c_accessor_name) start_of_list = '%s(R)' % (field.c_accessor_name)
@ -2266,13 +2241,13 @@ def _c_request_helper(self, name, void, regular, aux=False, reply_fds=False):
elif base_func_name == 'xcb_create_window' and field.c_field_name == 'value_mask': elif base_func_name == 'xcb_create_window' and field.c_field_name == 'value_mask':
field.enum = 'CW' field.enum = 'CW'
if field.enum: if field.enum:
assert 2 <= len(self.name) <= 3 # XXX: why the 'xcb' prefix?
key = (*self.name[:-1], field.enum) key = ('xcb', field.enum)
tname = _t(key) tname = _t(key)
if namecount[tname] > 1: if namecount[tname] > 1:
tname = _t(key + ('enum',)) tname = _t(key + ('enum',))
_h(' * @param %s A bitmask of #%s values.', field.c_field_name, tname) _h(' * @param %s A bitmask of #%s values.' % (field.c_field_name, tname))
if self.doc and field.field_name in self.doc.fields: if self.doc and field.field_name in self.doc.fields:
desc = self.doc.fields[field.field_name] desc = self.doc.fields[field.field_name]
@ -2280,8 +2255,7 @@ def _c_request_helper(self, name, void, regular, aux=False, reply_fds=False):
desc = desc.replace('`%s`' % name, '\\a %s' % (name)) desc = desc.replace('`%s`' % name, '\\a %s' % (name))
desc = desc.split("\n") desc = desc.split("\n")
desc = [line if line != '' else '\\n' for line in desc] desc = [line if line != '' else '\\n' for line in desc]
_h(' * @param %s %s', field.c_field_name, "\n * ".join(desc)) _h(' * @param %s %s' % (field.c_field_name, "\n * ".join(desc)))
# If there is no documentation yet, we simply don't generate an # If there is no documentation yet, we simply don't generate an
# @param tag. Doxygen will then warn about missing documentation. # @param tag. Doxygen will then warn about missing documentation.
@ -2340,7 +2314,7 @@ def _c_request_helper(self, name, void, regular, aux=False, reply_fds=False):
for field in param_fields: for field in param_fields:
if not field.type.fixed_size() and field.wire: if not field.type.fixed_size() and field.wire:
count = count + 2 count = count + 2
if field.type.c_need_serialize or field.type.c_need_sizeof: if field.type.c_need_serialize:
# _serialize() keeps track of padding automatically # _serialize() keeps track of padding automatically
count -= 1 count -= 1
dimension = count + 2 dimension = count + 2
@ -2612,10 +2586,9 @@ def _c_reply_fds(self, name):
_h(' * @param c The connection') _h(' * @param c The connection')
_h(' * @param reply The reply') _h(' * @param reply The reply')
_h(' *') _h(' *')
_h(' * Returns a pointer to the array of reply fds of the reply.') _h(' * Returns the array of reply fds of the request asked by')
_h(' *') _h(' *')
_h(' * The returned value points into the reply and must not be free().') _h(' * The returned value must be freed by the caller using free().')
_h(' * The fds are not managed by xcb. You must close() them before freeing the reply.')
_h(' */') _h(' */')
_c('') _c('')
_hc('int *') _hc('int *')
@ -2660,14 +2633,14 @@ def _man_request(self, name, void, aux):
name = 'man/%s.%s' % (linkname, section) name = 'man/%s.%s' % (linkname, section)
if manpaths: if manpaths:
sys.stdout.write(name) sys.stdout.write(name)
f = open(name, 'w', encoding='UTF-8') f = open(name, 'w')
f.write('.so man%s/%s.%s' % (section, func_name, section)) f.write('.so man%s/%s.%s' % (section, func_name, section))
f.close() f.close()
if manpaths: if manpaths:
sys.stdout.write('man/%s.%s ' % (func_name, section)) sys.stdout.write('man/%s.%s ' % (func_name, section))
# Our CWD is src/, so this will end up in src/man/ # Our CWD is src/, so this will end up in src/man/
f = open('man/%s.%s' % (func_name, section), 'w', encoding='UTF-8') f = open('man/%s.%s' % (func_name, section), 'w')
f.write('.TH %s %s "%s" "%s" "XCB Requests"\n' % (func_name, section, center_footer, left_footer)) f.write('.TH %s %s "%s" "%s" "XCB Requests"\n' % (func_name, section, center_footer, left_footer))
# Left-adjust instead of adjusting to both sides # Left-adjust instead of adjusting to both sides
f.write('.ad l\n') f.write('.ad l\n')
@ -3035,7 +3008,7 @@ def _man_event(self, name):
if manpaths: if manpaths:
sys.stdout.write('man/%s.%s ' % (self.c_type, section)) sys.stdout.write('man/%s.%s ' % (self.c_type, section))
# Our CWD is src/, so this will end up in src/man/ # Our CWD is src/, so this will end up in src/man/
f = open('man/%s.%s' % (self.c_type, section), 'w', encoding='UTF-8') f = open('man/%s.%s' % (self.c_type, section), 'w')
f.write('.TH %s %s "%s" "%s" "XCB Events"\n' % (self.c_type, section, center_footer, left_footer)) f.write('.TH %s %s "%s" "%s" "XCB Events"\n' % (self.c_type, section, center_footer, left_footer))
# Left-adjust instead of adjusting to both sides # Left-adjust instead of adjusting to both sides
f.write('.ad l\n') f.write('.ad l\n')

View File

@ -29,7 +29,11 @@
#define __XCB_H__ #define __XCB_H__
#include <sys/types.h> #include <sys/types.h>
#if defined(__solaris__)
#include <inttypes.h>
#else
#include <stdint.h> #include <stdint.h>
#endif
#ifndef _WIN32 #ifndef _WIN32
#include <sys/uio.h> #include <sys/uio.h>
@ -47,35 +51,7 @@ extern "C" {
* @file xcb.h * @file xcb.h
*/ */
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with older compilers. */
#endif
/*
* For the below checks, we currently assume that __GNUC__ indicates
* gcc 3.0 (released 2001) or later, as we require support for C99.
*/
/* Supported in gcc 2.5 and later */
#if defined(__GNUC__) || __has_attribute(__const__)
#define XCB_CONST_FUNCTION __attribute__((__const__))
#else
#define XCB_CONST_FUNCTION XCB_PURE_FUNCTION
#endif
/* Supported in gcc 2.7 and later */
#if defined(__GNUC__) || __has_attribute(__packed__)
#define XCB_PACKED __attribute__((__packed__)) #define XCB_PACKED __attribute__((__packed__))
#else
#define XCB_PACKED
#endif
/* Supported in gcc 2.96 and later */
#if defined(__GNUC__) || __has_attribute(__pure__)
#define XCB_PURE_FUNCTION __attribute__((__pure__))
#else
#define XCB_PURE_FUNCTION
#endif
/** /**
* @defgroup XCB_Core_API XCB Core API * @defgroup XCB_Core_API XCB Core API
@ -489,7 +465,6 @@ void xcb_prefetch_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
* *
* The result must not be freed. * The result must not be freed.
*/ */
XCB_PURE_FUNCTION
const struct xcb_setup_t *xcb_get_setup(xcb_connection_t *c); const struct xcb_setup_t *xcb_get_setup(xcb_connection_t *c);
/** /**
@ -500,7 +475,6 @@ const struct xcb_setup_t *xcb_get_setup(xcb_connection_t *c);
* Accessor for the file descriptor that was passed to the * Accessor for the file descriptor that was passed to the
* xcb_connect_to_fd call that returned @p c. * xcb_connect_to_fd call that returned @p c.
*/ */
XCB_PURE_FUNCTION
int xcb_get_file_descriptor(xcb_connection_t *c); int xcb_get_file_descriptor(xcb_connection_t *c);
/** /**
@ -521,7 +495,6 @@ int xcb_get_file_descriptor(xcb_connection_t *c);
* @return XCB_CONN_CLOSED_PARSE_ERR, error during parsing display string. * @return XCB_CONN_CLOSED_PARSE_ERR, error during parsing display string.
* @return XCB_CONN_CLOSED_INVALID_SCREEN, because the server does not have a screen matching the display. * @return XCB_CONN_CLOSED_INVALID_SCREEN, because the server does not have a screen matching the display.
*/ */
XCB_PURE_FUNCTION
int xcb_connection_has_error(xcb_connection_t *c); int xcb_connection_has_error(xcb_connection_t *c);
/** /**
@ -618,7 +591,7 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *display, xcb
/** /**
* @brief Allocates an XID for a new object. * @brief Allocates an XID for a new object.
* @param c The connection. * @param c The connection.
* @return A newly allocated XID, or -1 on failure. * @return A newly allocated XID.
* *
* Allocates an XID for a new object. Typically used just prior to * Allocates an XID for a new object. Typically used just prior to
* various object creation functions, such as xcb_create_window. * various object creation functions, such as xcb_create_window.
@ -626,35 +599,6 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *display, xcb
uint32_t xcb_generate_id(xcb_connection_t *c); uint32_t xcb_generate_id(xcb_connection_t *c);
/**
* @brief Obtain number of bytes read from the connection.
* @param c The connection
* @return Number of bytes read from the server.
*
* Returns cumulative number of bytes received from the connection.
*
* This retrieves the total number of bytes read from this connection,
* to be used for diagnostic/monitoring/informative purposes.
*/
uint64_t
xcb_total_read(xcb_connection_t *c);
/**
*
* @brief Obtain number of bytes written to the connection.
* @param c The connection
* @return Number of bytes written to the server.
*
* Returns cumulative number of bytes sent to the connection.
*
* This retrieves the total number of bytes written to this connection,
* to be used for diagnostic/monitoring/informative purposes.
*/
uint64_t
xcb_total_written(xcb_connection_t *c);
/** /**
* @} * @}
*/ */

View File

@ -31,8 +31,9 @@
#include <assert.h> #include <assert.h>
#include <X11/Xauth.h> #include <X11/Xauth.h>
#include <sys/param.h>
#include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#ifdef __INTERIX #ifdef __INTERIX
/* _don't_ ask. interix has INADDR_LOOPBACK in here. */ /* _don't_ ask. interix has INADDR_LOOPBACK in here. */
@ -47,8 +48,6 @@
#endif #endif
#include "xcb_windefs.h" #include "xcb_windefs.h"
#else #else
#include <sys/param.h>
#include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -73,7 +72,7 @@ enum auth_protos {
#define AUTH_PROTO_XDM_AUTHORIZATION "XDM-AUTHORIZATION-1" #define AUTH_PROTO_XDM_AUTHORIZATION "XDM-AUTHORIZATION-1"
#define AUTH_PROTO_MIT_MAGIC_COOKIE "MIT-MAGIC-COOKIE-1" #define AUTH_PROTO_MIT_MAGIC_COOKIE "MIT-MAGIC-COOKIE-1"
static const char *authnames[N_AUTH_PROTOS] = { static char *authnames[N_AUTH_PROTOS] = {
#ifdef HASXDMAUTH #ifdef HASXDMAUTH
AUTH_PROTO_XDM_AUTHORIZATION, AUTH_PROTO_XDM_AUTHORIZATION,
#endif #endif
@ -134,7 +133,6 @@ static Xauth *get_authptr(struct sockaddr *sockname, int display)
} }
addr += 12; addr += 12;
/* if v4-mapped, fall through. */ /* if v4-mapped, fall through. */
XCB_ALLOW_FALLTHRU
#endif #endif
case AF_INET: case AF_INET:
if(!addr) if(!addr)
@ -165,7 +163,7 @@ static Xauth *get_authptr(struct sockaddr *sockname, int display)
return XauGetBestAuthByAddr (family, return XauGetBestAuthByAddr (family,
(unsigned short) addrlen, addr, (unsigned short) addrlen, addr,
(unsigned short) dispbuflen, dispbuf, (unsigned short) dispbuflen, dispbuf,
N_AUTH_PROTOS, (char **)authnames, authnameslen); N_AUTH_PROTOS, authnames, authnameslen);
} }
#ifdef HASXDMAUTH #ifdef HASXDMAUTH
@ -271,17 +269,10 @@ static int compute_auth(xcb_auth_info_t *info, Xauth *authptr, struct sockaddr *
to the value returned by either getpeername() or getsockname() to the value returned by either getpeername() or getsockname()
(according to POSIX, applications should not assume a particular (according to POSIX, applications should not assume a particular
length for `sockaddr_un.sun_path') */ length for `sockaddr_un.sun_path') */
#ifdef _WIN32
static struct sockaddr *get_peer_sock_name(int(_stdcall *socket_func)(SOCKET,
struct sockaddr *,
socklen_t *),
int fd)
#else
static struct sockaddr *get_peer_sock_name(int (*socket_func)(int, static struct sockaddr *get_peer_sock_name(int (*socket_func)(int,
struct sockaddr *, struct sockaddr *,
socklen_t *), socklen_t *),
int fd) int fd)
#endif
{ {
socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK; socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK;
socklen_t actual_socknamelen = socknamelen; socklen_t actual_socknamelen = socknamelen;

View File

@ -32,6 +32,7 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
@ -47,9 +48,7 @@
#ifdef _WIN32 #ifdef _WIN32
#include "xcb_windefs.h" #include "xcb_windefs.h"
#include <io.h>
#else #else
#include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#endif /* _WIN32 */ #endif /* _WIN32 */
@ -170,8 +169,6 @@ static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info)
static int read_setup(xcb_connection_t *c) static int read_setup(xcb_connection_t *c)
{ {
const char newline = '\n';
/* Read the server response */ /* Read the server response */
c->setup = malloc(sizeof(xcb_setup_generic_t)); c->setup = malloc(sizeof(xcb_setup_generic_t));
if(!c->setup) if(!c->setup)
@ -197,7 +194,6 @@ static int read_setup(xcb_connection_t *c)
{ {
xcb_setup_failed_t *setup = (xcb_setup_failed_t *) c->setup; xcb_setup_failed_t *setup = (xcb_setup_failed_t *) c->setup;
write(STDERR_FILENO, xcb_setup_failed_reason(setup), xcb_setup_failed_reason_length(setup)); write(STDERR_FILENO, xcb_setup_failed_reason(setup), xcb_setup_failed_reason_length(setup));
write(STDERR_FILENO, &newline, 1);
return 0; return 0;
} }
@ -205,7 +201,6 @@ static int read_setup(xcb_connection_t *c)
{ {
xcb_setup_authenticate_t *setup = (xcb_setup_authenticate_t *) c->setup; xcb_setup_authenticate_t *setup = (xcb_setup_authenticate_t *) c->setup;
write(STDERR_FILENO, xcb_setup_authenticate_reason(setup), xcb_setup_authenticate_reason_length(setup)); write(STDERR_FILENO, xcb_setup_authenticate_reason(setup), xcb_setup_authenticate_reason_length(setup));
write(STDERR_FILENO, &newline, 1);
return 0; return 0;
} }
} }
@ -216,47 +211,33 @@ static int read_setup(xcb_connection_t *c)
/* precondition: there must be something for us to write. */ /* precondition: there must be something for us to write. */
static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count) static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count)
{ {
#ifndef _WIN32
int n; int n;
#endif
assert(!c->out.queue_len); assert(!c->out.queue_len);
#ifdef _WIN32 #ifdef _WIN32
int i = 0;
int ret = 0,err = 0;
struct iovec *vec;
n = 0;
/* Could use the WSASend win32 function for scatter/gather i/o but setting up the WSABUF struct from /* Could use the WSASend win32 function for scatter/gather i/o but setting up the WSABUF struct from
an iovec would require more work and I'm not sure of the benefit....works for now */ an iovec would require more work and I'm not sure of the benefit....works for now */
while (*count) vec = *vector;
while(i < *count)
{ {
struct iovec *vec = *vector; ret = send(c->fd,vec->iov_base,vec->iov_len,0);
if (vec->iov_len) if(ret == SOCKET_ERROR)
{ {
int ret = send(c->fd, vec->iov_base, vec->iov_len, 0); err = WSAGetLastError();
if (ret == SOCKET_ERROR) if(err == WSAEWOULDBLOCK)
{ {
int err = WSAGetLastError(); return 1;
if (err == WSAEWOULDBLOCK) }
{ }
return 1; n += ret;
} *vec++;
} i++;
if (ret <= 0)
{
_xcb_conn_shutdown(c, XCB_CONN_ERROR);
return 0;
}
c->out.total_written += ret;
vec->iov_len -= ret;
vec->iov_base = (char *)vec->iov_base + ret;
}
if (vec->iov_len == 0) {
(*vector)++;
(*count)--;
}
} }
if (!*count)
*vector = 0;
#else #else
n = *count; n = *count;
if (n > IOV_MAX) if (n > IOV_MAX)
@ -298,32 +279,28 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count)
return 1; return 1;
} }
#endif /* _WIN32 */
if(n <= 0) if(n <= 0)
{ {
_xcb_conn_shutdown(c, XCB_CONN_ERROR); _xcb_conn_shutdown(c, XCB_CONN_ERROR);
return 0; return 0;
} }
c->out.total_written += n;
for(; *count; --*count, ++*vector) for(; *count; --*count, ++*vector)
{ {
int cur = (*vector)->iov_len; int cur = (*vector)->iov_len;
if(cur > n) if(cur > n)
cur = n; cur = n;
if(cur) { (*vector)->iov_len -= cur;
(*vector)->iov_len -= cur; (*vector)->iov_base = (char *) (*vector)->iov_base + cur;
(*vector)->iov_base = (char *) (*vector)->iov_base + cur; n -= cur;
n -= cur;
}
if((*vector)->iov_len) if((*vector)->iov_len)
break; break;
} }
if(!*count) if(!*count)
*vector = 0; *vector = 0;
assert(n == 0); assert(n == 0);
#endif /* _WIN32 */
return 1; return 1;
} }
@ -367,11 +344,7 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info)
c = calloc(1, sizeof(xcb_connection_t)); c = calloc(1, sizeof(xcb_connection_t));
if(!c) { if(!c) {
#ifdef _WIN32
closesocket(fd);
#else
close(fd); close(fd);
#endif
return _xcb_conn_ret_error(XCB_CONN_CLOSED_MEM_INSUFFICIENT) ; return _xcb_conn_ret_error(XCB_CONN_CLOSED_MEM_INSUFFICIENT) ;
} }
@ -404,11 +377,7 @@ void xcb_disconnect(xcb_connection_t *c)
/* disallow further sends and receives */ /* disallow further sends and receives */
shutdown(c->fd, SHUT_RDWR); shutdown(c->fd, SHUT_RDWR);
#ifdef _WIN32
closesocket(c->fd);
#else
close(c->fd); close(c->fd);
#endif
pthread_mutex_destroy(&c->iolock); pthread_mutex_destroy(&c->iolock);
_xcb_in_destroy(&c->in); _xcb_in_destroy(&c->in);
@ -559,30 +528,3 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
return ret; return ret;
} }
uint64_t xcb_total_read(xcb_connection_t *c)
{
uint64_t n;
if (xcb_connection_has_error(c))
return 0;
pthread_mutex_lock(&c->iolock);
n = c->in.total_read;
pthread_mutex_unlock(&c->iolock);
return n;
}
uint64_t xcb_total_written(xcb_connection_t *c)
{
uint64_t n;
if (xcb_connection_has_error(c))
return 0;
pthread_mutex_lock(&c->iolock);
n = c->out.total_written;
pthread_mutex_unlock(&c->iolock);
return n;
}

View File

@ -32,6 +32,7 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
@ -39,7 +40,6 @@
#include <poll.h> #include <poll.h>
#endif #endif
#ifndef _WIN32 #ifndef _WIN32
#include <unistd.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
@ -239,15 +239,9 @@ static int read_packet(xcb_connection_t *c)
if(pend && pend->workaround == WORKAROUND_GLX_GET_FB_CONFIGS_BUG) if(pend && pend->workaround == WORKAROUND_GLX_GET_FB_CONFIGS_BUG)
{ {
uint32_t *p = (uint32_t *) c->in.queue; uint32_t *p = (uint32_t *) c->in.queue;
uint64_t new_length = ((uint64_t)p[2]) * ((uint64_t)p[3]); genrep.length = p[2] * p[3] * 2;
if(new_length >= (UINT32_MAX / UINT32_C(16)))
{
_xcb_conn_shutdown(c, XCB_CONN_CLOSED_MEM_INSUFFICIENT);
return 0;
}
genrep.length = (uint32_t)(new_length * UINT64_C(2));
} }
length += genrep.length * UINT64_C(4); length += genrep.length * 4;
/* XXX a bit of a hack -- we "know" that all FD replys place /* XXX a bit of a hack -- we "know" that all FD replys place
* the number of fds in the pad0 byte */ * the number of fds in the pad0 byte */
@ -257,7 +251,7 @@ static int read_packet(xcb_connection_t *c)
/* XGE events may have sizes > 32 */ /* XGE events may have sizes > 32 */
if ((genrep.response_type & 0x7f) == XCB_XGE_EVENT) if ((genrep.response_type & 0x7f) == XCB_XGE_EVENT)
eventlength = genrep.length * UINT64_C(4); eventlength = genrep.length * 4;
bufsize = length + eventlength + nfd * sizeof(int) + bufsize = length + eventlength + nfd * sizeof(int) +
(genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t)); (genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t));
@ -371,7 +365,7 @@ static void free_reply_list(struct reply_list *head)
} }
} }
static int read_block(const int fd, void *buf, const intptr_t len) static int read_block(const int fd, void *buf, const ssize_t len)
{ {
int done = 0; int done = 0;
while(done < len) while(done < len)
@ -742,16 +736,11 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
return 0; return 0;
pthread_mutex_lock(&c->iolock); pthread_mutex_lock(&c->iolock);
request = widen(c, cookie.sequence); request = widen(c, cookie.sequence);
if (XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed)) if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected)
&& XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed))
{ {
if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected)) _xcb_out_send_sync(c);
{ _xcb_out_flush_to(c, c->out.request);
_xcb_out_send_sync(c);
}
if (XCB_SEQUENCE_COMPARE(request, >=, c->out.request_expected_written))
{
_xcb_out_flush_to(c, c->out.request);
}
} }
reply = wait_for_reply(c, request, &ret); reply = wait_for_reply(c, request, &ret);
assert(!reply); assert(!reply);
@ -969,20 +958,8 @@ void _xcb_in_replies_done(xcb_connection_t *c)
pend = container_of(c->in.pending_replies_tail, struct pending_reply, next); pend = container_of(c->in.pending_replies_tail, struct pending_reply, next);
if(pend->workaround == WORKAROUND_EXTERNAL_SOCKET_OWNER) if(pend->workaround == WORKAROUND_EXTERNAL_SOCKET_OWNER)
{ {
if (XCB_SEQUENCE_COMPARE(pend->first_request, <=, c->out.request)) { pend->last_request = c->out.request;
pend->last_request = c->out.request; pend->workaround = WORKAROUND_NONE;
pend->workaround = WORKAROUND_NONE;
} else {
/* The socket was taken, but no requests were actually sent
* so just discard the pending_reply that was created.
*/
struct pending_reply **prev_next = &c->in.pending_replies;
while (*prev_next != pend)
prev_next = &(*prev_next)->next;
*prev_next = NULL;
c->in.pending_replies_tail = prev_next;
free(pend);
}
} }
} }
} }
@ -1036,7 +1013,6 @@ int _xcb_in_read(xcb_connection_t *c)
} }
} }
#endif #endif
c->in.total_read += n;
c->in.queue_len += n; c->in.queue_len += n;
} }
while(read_packet(c)) while(read_packet(c))
@ -1063,7 +1039,7 @@ int _xcb_in_read(xcb_connection_t *c)
} }
#endif #endif
#ifndef _WIN32 #ifndef _WIN32
if((n > 0) || (n < 0 && (errno == EAGAIN || errno == EINTR))) if((n > 0) || (n < 0 && errno == EAGAIN))
#else #else
if((n > 0) || (n < 0 && WSAGetLastError() == WSAEWOULDBLOCK)) if((n > 0) || (n < 0 && WSAGetLastError() == WSAEWOULDBLOCK))
#endif /* !_WIN32 */ #endif /* !_WIN32 */

View File

@ -36,7 +36,7 @@
typedef struct node { typedef struct node {
struct node *next; struct node *next;
uint64_t key; unsigned int key;
void *data; void *data;
} node; } node;
@ -73,7 +73,7 @@ void _xcb_map_delete(_xcb_map *list, xcb_list_free_func_t do_free)
free(list); free(list);
} }
int _xcb_map_put(_xcb_map *list, uint64_t key, void *data) int _xcb_map_put(_xcb_map *list, unsigned int key, void *data)
{ {
node *cur = malloc(sizeof(node)); node *cur = malloc(sizeof(node));
if(!cur) if(!cur)
@ -86,7 +86,7 @@ int _xcb_map_put(_xcb_map *list, uint64_t key, void *data)
return 1; return 1;
} }
void *_xcb_map_remove(_xcb_map *list, uint64_t key) void *_xcb_map_remove(_xcb_map *list, unsigned int key)
{ {
node **cur; node **cur;
for(cur = &list->head; *cur; cur = &(*cur)->next) for(cur = &list->head; *cur; cur = &(*cur)->next)

View File

@ -31,11 +31,7 @@
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h> #include <unistd.h>
#endif
#include <string.h> #include <string.h>
#include "xcb.h" #include "xcb.h"
@ -391,14 +387,8 @@ int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), v
{ {
c->out.return_socket = return_socket; c->out.return_socket = return_socket;
c->out.socket_closure = closure; c->out.socket_closure = closure;
if(flags) { if(flags)
/* c->out.request + 1 will be the first request sent by the external _xcb_in_expect_reply(c, c->out.request, WORKAROUND_EXTERNAL_SOCKET_OWNER, flags);
* socket owner. If the socket is returned before this request is sent
* it will be detected in _xcb_in_replies_done and this pending_reply
* will be discarded.
*/
_xcb_in_expect_reply(c, c->out.request + 1, WORKAROUND_EXTERNAL_SOCKET_OWNER, flags);
}
assert(c->out.request == c->out.request_written); assert(c->out.request == c->out.request_written);
*sent = c->out.request; *sent = c->out.request;
} }
@ -447,7 +437,6 @@ int _xcb_out_init(_xcb_out *out)
out->request = 0; out->request = 0;
out->request_written = 0; out->request_written = 0;
out->request_expected_written = 0;
if(pthread_mutex_init(&out->reqlenlock, 0)) if(pthread_mutex_init(&out->reqlenlock, 0))
return 0; return 0;
@ -458,9 +447,8 @@ int _xcb_out_init(_xcb_out *out)
void _xcb_out_destroy(_xcb_out *out) void _xcb_out_destroy(_xcb_out *out)
{ {
pthread_mutex_destroy(&out->reqlenlock);
pthread_cond_destroy(&out->cond); pthread_cond_destroy(&out->cond);
pthread_cond_destroy(&out->socket_cond); 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)
@ -469,7 +457,6 @@ int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count)
while(ret && count) while(ret && count)
ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count); ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count);
c->out.request_written = c->out.request; c->out.request_written = c->out.request;
c->out.request_expected_written = c->in.request_expected;
pthread_cond_broadcast(&c->out.cond); pthread_cond_broadcast(&c->out.cond);
_xcb_in_wake_up_next_reader(c); _xcb_in_wake_up_next_reader(c);
return ret; return ret;

View File

@ -36,12 +36,12 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stddef.h> #include <stddef.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#ifdef _WIN32 #ifdef _WIN32
#include "xcb_windefs.h" #include "xcb_windefs.h"
#else #else
#include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
@ -60,27 +60,16 @@
# include <sys/stat.h> # include <sys/stat.h>
#endif #endif
#ifdef HAVE_LAUNCHD
#include <sys/stat.h> #include <sys/stat.h>
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif #endif
int xcb_popcount(uint32_t mask) int xcb_popcount(uint32_t mask)
{ {
#if __has_builtin(__builtin_popcount)
return __builtin_popcount(mask);
#else
/*
* Count the number of bits set to 1 in a 32-bit word.
* Algorithm from MIT AI Lab Memo 239: "HAKMEM", ITEM 169.
* https://dspace.mit.edu/handle/1721.1/6086
*/
uint32_t y; uint32_t y;
y = (mask >> 1) & 033333333333; y = (mask >> 1) & 033333333333;
y = mask - y - ((y >> 1) & 033333333333); y = mask - y - ((y >> 1) & 033333333333);
return ((y + (y >> 3)) & 030707070707) % 077; return ((y + (y >> 3)) & 030707070707) % 077;
#endif
} }
int xcb_sumof(uint8_t *list, int len) int xcb_sumof(uint8_t *list, int len)
@ -93,6 +82,7 @@ int xcb_sumof(uint8_t *list, int len)
return s; return s;
} }
#ifdef HAVE_LAUNCHD
/* Return true and parse if name matches <path to socket>[.<screen>] /* Return true and parse if name matches <path to socket>[.<screen>]
* Upon success: * Upon success:
* host = <path to socket> * host = <path to socket>
@ -104,33 +94,20 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
int *displayp, int *screenp) int *displayp, int *screenp)
{ {
struct stat sbuf; struct stat sbuf;
/* In addition to the AF_UNIX path, there may be a screen number. char path[PATH_MAX];
* The trailing \0 is already accounted in the size of sun_path. */ int _screen = 0;
char path[sizeof(((struct sockaddr_un*)0)->sun_path) + 1 + 10];
size_t len;
int _screen = 0, res;
len = strlen(name); strlcpy(path, name, sizeof(path));
if (len >= sizeof(path)) if (0 != stat(path, &sbuf)) {
return 0; char *dot = strrchr(path, '.');
memcpy(path, name, len + 1); if (!dot)
res = stat(path, &sbuf);
if (0 != res) {
unsigned long lscreen;
char *dot, *endptr;
if (res != -1 || (errno != ENOENT && errno != ENOTDIR))
return 0;
dot = strrchr(path, '.');
if (!dot || dot[1] < '1' || dot[1] > '9')
return 0; return 0;
*dot = '\0'; *dot = '\0';
errno = 0;
lscreen = strtoul(dot + 1, &endptr, 10);
if (lscreen > INT_MAX || !endptr || *endptr || errno)
return 0;
if (0 != stat(path, &sbuf)) if (0 != stat(path, &sbuf))
return 0; return 0;
_screen = (int)lscreen;
_screen = atoi(dot + 1);
} }
if (host) { if (host) {
@ -156,6 +133,7 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
return 1; return 1;
} }
#endif
static int _xcb_parse_display(const char *name, char **host, char **protocol, static int _xcb_parse_display(const char *name, char **host, char **protocol,
int *displayp, int *screenp) int *displayp, int *screenp)
@ -168,12 +146,11 @@ static int _xcb_parse_display(const char *name, char **host, char **protocol,
if(!name) if(!name)
return 0; return 0;
#ifdef HAVE_LAUNCHD
/* First check for <path to socket>[.<screen>] */ /* First check for <path to socket>[.<screen>] */
if (name[0] == '/') if (_xcb_parse_display_path_to_socket(name, host, protocol, displayp, screenp))
return _xcb_parse_display_path_to_socket(name, host, protocol, displayp, screenp); return 1;
#endif
if (strncmp(name, "unix:", 5) == 0)
return _xcb_parse_display_path_to_socket(name + 5, host, protocol, displayp, screenp);
slash = strrchr(name, '/'); slash = strrchr(name, '/');
@ -259,46 +236,41 @@ static int _xcb_open(const char *host, char *protocol, const int display)
char *file = NULL; char *file = NULL;
int actual_filelen; int actual_filelen;
#ifndef _WIN32 /* If protocol or host is "unix", fall through to Unix socket code below */
if (protocol && strcmp("unix", protocol) == 0 && host && host[0] == '/') { if ((!protocol || (strcmp("unix",protocol) != 0)) &&
/* Full path to socket provided, ignore everything else */ (*host != '\0') && (strcmp("unix",host) != 0))
filelen = strlen(host) + 1; {
if (filelen > INT_MAX) /* display specifies TCP */
return -1; unsigned short port = X_TCP_PORT + display;
file = malloc(filelen); return _xcb_open_tcp(host, protocol, port);
if (file == NULL) }
return -1;
memcpy(file, host, filelen);
actual_filelen = (int)(filelen - 1);
} else {
#endif
/* If protocol or host is "unix", fall through to Unix socket code below */
if ((!protocol || (strcmp("unix",protocol) != 0)) &&
(*host != '\0') && (strcmp("unix",host) != 0))
{
/* display specifies TCP */
unsigned short port = X_TCP_PORT + display;
return _xcb_open_tcp(host, protocol, port);
}
#ifndef _WIN32 #ifndef _WIN32
#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED) #if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED)
/* Check special path for Unix sockets under Solaris Trusted Extensions */ /* Check special path for Unix sockets under Solaris Trusted Extensions */
if (is_system_labeled()) if (is_system_labeled())
{ {
const char *tsol_base = "/var/tsol/doors/.X11-unix/X"; struct stat sbuf;
char tsol_socket[PATH_MAX]; const char *tsol_base = "/var/tsol/doors/.X11-unix/X";
struct stat sbuf; char tsol_socket[PATH_MAX];
snprintf(tsol_socket, sizeof(tsol_socket), "%s%d", tsol_base, display); snprintf(tsol_socket, sizeof(tsol_socket), "%s%d", tsol_base, display);
if (stat(tsol_socket, &sbuf) == 0) if (stat(tsol_socket, &sbuf) == 0)
base = tsol_base; base = tsol_base;
else if (errno != ENOENT) }
return 0;
}
#endif #endif
#ifdef HAVE_LAUNCHD
struct stat sbuf;
if (0 == stat(host, &sbuf)) {
file = strdup(host);
if(file == NULL)
return -1;
filelen = actual_filelen = strlen(file);
} else
#endif
{
filelen = strlen(base) + 1 + sizeof(display) * 3 + 1; filelen = strlen(base) + 1 + sizeof(display) * 3 + 1;
file = malloc(filelen); file = malloc(filelen);
if(file == NULL) if(file == NULL)
@ -306,23 +278,24 @@ static int _xcb_open(const char *host, char *protocol, const int display)
/* display specifies Unix socket */ /* display specifies Unix socket */
actual_filelen = snprintf(file, filelen, "%s%d", base, display); actual_filelen = snprintf(file, filelen, "%s%d", base, display);
if(actual_filelen < 0)
{
free(file);
return -1;
}
/* snprintf may truncate the file */
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
} }
if(actual_filelen < 0)
{
free(file);
return -1;
}
/* snprintf may truncate the file */
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
fd = _xcb_open_unix(protocol, file); fd = _xcb_open_unix(protocol, file);
free(file); free(file);
@ -416,11 +389,7 @@ static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short
fd = _xcb_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); fd = _xcb_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (_xcb_do_connect(fd, addr->ai_addr, addr->ai_addrlen) >= 0) if (_xcb_do_connect(fd, addr->ai_addr, addr->ai_addrlen) >= 0)
break; break;
#ifdef _WIN32
closesocket(fd);
#else
close(fd); close(fd);
#endif
fd = -1; fd = -1;
} }
freeaddrinfo(results); freeaddrinfo(results);
@ -446,11 +415,7 @@ static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short
if(_xcb_do_connect(fd, (struct sockaddr*)&_s, sizeof(_s)) >= 0) if(_xcb_do_connect(fd, (struct sockaddr*)&_s, sizeof(_s)) >= 0)
break; break;
#ifdef _WIN32
closesocket(fd);
#else
close(fd); close(fd);
#endif
fd = -1; fd = -1;
++_c; ++_c;
} }
@ -559,8 +524,10 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname,
if(auth) { if(auth) {
c = xcb_connect_to_fd(fd, auth); c = xcb_connect_to_fd(fd, auth);
goto out;
} }
else if(_xcb_get_auth_info(fd, &ourauth, display))
if(_xcb_get_auth_info(fd, &ourauth, display))
{ {
c = xcb_connect_to_fd(fd, &ourauth); c = xcb_connect_to_fd(fd, &ourauth);
free(ourauth.name); free(ourauth.name);

View File

@ -55,7 +55,7 @@ uint32_t xcb_generate_id(xcb_connection_t *c)
/* check for extension */ /* check for extension */
const xcb_query_extension_reply_t *xc_misc_reply = const xcb_query_extension_reply_t *xc_misc_reply =
xcb_get_extension_data(c, &xcb_xc_misc_id); xcb_get_extension_data(c, &xcb_xc_misc_id);
if (!xc_misc_reply || !xc_misc_reply->present) { if (!xc_misc_reply) {
pthread_mutex_unlock(&c->xid.lock); pthread_mutex_unlock(&c->xid.lock);
return -1; return -1;
} }

View File

@ -297,7 +297,6 @@ int xcb_poll_for_reply64(xcb_connection_t *c, uint64_t request, void **reply, xc
* @param replylen The size of the reply. * @param replylen The size of the reply.
* @return Pointer to the location where received file descriptors are stored. * @return Pointer to the location where received file descriptors are stored.
*/ */
XCB_CONST_FUNCTION
int *xcb_get_reply_fds(xcb_connection_t *c, void *reply, size_t replylen); int *xcb_get_reply_fds(xcb_connection_t *c, void *reply, size_t replylen);
@ -307,7 +306,6 @@ int *xcb_get_reply_fds(xcb_connection_t *c, void *reply, size_t replylen);
* @param mask The mask to check * @param mask The mask to check
* @return The number of set bits in the mask * @return The number of set bits in the mask
*/ */
XCB_CONST_FUNCTION
int xcb_popcount(uint32_t mask); int xcb_popcount(uint32_t mask);
/** /**
@ -315,7 +313,6 @@ int xcb_popcount(uint32_t mask);
* @param len The length of the array * @param len The length of the array
* @return The sum of all entries in the array. * @return The sum of all entries in the array.
*/ */
XCB_PURE_FUNCTION
int xcb_sumof(uint8_t *list, int len); int xcb_sumof(uint8_t *list, int len);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -38,16 +38,6 @@
#pragma GCC visibility push(hidden) #pragma GCC visibility push(hidden)
#endif #endif
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with older compilers. */
#endif
#if __has_attribute(fallthrough)
# define XCB_ALLOW_FALLTHRU __attribute__ ((fallthrough));
#else
# define XCB_ALLOW_FALLTHRU /* FALLTHRU */
#endif
enum workarounds { enum workarounds {
WORKAROUND_NONE, WORKAROUND_NONE,
WORKAROUND_GLX_GET_FB_CONFIGS_BUG, WORKAROUND_GLX_GET_FB_CONFIGS_BUG,
@ -83,8 +73,8 @@ typedef struct _xcb_map _xcb_map;
_xcb_map *_xcb_map_new(void); _xcb_map *_xcb_map_new(void);
void _xcb_map_delete(_xcb_map *q, xcb_list_free_func_t do_free); void _xcb_map_delete(_xcb_map *q, xcb_list_free_func_t do_free);
int _xcb_map_put(_xcb_map *q, uint64_t key, void *data); int _xcb_map_put(_xcb_map *q, unsigned int key, void *data);
void *_xcb_map_remove(_xcb_map *q, uint64_t key); void *_xcb_map_remove(_xcb_map *q, unsigned int key);
/* xcb_out.c */ /* xcb_out.c */
@ -113,8 +103,6 @@ typedef struct _xcb_out {
uint64_t request; uint64_t request;
uint64_t request_written; uint64_t request_written;
uint64_t request_expected_written;
uint64_t total_written;
pthread_mutex_t reqlenlock; pthread_mutex_t reqlenlock;
enum lazy_reply_tag maximum_request_length_tag; enum lazy_reply_tag maximum_request_length_tag;
@ -147,7 +135,6 @@ typedef struct _xcb_in {
uint64_t request_expected; uint64_t request_expected;
uint64_t request_read; uint64_t request_read;
uint64_t request_completed; uint64_t request_completed;
uint64_t total_read;
struct reply_list *current_reply; struct reply_list *current_reply;
struct reply_list **current_reply_tail; struct reply_list **current_reply_tail;
@ -225,7 +212,6 @@ struct xcb_connection_t {
void _xcb_conn_shutdown(xcb_connection_t *c, int err); void _xcb_conn_shutdown(xcb_connection_t *c, int err);
XCB_CONST_FUNCTION
xcb_connection_t *_xcb_conn_ret_error(int err); xcb_connection_t *_xcb_conn_ret_error(int err);
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count); int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);

View File

@ -1,19 +1,10 @@
#include <stdlib.h> #include <stdlib.h>
#include "check_suites.h" #include "check_suites.h"
#if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 13
void suite_add_test(Suite *s, TFun tf, const char *name) void suite_add_test(Suite *s, TFun tf, const char *name)
#else
void suite_add_test(Suite *s, const TTest *tt, const char *name)
#endif
{ {
TCase *tc = tcase_create(name); TCase *tc = tcase_create(name);
#if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 13
tcase_add_test(tc, tf); tcase_add_test(tc, tf);
#else
tcase_add_test(tc, tt);
#endif
suite_add_tcase(s, tc); suite_add_tcase(s, tc);
} }

View File

@ -1,10 +1,6 @@
#include <check.h> #include <check.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef __unix__
#include <unistd.h>
#endif
#include "check_suites.h" #include "check_suites.h"
#include "xcb.h" #include "xcb.h"
#include "xcbext.h" #include "xcbext.h"
@ -16,10 +12,6 @@ typedef enum test_type_t {
} test_type_t; } test_type_t;
static const char *const test_string[] = { "", "via $DISPLAY " }; static const char *const test_string[] = { "", "via $DISPLAY " };
/* putenv(3) takes a pointer to a writable string that it adds directly
to the environment, so it must be in persistent memory, not on the stack */
static char display_env[] = "DISPLAY=";
static void parse_display_pass(const char *name, const char *host, const int display, const int screen) static void parse_display_pass(const char *name, const char *host, const int display, const int screen)
{ {
int success; int success;
@ -33,7 +25,7 @@ static void parse_display_pass(const char *name, const char *host, const int dis
if(test_type == TEST_ARGUMENT) if(test_type == TEST_ARGUMENT)
{ {
argument = name; argument = name;
putenv(display_env); putenv("DISPLAY=");
} }
else if(test_type == TEST_ENVIRONMENT) else if(test_type == TEST_ENVIRONMENT)
{ {
@ -45,20 +37,20 @@ static void parse_display_pass(const char *name, const char *host, const int dis
got_display = got_screen = -42; got_display = got_screen = -42;
mark_point(); mark_point();
success = xcb_parse_display(argument, &got_host, &got_display, &got_screen); success = xcb_parse_display(argument, &got_host, &got_display, &got_screen);
ck_assert_msg(success, "unexpected parse failure %sfor '%s'", test_string[test_type], name); fail_unless(success, "unexpected parse failure %sfor '%s'", test_string[test_type], name);
ck_assert_msg(strcmp(host, got_host) == 0, "parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host); fail_unless(strcmp(host, got_host) == 0, "parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host);
ck_assert_msg(display == got_display, "parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display); fail_unless(display == got_display, "parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display);
ck_assert_msg(screen == got_screen, "parse %sproduced unexpected screen '%d' for '%s': expected '%d'", test_string[test_type], got_screen, name, screen); fail_unless(screen == got_screen, "parse %sproduced unexpected screen '%d' for '%s': expected '%d'", test_string[test_type], got_screen, name, screen);
got_host = (char *) -1; got_host = (char *) -1;
got_display = got_screen = -42; got_display = got_screen = -42;
mark_point(); mark_point();
success = xcb_parse_display(argument, &got_host, &got_display, 0); success = xcb_parse_display(argument, &got_host, &got_display, 0);
ck_assert_msg(success, "unexpected screenless parse failure %sfor '%s'", test_string[test_type], name); fail_unless(success, "unexpected screenless parse failure %sfor '%s'", test_string[test_type], name);
ck_assert_msg(strcmp(host, got_host) == 0, "screenless parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host); fail_unless(strcmp(host, got_host) == 0, "screenless parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host);
ck_assert_msg(display == got_display, "screenless parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display); fail_unless(display == got_display, "screenless parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display);
} }
putenv(display_env); putenv("DISPLAY=");
} }
static void parse_display_fail(const char *name) static void parse_display_fail(const char *name)
@ -74,7 +66,7 @@ static void parse_display_fail(const char *name)
if(test_type == TEST_ARGUMENT) if(test_type == TEST_ARGUMENT)
{ {
argument = name; argument = name;
putenv(display_env); putenv("DISPLAY=");
} }
else if(test_type == TEST_ENVIRONMENT) else if(test_type == TEST_ENVIRONMENT)
{ {
@ -87,55 +79,24 @@ static void parse_display_fail(const char *name)
got_display = got_screen = -42; got_display = got_screen = -42;
mark_point(); mark_point();
success = xcb_parse_display(argument, &got_host, &got_display, &got_screen); success = xcb_parse_display(argument, &got_host, &got_display, &got_screen);
ck_assert_msg(!success, "unexpected parse success %sfor '%s'", test_string[test_type], name); fail_unless(!success, "unexpected parse success %sfor '%s'", test_string[test_type], name);
ck_assert_msg(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host); fail_unless(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host);
ck_assert_msg(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display); fail_unless(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display);
ck_assert_msg(got_screen == -42, "screen changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_screen); fail_unless(got_screen == -42, "screen changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_screen);
got_host = (char *) -1; got_host = (char *) -1;
got_display = got_screen = -42; got_display = got_screen = -42;
mark_point(); mark_point();
success = xcb_parse_display(argument, &got_host, &got_display, 0); success = xcb_parse_display(argument, &got_host, &got_display, 0);
ck_assert_msg(!success, "unexpected screenless parse success %sfor '%s'", test_string[test_type], name); fail_unless(!success, "unexpected screenless parse success %sfor '%s'", test_string[test_type], name);
ck_assert_msg(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host); fail_unless(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host);
ck_assert_msg(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display); fail_unless(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display);
} }
putenv(display_env); putenv("DISPLAY=");
} }
START_TEST(parse_display_unix) START_TEST(parse_display_unix)
{ {
#ifdef __unix__
char buf[sizeof "/tmp/xcb-test.XXXXXXX"];
char buf2[sizeof(buf) + 7];
int r, v;
memcpy(buf, "/tmp/xcb-test.XXXXXXX", sizeof buf);
v = mkstemp(buf);
ck_assert_msg(v >= 0, "cannot create temporary file");
parse_display_pass(buf, buf, 0, 0);
r = snprintf(buf2, sizeof buf2, "unix:%s", buf);
if (r < 5 || r >= (int)sizeof buf2) {
ck_assert_msg(0, "snprintf() failed (return value %d)", r);
unlink(buf);
return;
}
parse_display_pass(buf2, buf, 0, 0);
r = snprintf(buf2, sizeof buf2, "unix:%s.1", buf);
if (r < 7 || r >= (int)sizeof buf2) {
ck_assert_msg(0, "snprintf() failed (return value %d)", r);
unlink(buf);
return;
}
parse_display_pass(buf2, buf, 0, 1);
r = snprintf(buf2, sizeof buf2, "%s.1", buf);
if (r < 2 || r >= (int)sizeof buf2) {
ck_assert_msg(0, "snprintf() failed (return value %d)", r);
unlink(buf);
return;
}
parse_display_pass(buf2, buf, 0, 1);
unlink(buf);
#endif
parse_display_pass(":0", "", 0, 0); parse_display_pass(":0", "", 0, 0);
parse_display_pass(":1", "", 1, 0); parse_display_pass(":1", "", 1, 0);
parse_display_pass(":0.1", "", 0, 1); parse_display_pass(":0.1", "", 0, 1);
@ -222,7 +183,7 @@ END_TEST
static void popcount_eq(uint32_t bits, int count) static void popcount_eq(uint32_t bits, int count)
{ {
ck_assert_msg(xcb_popcount(bits) == count, "unexpected popcount(%08x) != %d", bits, count); fail_unless(xcb_popcount(bits) == count, "unexpected popcount(%08x) != %d", bits, count);
} }
START_TEST(popcount) START_TEST(popcount)
@ -245,7 +206,7 @@ END_TEST
Suite *public_suite(void) Suite *public_suite(void)
{ {
Suite *s = suite_create("Public API"); Suite *s = suite_create("Public API");
putenv(display_env); putenv("DISPLAY=");
suite_add_test(s, parse_display_unix, "xcb_parse_display unix"); suite_add_test(s, parse_display_unix, "xcb_parse_display unix");
suite_add_test(s, parse_display_ip, "xcb_parse_display ip"); suite_add_test(s, parse_display_ip, "xcb_parse_display ip");
suite_add_test(s, parse_display_ipv4, "xcb_parse_display ipv4"); suite_add_test(s, parse_display_ipv4, "xcb_parse_display ipv4");

View File

@ -1,8 +1,4 @@
#include <check.h> #include <check.h>
#if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 13
void suite_add_test(Suite *s, TFun tf, const char *name); void suite_add_test(Suite *s, TFun tf, const char *name);
#else
void suite_add_test(Suite *s, const TTest *tt, const char *name);
#endif
Suite *public_suite(void); Suite *public_suite(void);

View File

@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: XCB Dbe
Description: XCB Double Buffer Extension
Version: @PACKAGE_VERSION@
Requires.private: xcb
Libs: -L${libdir} -lxcb-dbe
Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Present Name: XCB Present
Description: XCB Present Extension Description: XCB Present Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb xcb-randr xcb-xfixes xcb-sync xcb-dri3 Requires.private: xcb xcb-randr xcb-xfixes xcb-sync
Libs: -L${libdir} -lxcb-present Libs: -L${libdir} -lxcb-present
Cflags: -I${includedir} Cflags: -I${includedir}