Compare commits

..

4 Commits

Author SHA1 Message Date
Uli Schlachter 7cf5ac145b Release libxcb 1.11.1 2015-09-06 12:39:19 +02:00
Uli Schlachter 00903d4d6a Fix a thread hang with xcb_wait_for_special_event()
Consider the following:

- Two threads are calling xcb_wait_for_special_event() and xcb_wait_for_reply()
  concurrently.
- The thread doing xcb_wait_for_reply() wins the race and poll()s the socket for
  readability.
- The other thread will be put to sleep on the special_event_cond of the special
  event (this is done in _xcb_conn_wait() via the argument
  xcb_wait_for_special_event() gives it).
- The first thread gets its reply, but does not yet receive any special event.

In this case, the first thread will return to its caller. On its way out, it
will call _xcb_in_wake_up_next_reader(), but that function cannot wake up
anything since so far it did not handle xcb_wait_for_special_event().

Thus, the first thread stays blocked on the condition variable and no thread
tries to read from the socket.

A test case demonstrating this problem is available at the bug report.

Fix this similar to how we handle this with xcb_wait_for_reply():

The function wait_for_reply() adds an entry into a linked list of threads that
wait for a reply. Via this list, _xcb_in_wake_up_next_reader() can wake up this
thread so that it can call _xcb_conn_wait() again and then poll()s the socket.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=84252
Signed-off-by: Uli Schlachter <psychon@znc.in>
Tested-by: Michel Dänzer <michel.daenzer@amd.com>
2015-09-05 14:56:51 +02:00
Michel Dänzer a31c295870 Call _xcb_wake_up_next_reader from xcb_wait_for_special_event
All functions calling _xcb_conn_wait() must make sure that waiting
readers are woken up when we read a reply or event that they are waiting
for. xcb_wait_for_special_event() did not do so. This adds the missing
call to_xcb_in_wake_up_next_reader().

Fixes deadlock when waiting for a special event and concurrently
processing the display connection queue in another thread.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=84252
Tested-by: Thomas Daede <bztdlinux@gmail.com>
Tested-by: Clément Guérin <geecko.dev@free.fr>
Reviewed-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Michel Dänzer <michel@daenzer.net>
Signed-off-by: Uli Schlachter <psychon@znc.in>
2015-09-05 14:56:45 +02:00
Christian Linhart 0ba6fe9b4e expose 64-bit sequence numbers for XLib
While XCB uses 64-bit sequence number internally, it only exposes
"unsigned int" so that, on 32-bit architecture, Xlib based applications
may see their sequence number wrap which causes the connection to the X
server to be lost.

Expose 64-bit sequence number from XCB API so that Xlib and others can
use it even on 32-bit environment.

This implies the following API addition:

  xcb_send_request64()
  xcb_discard_reply64()
  xcb_wait_for_reply64()
  xcb_poll_for_reply64()

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71338

Reviewed-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Christian Linhart <chris@demorecorder.com>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2015-09-05 14:56:03 +02:00
57 changed files with 863 additions and 1801 deletions

5
.gitignore vendored
View File

@ -21,8 +21,3 @@ libtool
m4/l*.m4 m4/l*.m4
mkinstalldirs mkinstalldirs
stamp-h1 stamp-h1
ChangeLog
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

229
INSTALL Normal file
View File

@ -0,0 +1,229 @@
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the `--target=TYPE' option to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
will cause the specified gcc to be used as the C compiler (unless it is
overridden in the site shell script).
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

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
@ -87,9 +84,6 @@ endif
if BUILD_XVMC if BUILD_XVMC
pkgconfig_DATA += xcb-xvmc.pc pkgconfig_DATA += xcb-xvmc.pc
endif endif
if BUILD_GE
pkgconfig_DATA += xcb-ge.pc
endif
AM_TESTS_ENVIRONMENT = \ AM_TESTS_ENVIRONMENT = \
@ -102,17 +96,4 @@ 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
.PHONY: ChangeLog INSTALL
INSTALL:
$(INSTALL_CMD)
ChangeLog:
$(CHANGELOG_CMD)
dist-hook: ChangeLog INSTALL

47
NEWS
View File

@ -1,50 +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)
=========================
* Add support for variable-sized lists of FDs
* Poll for events when blocking waiting for special events
* xinput: Enable XInput extension by default
* ge: Add explicit support for GenericEvent extension
* Fix documentation warnings from clang
* Cosmetic cleanups
Release 1.12 (2016-05-18)
=========================
* configure: Various fixes for dri3 and FD passing support
* configure: Don't report all the warning CFLAGS
* configure: Disable Xevie and Xprint by default
* Add support for various new constructs in the XML schema
* Make some functions also accept connections in an error state
* Never return NULL from xcb_get_setup()
* Use Requires.private in .pc files to avoid overlinking
* Fix align-pads for switches which start at unaligned positions
* Use anonymous structs for some nested structs
* Also generate accessors for variable-sized events and requests
* Improved python3 compatibility
* Generate C99 initializers instead of comments
* Various simplifications to the python code
* Fix line breaks in xcb-requests manual page
* Always close FDs in xcb_send_fd()
* Fix thread-safety issues with FD passing
* Add xcb_send_request_with_fds() and xcb_send_request_with_fds64()
* Fix endless loop with too many outstanding FDs to send
* Link with winsock library on MinGW
* Disable some unfinished API for some server-side code by default
* Use align-offsets computed by xcb-proto instead of low bits of pointers
* Fix iterator interaction with align padding
* Stop serializing padding by default
* Increase unix socket send buffer to at least 64KiB
Release 1.11.1 (2015-09-06) Release 1.11.1 (2015-09-06)
=========================== ===========================
* Expose 64-bit sequence numbers for XLib * Expose 64-bit sequence numbers for XLib

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

@ -23,7 +23,7 @@ for inc in src/*.h; do
included=`grep '# *include' $inc | included=`grep '# *include' $inc |
sed -e 's/[^<"]*[<"]//' -e 's/[>"]//' | sed -e 's/[^<"]*[<"]//' -e 's/[>"]//' |
grep -v 'xcb.h\|xproto.h'` grep -v 'xcb.h\|xproto.h'`
requires=`grep '^Requires.private:' $pcin` requires=`grep '^Requires:' $pcin`
missing="" missing=""
for i in $included; do for i in $included; do
ibase=`basename $i .h` ibase=`basename $i .h`
@ -58,7 +58,7 @@ for inc in src/*.h; do
*) *)
if [ "$fix" = "y" ]; then if [ "$fix" = "y" ]; then
echo $package adding dependency on $missing echo $package adding dependency on $missing
sed -i '/^Requires.private:/s/$/ '"$missing"'/' $pcin sed -i '/^Requires:/s/$/ '"$missing"'/' $pcin
else else
echo $package missing $missing echo $package missing $missing
status=1 status=1

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.11.1],
[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.11)
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,11 +86,18 @@ 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)
# Find support for sending a message from a socket AC_ARG_ENABLE(sendfds, AS_HELP_STRING([--disable-sendfds], [Support FD passing (default: auto)]),
AC_SEARCH_LIBS(sendmsg, socket, [have_sendmsg="yes"], [have_sendmsg="no"]) [sendfds=$enableval], [sendfds=auto])
case x$sendfds in
xauto)
AC_SEARCH_LIBS(sendmsg, socket, [sendfds="yes"], [sendfds="no"])
;;
esac
# XPG4v2/UNIX95 added msg_control - check to see if we need to define # XPG4v2/UNIX95 added msg_control - check to see if we need to define
# _XOPEN_SOURCE to get it (such as on Solaris) # _XOPEN_SOURCE to get it (such as on Solaris)
@ -124,14 +126,14 @@ if test "x$ac_cv_member_struct_msghdr_msg_control" = xno; then
AC_CHECK_MEMBER([struct msghdr.msg_control], AC_CHECK_MEMBER([struct msghdr.msg_control],
[AC_DEFINE([_XOPEN_SOURCE], [500], [AC_DEFINE([_XOPEN_SOURCE], [500],
[Defined if needed to expose struct msghdr.msg_control]) [Defined if needed to expose struct msghdr.msg_control])
], [have_sendmsg="no"], [ ], [sendfds="no"], [
#define _XOPEN_SOURCE 500 #define _XOPEN_SOURCE 500
AC_INCLUDES_DEFAULT AC_INCLUDES_DEFAULT
#include <sys/socket.h> #include <sys/socket.h>
]) ])
fi fi
case x$have_sendmsg in case x$sendfds in
xyes) xyes)
AC_DEFINE([HAVE_SENDMSG],1,[Define if your platform supports sendmsg]) AC_DEFINE([HAVE_SENDMSG],1,[Define if your platform supports sendmsg])
;; ;;
@ -210,47 +212,42 @@ case $host_os in
;; ;;
esac esac
dnl Link with winsock for socket functions on MinGW XCB_EXTENSION(Composite, "yes")
case $host_os in XCB_EXTENSION(Damage, "yes")
*mingw*) XCB_EXTENSION(DPMS, "yes")
AC_CHECK_LIB([ws2_32],[main]) XCB_EXTENSION(DRI2, "yes")
;; XCB_EXTENSION(DRI3, "$sendfds")
*) XCB_EXTENSION(GLX, "yes")
;; XCB_EXTENSION(Present, "yes")
esac XCB_EXTENSION(RandR, "yes")
XCB_EXTENSION(Record, "yes")
XCB_EXTENSION(Render, "yes")
XCB_EXTENSION(Resource, "yes")
XCB_EXTENSION(Screensaver, "yes")
XCB_EXTENSION(Shape, "yes")
XCB_EXTENSION(Shm, "yes")
XCB_EXTENSION(Sync, "yes")
XCB_EXTENSION(Xevie, "yes")
XCB_EXTENSION(XFixes, "yes")
XCB_EXTENSION(XFree86-DRI, "yes")
XCB_EXTENSION(Xinerama, "yes")
XCB_EXTENSION(XInput, "no")
XCB_EXTENSION(XKB, "yes")
XCB_EXTENSION(Xprint, "yes")
XCB_EXTENSION(SELinux, "no")
XCB_EXTENSION(XTest, "yes")
XCB_EXTENSION(Xv, "yes")
XCB_EXTENSION(XvMC, "yes")
XCB_EXTENSION(Composite, yes) AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto])
XCB_EXTENSION(Damage, yes) if test "x$LAUNCHD" = xauto; then
XCB_EXTENSION(Dbe, yes) unset LAUNCHD
XCB_EXTENSION(DPMS, yes) AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin])
XCB_EXTENSION(DRI2, yes) fi
XCB_EXTENSION(DRI3, $have_sendmsg)
XCB_EXTENSION(GE, no)
XCB_EXTENSION(GLX, yes)
XCB_EXTENSION(Present, yes)
XCB_EXTENSION(RandR, yes)
XCB_EXTENSION(Record, yes)
XCB_EXTENSION(Render, yes)
XCB_EXTENSION(Resource, yes)
XCB_EXTENSION(Screensaver, yes)
XCB_EXTENSION(Shape, yes)
XCB_EXTENSION(Shm, yes)
XCB_EXTENSION(Sync, yes)
XCB_EXTENSION(Xevie, no)
XCB_EXTENSION(XFixes, yes)
XCB_EXTENSION(XFree86-DRI, yes)
XCB_EXTENSION(Xinerama, yes)
XCB_EXTENSION(XInput, yes)
XCB_EXTENSION(XKB, yes)
XCB_EXTENSION(Xprint, no)
XCB_EXTENSION(SELinux, no)
XCB_EXTENSION(XTest, yes)
XCB_EXTENSION(Xv, yes)
XCB_EXTENSION(XvMC, yes)
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]) if test "x$LAUNCHD" = xyes ; then
AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available])
AM_CONDITIONAL(XCB_SERVERSIDE_SUPPORT, test "x$XCB_SERVERSIDE_SUPPORT" = "xyes") fi
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Makefile Makefile
@ -264,11 +261,9 @@ 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
xcb-ge.pc
xcb-glx.pc xcb-glx.pc
xcb-present.pc xcb-present.pc
xcb-randr.pc xcb-randr.pc
@ -305,7 +300,7 @@ echo " Package: ${PACKAGE_NAME} ${PACKAGE_VERSION}"
echo "" echo ""
echo " Configuration" echo " Configuration"
echo " XDM support.........: ${have_xdmcp}" echo " XDM support.........: ${have_xdmcp}"
echo " sendmsg fd passing..: ${have_sendmsg}" echo " sendmsg fd passing..: ${sendfds}"
echo " Build unit tests....: ${HAVE_CHECK}" echo " Build unit tests....: ${HAVE_CHECK}"
echo " with html results.: ${HTML_CHECK_RESULT}" echo " with html results.: ${HTML_CHECK_RESULT}"
echo " XCB buffer size.....: ${xcb_queue_buffer_size}" echo " XCB buffer size.....: ${xcb_queue_buffer_size}"
@ -313,11 +308,9 @@ 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}"
echo " GenericEvent........: ${BUILD_GE}"
echo " Glx.................: ${BUILD_GLX}" echo " Glx.................: ${BUILD_GLX}"
echo " Randr...............: ${BUILD_RANDR}" echo " Randr...............: ${BUILD_RANDR}"
echo " Record..............: ${BUILD_RECORD}" echo " Record..............: ${BUILD_RECORD}"
@ -342,6 +335,7 @@ echo ""
echo " Used CFLAGS:" echo " Used CFLAGS:"
echo " CPPFLAGS............: ${CPPFLAGS}" echo " CPPFLAGS............: ${CPPFLAGS}"
echo " CFLAGS..............: ${CFLAGS}" echo " CFLAGS..............: ${CFLAGS}"
echo " Warning CFLAGS......: ${BASE_CFLAGS}"
echo "" echo ""
echo " Installation:" echo " Installation:"
echo " Prefix..............: ${prefix}" echo " Prefix..............: ${prefix}"

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

View File

@ -38,32 +38,15 @@ dnl XCB_EXTENSION(name, default)
dnl set the X extension dnl set the X extension
dnl dnl
AC_DEFUN([XCB_EXTENSION], AC_DEFUN([XCB_EXTENSION],
[dnl [
pushdef([UP], translit([$1], [-a-z], [_A-Z]))dnl pushdef([UP], translit([$1], [-a-z], [_A-Z]))dnl
pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl
dnl
m4_if([$2], [yes], [m4_define([xcb_defopt], [yes])],
[$2], [no], [m4_define([xcb_defopt], [no])],
m4_define([xcb_defopt], [auto]))dnl
AC_ARG_ENABLE(DOWN, AC_ARG_ENABLE(DOWN,
[AS_HELP_STRING([--enable-[]DOWN], [AS_HELP_STRING([--enable-[]DOWN], [Build XCB $1 Extension (default: $2)])],
[Build XCB $1 Extension (default: ]xcb_defopt[)])],
[BUILD_[]UP=$enableval], [BUILD_[]UP=$enableval],
[BUILD_[]UP=xcb_defopt]) [BUILD_[]UP=$2])
dnl
m4_if(xcb_defopt, [auto], [
# This extension has a default value of "auto" and depends on the value of $2
if test "x$BUILD_[]UP" = "xauto" ; then
BUILD_[]UP=$2
fi
if test "x$BUILD_[]UP" = "xyes" ; then
if test "x$2" = "xno" ; then
AC_MSG_ERROR([Extension []UP requested, but dependencies are not met])
fi
fi])
m4_undefine([xcb_defopt])dnl
AM_CONDITIONAL(BUILD_[]UP, [test "x$BUILD_[]UP" = "xyes"]) AM_CONDITIONAL(BUILD_[]UP, [test "x$BUILD_[]UP" = "xyes"])
]) ])

View File

@ -36,7 +36,7 @@ void my_example(xcb_connection *conn) {
cookie = xcb_intern_atom(conn, 0, strlen("_NET_WM_NAME"), "_NET_WM_NAME"); cookie = xcb_intern_atom(conn, 0, strlen("_NET_WM_NAME"), "_NET_WM_NAME");
/* ... do other work here if possible ... */ /* ... do other work here if possible ... */
if ((reply = xcb_intern_atom_reply(conn, cookie, NULL))) { if ((reply = xcb_intern_atom_reply(conn, cookie, NULL))) {
printf("The _NET_WM_NAME atom has ID %u\\n", reply->atom); printf("The _NET_WM_NAME atom has ID %u\n", reply->atom);
} }
free(reply); free(reply);
} }
@ -118,7 +118,7 @@ void my_example(xcb_connection *conn, xcb_window_t window) {
cookie = xcb_intern_atom(c, 0, strlen("_NET_WM_NAME"), "_NET_WM_NAME"); cookie = xcb_intern_atom(c, 0, strlen("_NET_WM_NAME"), "_NET_WM_NAME");
/* ... do other work here if possible ... */ /* ... do other work here if possible ... */
if ((reply = xcb_intern_atom_reply(c, cookie, &error))) { if ((reply = xcb_intern_atom_reply(c, cookie, &error))) {
printf("The _NET_WM_NAME atom has ID %u\\n", reply->atom); printf("The _NET_WM_NAME atom has ID %u\n", reply->atom);
free(reply); free(reply);
} else { } else {
fprintf(stderr, "X11 Error %d\\n", error->error_code); fprintf(stderr, "X11 Error %d\\n", error->error_code);
@ -138,7 +138,7 @@ void my_example(xcb_connection *conn, xcb_window_t window) {
"_NET_WM_NAME"); "_NET_WM_NAME");
/* ... do other work here if possible ... */ /* ... do other work here if possible ... */
if ((reply = xcb_intern_atom_reply(c, cookie, NULL))) { if ((reply = xcb_intern_atom_reply(c, cookie, NULL))) {
printf("The _NET_WM_NAME atom has ID %u\\n", reply->atom); printf("The _NET_WM_NAME atom has ID %u\n", reply->atom);
free(reply); free(reply);
} }

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
@ -240,13 +232,6 @@ libxcb_xvmc_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_xvmc_la_SOURCES = xvmc.c xvmc.h nodist_libxcb_xvmc_la_SOURCES = xvmc.c xvmc.h
endif endif
EXTSOURCES += ge.c
if BUILD_GE
lib_LTLIBRARIES += libxcb-ge.la
libxcb_ge_la_LDFLAGS = -version-info 0:0:0 -no-undefined @lt_enable_auto_import@
libxcb_ge_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_ge_la_SOURCES = ge.c ge.h
endif
EXTHEADERS=$(EXTSOURCES:.c=.h) EXTHEADERS=$(EXTSOURCES:.c=.h)
xcbinclude_HEADERS = xcb.h xcbext.h xcbinclude_HEADERS = xcb.h xcbext.h
@ -263,15 +248,9 @@ libman_DATA = $(BUILT_MAN_PAGES)
BUILT_SOURCES = $(EXTSOURCES) $(BUILT_MAN_PAGES) BUILT_SOURCES = $(EXTSOURCES) $(BUILT_MAN_PAGES)
CLEANFILES = $(EXTSOURCES) $(EXTHEADERS) $(BUILT_MAN_PAGES) CLEANFILES = $(EXTSOURCES) $(EXTHEADERS) $(BUILT_MAN_PAGES)
C_CLIENT_PY_EXTRA_ARGS =
if XCB_SERVERSIDE_SUPPORT
C_CLIENT_PY_EXTRA_ARGS += --server-side
endif
$(EXTSOURCES): c_client.py $(XCBPROTO_XCBINCLUDEDIR)/$(@:.c=.xml) $(EXTSOURCES): c_client.py $(XCBPROTO_XCBINCLUDEDIR)/$(@:.c=.xml)
$(AM_V_GEN)$(PYTHON) $(srcdir)/c_client.py -c "$(PACKAGE_STRING)" -l "$(XORG_MAN_PAGE)" \ $(AM_V_GEN)$(PYTHON) $(srcdir)/c_client.py -c "$(PACKAGE_STRING)" -l "$(XORG_MAN_PAGE)" \
-s "$(LIB_MAN_SUFFIX)" -p $(XCBPROTO_XCBPYTHONDIR) \ -s "$(LIB_MAN_SUFFIX)" -p $(XCBPROTO_XCBPYTHONDIR) \
$(C_CLIENT_PY_EXTRA_ARGS) \
$(XCBPROTO_XCBINCLUDEDIR)/$(@:.c=.xml) $(XCBPROTO_XCBINCLUDEDIR)/$(@:.c=.xml)
$(BUILT_MAN_PAGES): $(EXTSOURCES) $(BUILT_MAN_PAGES): $(EXTSOURCES)

File diff suppressed because it is too large Load Diff

142
src/xcb.h
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
@ -166,18 +142,6 @@ typedef struct {
uint32_t full_sequence; /**< full sequence */ uint32_t full_sequence; /**< full sequence */
} xcb_generic_event_t; } xcb_generic_event_t;
/**
* @brief Raw Generic event.
*
* A generic event structure as used on the wire, i.e., without the full_sequence field
*/
typedef struct {
uint8_t response_type; /**< Type of the response */
uint8_t pad0; /**< Padding */
uint16_t sequence; /**< Sequence number */
uint32_t pad[7]; /**< Padding */
} xcb_raw_generic_event_t;
/** /**
* @brief GE event * @brief GE event
* *
@ -261,7 +225,7 @@ typedef struct xcb_auth_info_t {
/** /**
* @brief Forces any buffered output to be written to the server. * @brief Forces any buffered output to be written to the server.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @return > @c 0 on success, <= @c 0 otherwise. * @return > @c 0 on success, <= @c 0 otherwise.
* *
* Forces any buffered output to be written to the server. Blocks * Forces any buffered output to be written to the server. Blocks
@ -271,7 +235,7 @@ int xcb_flush(xcb_connection_t *c);
/** /**
* @brief Returns the maximum request length that this server accepts. * @brief Returns the maximum request length that this server accepts.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @return The maximum request length field. * @return The maximum request length field.
* *
* In the absence of the BIG-REQUESTS extension, returns the * In the absence of the BIG-REQUESTS extension, returns the
@ -288,7 +252,7 @@ uint32_t xcb_get_maximum_request_length(xcb_connection_t *c);
/** /**
* @brief Prefetch the maximum request length without blocking. * @brief Prefetch the maximum request length without blocking.
* @param c The connection to the X server. * @param c: The connection to the X server.
* *
* Without blocking, does as much work as possible toward computing * Without blocking, does as much work as possible toward computing
* the maximum request length accepted by the X server. * the maximum request length accepted by the X server.
@ -310,7 +274,7 @@ void xcb_prefetch_maximum_request_length(xcb_connection_t *c);
/** /**
* @brief Returns the next event or error from the server. * @brief Returns the next event or error from the server.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @return The next event from the server. * @return The next event from the server.
* *
* Returns the next event or error from the server, or returns null in * Returns the next event or error from the server, or returns null in
@ -321,7 +285,7 @@ xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c);
/** /**
* @brief Returns the next event or error from the server. * @brief Returns the next event or error from the server.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @return The next event from the server. * @return The next event from the server.
* *
* Returns the next event or error from the server, if one is * Returns the next event or error from the server, if one is
@ -334,7 +298,7 @@ xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c);
/** /**
* @brief Returns the next event without reading from the connection. * @brief Returns the next event without reading from the connection.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @return The next already queued event from the server. * @return The next already queued event from the server.
* *
* This is a version of xcb_poll_for_event that only examines the * This is a version of xcb_poll_for_event that only examines the
@ -382,8 +346,8 @@ void xcb_unregister_for_special_event(xcb_connection_t *c,
/** /**
* @brief Return the error for a request, or NULL if none can ever arrive. * @brief Return the error for a request, or NULL if none can ever arrive.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param cookie The request cookie. * @param cookie: The request cookie.
* @return The error for the request, or NULL if none can ever arrive. * @return The error for the request, or NULL if none can ever arrive.
* *
* The xcb_void_cookie_t cookie supplied to this function must have resulted * The xcb_void_cookie_t cookie supplied to this function must have resulted
@ -400,8 +364,8 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
/** /**
* @brief Discards the reply for a request. * @brief Discards the reply for a request.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param sequence The request sequence number from a cookie. * @param sequence: The request sequence number from a cookie.
* *
* Discards the reply for a request. Additionally, any error generated * Discards the reply for a request. Additionally, any error generated
* by the request is also discarded (unless it was an _unchecked request * by the request is also discarded (unless it was an _unchecked request
@ -416,8 +380,8 @@ void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence);
/** /**
* @brief Discards the reply for a request, given by a 64bit sequence number * @brief Discards the reply for a request, given by a 64bit sequence number
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param sequence 64-bit sequence number as returned by xcb_send_request64(). * @param sequence: 64-bit sequence number as returned by xcb_send_request64().
* *
* Discards the reply for a request. Additionally, any error generated * Discards the reply for a request. Additionally, any error generated
* by the request is also discarded (unless it was an _unchecked request * by the request is also discarded (unless it was an _unchecked request
@ -439,8 +403,8 @@ void xcb_discard_reply64(xcb_connection_t *c, uint64_t sequence);
/** /**
* @brief Caches reply information from QueryExtension requests. * @brief Caches reply information from QueryExtension requests.
* @param c The connection. * @param c: The connection.
* @param ext The extension data. * @param ext: The extension data.
* @return A pointer to the xcb_query_extension_reply_t for the extension. * @return A pointer to the xcb_query_extension_reply_t for the extension.
* *
* This function is the primary interface to the "extension cache", * This function is the primary interface to the "extension cache",
@ -457,8 +421,8 @@ const struct xcb_query_extension_reply_t *xcb_get_extension_data(xcb_connection_
/** /**
* @brief Prefetch of extension data into the extension cache * @brief Prefetch of extension data into the extension cache
* @param c The connection. * @param c: The connection.
* @param ext The extension data. * @param ext: The extension data.
* *
* This function allows a "prefetch" of extension data into the * This function allows a "prefetch" of extension data into the
* extension cache. Invoking the function may cause a call to * extension cache. Invoking the function may cause a call to
@ -473,7 +437,7 @@ void xcb_prefetch_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
/** /**
* @brief Access the data returned by the server. * @brief Access the data returned by the server.
* @param c The connection. * @param c: The connection.
* @return A pointer to an xcb_setup_t structure. * @return A pointer to an xcb_setup_t structure.
* *
* Accessor for the data returned by the server when the xcb_connection_t * Accessor for the data returned by the server when the xcb_connection_t
@ -489,23 +453,21 @@ 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);
/** /**
* @brief Access the file descriptor of the connection. * @brief Access the file descriptor of the connection.
* @param c The connection. * @param c: The connection.
* @return The file descriptor. * @return The file descriptor.
* *
* 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);
/** /**
* @brief Test whether the connection has shut down due to a fatal error. * @brief Test whether the connection has shut down due to a fatal error.
* @param c The connection. * @param c: The connection.
* @return > 0 if the connection is in an error state; 0 otherwise. * @return > 0 if the connection is in an error state; 0 otherwise.
* *
* Some errors that occur in the context of an xcb_connection_t * Some errors that occur in the context of an xcb_connection_t
@ -521,13 +483,12 @@ 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);
/** /**
* @brief Connects to the X server. * @brief Connects to the X server.
* @param fd The file descriptor. * @param fd: The file descriptor.
* @param auth_info Authentication data. * @param auth_info: Authentication data.
* @return A newly allocated xcb_connection_t structure. * @return A newly allocated xcb_connection_t structure.
* *
* Connects to an X server, given the open socket @p fd and the * Connects to an X server, given the open socket @p fd and the
@ -545,7 +506,7 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info);
/** /**
* @brief Closes the connection. * @brief Closes the connection.
* @param c The connection. * @param c: The connection.
* *
* Closes the file descriptor and frees all memory associated with the * Closes the file descriptor and frees all memory associated with the
* connection @c c. If @p c is @c NULL, nothing is done. * connection @c c. If @p c is @c NULL, nothing is done.
@ -557,10 +518,10 @@ void xcb_disconnect(xcb_connection_t *c);
/** /**
* @brief Parses a display string name in the form documented by X(7x). * @brief Parses a display string name in the form documented by X(7x).
* @param name The name of the display. * @param name: The name of the display.
* @param host A pointer to a malloc'd copy of the hostname. * @param host: A pointer to a malloc'd copy of the hostname.
* @param display A pointer to the display number. * @param display: A pointer to the display number.
* @param screen A pointer to the screen number. * @param screen: A pointer to the screen number.
* @return 0 on failure, non 0 otherwise. * @return 0 on failure, non 0 otherwise.
* *
* Parses the display string name @p display_name in the form * Parses the display string name @p display_name in the form
@ -576,8 +537,8 @@ int xcb_parse_display(const char *name, char **host, int *display, int *screen);
/** /**
* @brief Connects to the X server. * @brief Connects to the X server.
* @param displayname The name of the display. * @param displayname: The name of the display.
* @param screenp A pointer to a preferred screen number. * @param screenp: A pointer to a preferred screen number.
* @return A newly allocated xcb_connection_t structure. * @return A newly allocated xcb_connection_t structure.
* *
* Connects to the X server specified by @p displayname. If @p * Connects to the X server specified by @p displayname. If @p
@ -595,9 +556,9 @@ xcb_connection_t *xcb_connect(const char *displayname, int *screenp);
/** /**
* @brief Connects to the X server, using an authorization information. * @brief Connects to the X server, using an authorization information.
* @param display The name of the display. * @param display: The name of the display.
* @param auth The authorization information. * @param auth: The authorization information.
* @param screen A pointer to a preferred screen number. * @param screen: A pointer to a preferred screen number.
* @return A newly allocated xcb_connection_t structure. * @return A newly allocated xcb_connection_t structure.
* *
* Connects to the X server specified by @p displayname, using the * Connects to the X server specified by @p displayname, using the
@ -617,8 +578,8 @@ 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 +587,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 */
@ -65,26 +64,6 @@ typedef struct {
uint16_t length; uint16_t length;
} xcb_setup_generic_t; } xcb_setup_generic_t;
static const xcb_setup_t xcb_error_setup = {
0, /* status: failed (but we wouldn't have a xcb_setup_t in this case) */
0, /* pad0 */
0, 0, /* protocol version, should be 11.0, but isn't */
0, /* length, invalid value */
0, /* release_number */
0, 0, /* resource_id_{base,mask} */
0, /* motion_buffer_size */
0, /* vendor_len */
0, /* maximum_request_length */
0, /* roots_len */
0, /* pixmap_formats_len */
0, /* image_byte_order */
0, /* bitmap_format_bit_order */
0, /* bitmap_format_scanline_unit */
0, /* bitmap_format_scanline_pad */
0, 0, /* {min,max}_keycode */
{ 0, 0, 0, 0 } /* pad1 */
};
/* Keep this list in sync with is_static_error_conn()! */ /* Keep this list in sync with is_static_error_conn()! */
static const int xcb_con_error = XCB_CONN_ERROR; static const int xcb_con_error = XCB_CONN_ERROR;
static const int xcb_con_closed_mem_er = XCB_CONN_CLOSED_MEM_INSUFFICIENT; static const int xcb_con_closed_mem_er = XCB_CONN_CLOSED_MEM_INSUFFICIENT;
@ -170,8 +149,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 +174,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 +181,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 +191,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 +259,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;
} }
@ -331,15 +288,15 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count)
const xcb_setup_t *xcb_get_setup(xcb_connection_t *c) const xcb_setup_t *xcb_get_setup(xcb_connection_t *c)
{ {
if(is_static_error_conn(c)) if(c->has_error)
return &xcb_error_setup; return 0;
/* doesn't need locking because it's never written to. */ /* doesn't need locking because it's never written to. */
return c->setup; return c->setup;
} }
int xcb_get_file_descriptor(xcb_connection_t *c) int xcb_get_file_descriptor(xcb_connection_t *c)
{ {
if(is_static_error_conn(c)) if(c->has_error)
return -1; return -1;
/* doesn't need locking because it's never written to. */ /* doesn't need locking because it's never written to. */
return c->fd; return c->fd;
@ -367,11 +324,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 +357,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 +508,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)
@ -667,8 +661,6 @@ int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply,
assert(reply != 0); assert(reply != 0);
pthread_mutex_lock(&c->iolock); pthread_mutex_lock(&c->iolock);
ret = poll_for_reply(c, widen(c, request), reply, error); ret = poll_for_reply(c, widen(c, request), reply, error);
if(!ret && c->in.reading == 0 && _xcb_in_read(c)) /* _xcb_in_read shuts down the connection on error */
ret = poll_for_reply(c, widen(c, request), reply, error);
pthread_mutex_unlock(&c->iolock); pthread_mutex_unlock(&c->iolock);
return ret; return ret;
} }
@ -686,8 +678,6 @@ int xcb_poll_for_reply64(xcb_connection_t *c, uint64_t request, void **reply, xc
assert(reply != 0); assert(reply != 0);
pthread_mutex_lock(&c->iolock); pthread_mutex_lock(&c->iolock);
ret = poll_for_reply(c, request, reply, error); ret = poll_for_reply(c, request, reply, error);
if(!ret && c->in.reading == 0 && _xcb_in_read(c)) /* _xcb_in_read shuts down the connection on error */
ret = poll_for_reply(c, request, reply, error);
pthread_mutex_unlock(&c->iolock); pthread_mutex_unlock(&c->iolock);
return ret; return ret;
} }
@ -742,16 +732,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);
@ -783,8 +768,6 @@ xcb_generic_event_t *xcb_poll_for_special_event(xcb_connection_t *c,
return 0; return 0;
pthread_mutex_lock(&c->iolock); pthread_mutex_lock(&c->iolock);
event = get_special_event(c, se); event = get_special_event(c, se);
if(!event && c->in.reading == 0 && _xcb_in_read(c)) /* _xcb_in_read shuts down the connection on error */
event = get_special_event(c, se);
pthread_mutex_unlock(&c->iolock); pthread_mutex_unlock(&c->iolock);
return event; return event;
} }
@ -969,20 +952,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 +1007,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 +1033,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"
@ -181,59 +177,15 @@ uint32_t xcb_get_maximum_request_length(xcb_connection_t *c)
return c->out.maximum_request_length.value; return c->out.maximum_request_length.value;
} }
static void close_fds(int *fds, unsigned int num_fds) uint64_t xcb_send_request64(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
{
for (unsigned int index = 0; index < num_fds; index++)
close(fds[index]);
}
static void send_fds(xcb_connection_t *c, int *fds, unsigned int num_fds)
{
#if HAVE_SENDMSG
/* Calling _xcb_out_flush_to() can drop the iolock and wait on a condition
* variable if another thread is currently writing (c->out.writing > 0).
* This call waits for writers to be done and thus _xcb_out_flush_to() will
* do the work itself (in which case we are a writer and
* prepare_socket_request() will wait for us to be done if another threads
* tries to send fds, too). Thanks to this, we can atomically write out FDs.
*/
prepare_socket_request(c);
while (num_fds > 0) {
while (c->out.out_fd.nfd == XCB_MAX_PASS_FD && !c->has_error) {
/* XXX: if c->out.writing > 0, this releases the iolock and
* potentially allows other threads to interfere with their own fds.
*/
_xcb_out_flush_to(c, c->out.request);
if (c->out.out_fd.nfd == XCB_MAX_PASS_FD) {
/* We need some request to send FDs with */
_xcb_out_send_sync(c);
}
}
if (c->has_error)
break;
c->out.out_fd.fd[c->out.out_fd.nfd++] = fds[0];
fds++;
num_fds--;
}
#endif
close_fds(fds, num_fds);
}
uint64_t xcb_send_request_with_fds64(xcb_connection_t *c, int flags, struct iovec *vector,
const xcb_protocol_request_t *req, unsigned int num_fds, int *fds)
{ {
uint64_t request; uint64_t request;
uint32_t prefix[2]; uint32_t prefix[2];
int veclen = req->count; int veclen = req->count;
enum workarounds workaround = WORKAROUND_NONE; enum workarounds workaround = WORKAROUND_NONE;
if(c->has_error) { if(c->has_error)
close_fds(fds, num_fds);
return 0; return 0;
}
assert(c != 0); assert(c != 0);
assert(vector != 0); assert(vector != 0);
@ -252,7 +204,6 @@ uint64_t xcb_send_request_with_fds64(xcb_connection_t *c, int flags, struct iove
const xcb_query_extension_reply_t *extension = xcb_get_extension_data(c, req->ext); const xcb_query_extension_reply_t *extension = xcb_get_extension_data(c, req->ext);
if(!(extension && extension->present)) if(!(extension && extension->present))
{ {
close_fds(fds, num_fds);
_xcb_conn_shutdown(c, XCB_CONN_CLOSED_EXT_NOTSUPPORTED); _xcb_conn_shutdown(c, XCB_CONN_CLOSED_EXT_NOTSUPPORTED);
return 0; return 0;
} }
@ -283,7 +234,6 @@ uint64_t xcb_send_request_with_fds64(xcb_connection_t *c, int flags, struct iove
} }
else if(longlen > xcb_get_maximum_request_length(c)) else if(longlen > xcb_get_maximum_request_length(c))
{ {
close_fds(fds, num_fds);
_xcb_conn_shutdown(c, XCB_CONN_CLOSED_REQ_LEN_EXCEED); _xcb_conn_shutdown(c, XCB_CONN_CLOSED_REQ_LEN_EXCEED);
return 0; /* server can't take this; maybe need BIGREQUESTS? */ return 0; /* server can't take this; maybe need BIGREQUESTS? */
} }
@ -314,11 +264,6 @@ uint64_t xcb_send_request_with_fds64(xcb_connection_t *c, int flags, struct iove
/* get a sequence number and arrange for delivery. */ /* get a sequence number and arrange for delivery. */
pthread_mutex_lock(&c->iolock); pthread_mutex_lock(&c->iolock);
/* send FDs before establishing a good request number, because this might
* call send_sync(), too
*/
send_fds(c, fds, num_fds);
prepare_socket_request(c); prepare_socket_request(c);
/* send GetInputFocus (sync_req) when 64k-2 requests have been sent without /* send GetInputFocus (sync_req) when 64k-2 requests have been sent without
@ -327,7 +272,7 @@ uint64_t xcb_send_request_with_fds64(xcb_connection_t *c, int flags, struct iove
* applications see sequence 0 as that is used to indicate * applications see sequence 0 as that is used to indicate
* an error in sending the request * an error in sending the request
*/ */
while ((req->isvoid && c->out.request == c->in.request_expected + (1 << 16) - 2) || while ((req->isvoid && c->out.request == c->in.request_expected + (1 << 16) - 2) ||
(unsigned int) (c->out.request + 1) == 0) (unsigned int) (c->out.request + 1) == 0)
{ {
@ -341,18 +286,6 @@ uint64_t xcb_send_request_with_fds64(xcb_connection_t *c, int flags, struct iove
return request; return request;
} }
/* request number are actually uint64_t internally but keep API compat with unsigned int */
unsigned int xcb_send_request_with_fds(xcb_connection_t *c, int flags, struct iovec *vector,
const xcb_protocol_request_t *req, unsigned int num_fds, int *fds)
{
return xcb_send_request_with_fds64(c, flags, vector, req, num_fds, fds);
}
uint64_t xcb_send_request64(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
{
return xcb_send_request_with_fds64(c, flags, vector, req, 0, NULL);
}
/* request number are actually uint64_t internally but keep API compat with unsigned int */ /* request number are actually uint64_t internally but keep API compat with unsigned int */
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req) unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
{ {
@ -362,15 +295,19 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
void void
xcb_send_fd(xcb_connection_t *c, int fd) xcb_send_fd(xcb_connection_t *c, int fd)
{ {
int fds[1] = { fd }; #if HAVE_SENDMSG
if (c->has_error)
if (c->has_error) {
close(fd);
return; return;
}
pthread_mutex_lock(&c->iolock); pthread_mutex_lock(&c->iolock);
send_fds(c, &fds[0], 1); while (c->out.out_fd.nfd == XCB_MAX_PASS_FD) {
_xcb_out_flush_to(c, c->out.request);
if (c->has_error)
break;
}
if (!c->has_error)
c->out.out_fd.fd[c->out.out_fd.nfd++] = fd;
pthread_mutex_unlock(&c->iolock); pthread_mutex_unlock(&c->iolock);
#endif
} }
int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), void *closure, int flags, uint64_t *sent) int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), void *closure, int flags, uint64_t *sent)
@ -391,14 +328,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 +378,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 +388,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 +398,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,39 @@ 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);
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 +276,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 +387,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 +413,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;
} }
@ -465,8 +428,6 @@ static int _xcb_open_unix(char *protocol, const char *file)
{ {
int fd; int fd;
struct sockaddr_un addr; struct sockaddr_un addr;
socklen_t len = sizeof(int);
int val;
if (protocol && strcmp("unix",protocol)) if (protocol && strcmp("unix",protocol))
return -1; return -1;
@ -479,11 +440,6 @@ static int _xcb_open_unix(char *protocol, const char *file)
fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0); fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0);
if(fd == -1) if(fd == -1)
return -1; return -1;
if(getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &len) == 0 && val < 64 * 1024)
{
val = 64 * 1024;
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, sizeof(int));
}
if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
close(fd); close(fd);
return -1; return -1;
@ -559,8 +515,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

@ -60,21 +60,21 @@ enum xcb_send_request_flags_t {
/** /**
* @brief Send a request to the server. * @brief Send a request to the server.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param flags A combination of flags from the xcb_send_request_flags_t enumeration. * @param flags: A combination of flags from the xcb_send_request_flags_t enumeration.
* @param vector Data to send; must have two iovecs before start for internal use. * @param vector: Data to send; must have two iovecs before start for internal use.
* @param request Information about the request to be sent. * @param request: Information about the request to be sent.
* @return The request's sequence number on success, 0 otherwise. * @return The request's sequence number on success, 0 otherwise.
* *
* This function sends a new request to the X server. The data of the request is * This function sends a new request to the X server. The data of the request is
* given as an array of @c iovecs in the @p vector argument. The length of that * given as an array of @c iovecs in the @p vector argument. The length of that
* array and the necessary management information are given in the @p request * array and the neccessary management information are given in the @p request
* argument. * argument.
* *
* When this function returns, the request might or might not be sent already. * When this function returns, the request might or might not be sent already.
* Use xcb_flush() to make sure that it really was sent. * Use xcb_flush() to make sure that it really was sent.
* *
* Please note that this function is not the preferred way for sending requests. * Please note that this function is not the prefered way for sending requests.
* It's better to use the generated wrapper functions. * It's better to use the generated wrapper functions.
* *
* Please note that xcb might use index -1 and -2 of the @p vector array internally, * Please note that xcb might use index -1 and -2 of the @p vector array internally,
@ -82,54 +82,23 @@ enum xcb_send_request_flags_t {
*/ */
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request); unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request);
/**
* @brief Send a request to the server.
* @param c The connection to the X server.
* @param flags A combination of flags from the xcb_send_request_flags_t enumeration.
* @param vector Data to send; must have two iovecs before start for internal use.
* @param request Information about the request to be sent.
* @param num_fds Number of additional file descriptors to send to the server
* @param fds Additional file descriptors that should be send to the server.
* @return The request's sequence number on success, 0 otherwise.
*
* This function sends a new request to the X server. The data of the request is
* given as an array of @c iovecs in the @p vector argument. The length of that
* array and the necessary management information are given in the @p request
* argument.
*
* If @p num_fds is non-zero, @p fds points to an array of file descriptors that
* will be sent to the X server along with this request. After this function
* returns, all file descriptors sent are owned by xcb and will be closed
* eventually.
*
* When this function returns, the request might or might not be sent already.
* Use xcb_flush() to make sure that it really was sent.
*
* Please note that this function is not the preferred way for sending requests.
*
* Please note that xcb might use index -1 and -2 of the @p vector array internally,
* so they must be valid!
*/
unsigned int xcb_send_request_with_fds(xcb_connection_t *c, int flags, struct iovec *vector,
const xcb_protocol_request_t *request, unsigned int num_fds, int *fds);
/** /**
* @brief Send a request to the server, with 64-bit sequence number returned. * @brief Send a request to the server, with 64-bit sequence number returned.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param flags A combination of flags from the xcb_send_request_flags_t enumeration. * @param flags: A combination of flags from the xcb_send_request_flags_t enumeration.
* @param vector Data to send; must have two iovecs before start for internal use. * @param vector: Data to send; must have two iovecs before start for internal use.
* @param request Information about the request to be sent. * @param request: Information about the request to be sent.
* @return The request's sequence number on success, 0 otherwise. * @return The request's sequence number on success, 0 otherwise.
* *
* This function sends a new request to the X server. The data of the request is * This function sends a new request to the X server. The data of the request is
* given as an array of @c iovecs in the @p vector argument. The length of that * given as an array of @c iovecs in the @p vector argument. The length of that
* array and the necessary management information are given in the @p request * array and the neccessary management information are given in the @p request
* argument. * argument.
* *
* When this function returns, the request might or might not be sent already. * When this function returns, the request might or might not be sent already.
* Use xcb_flush() to make sure that it really was sent. * Use xcb_flush() to make sure that it really was sent.
* *
* Please note that this function is not the preferred way for sending requests. * Please note that this function is not the prefered way for sending requests.
* It's better to use the generated wrapper functions. * It's better to use the generated wrapper functions.
* *
* Please note that xcb might use index -1 and -2 of the @p vector array internally, * Please note that xcb might use index -1 and -2 of the @p vector array internally,
@ -137,60 +106,28 @@ unsigned int xcb_send_request_with_fds(xcb_connection_t *c, int flags, struct io
*/ */
uint64_t xcb_send_request64(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request); uint64_t xcb_send_request64(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request);
/**
* @brief Send a request to the server, with 64-bit sequence number returned.
* @param c The connection to the X server.
* @param flags A combination of flags from the xcb_send_request_flags_t enumeration.
* @param vector Data to send; must have two iovecs before start for internal use.
* @param request Information about the request to be sent.
* @param num_fds Number of additional file descriptors to send to the server
* @param fds Additional file descriptors that should be send to the server.
* @return The request's sequence number on success, 0 otherwise.
*
* This function sends a new request to the X server. The data of the request is
* given as an array of @c iovecs in the @p vector argument. The length of that
* array and the necessary management information are given in the @p request
* argument.
*
* If @p num_fds is non-zero, @p fds points to an array of file descriptors that
* will be sent to the X server along with this request. After this function
* returns, all file descriptors sent are owned by xcb and will be closed
* eventually.
*
* When this function returns, the request might or might not be sent already.
* Use xcb_flush() to make sure that it really was sent.
*
* Please note that this function is not the preferred way for sending requests.
* It's better to use the generated wrapper functions.
*
* Please note that xcb might use index -1 and -2 of the @p vector array internally,
* so they must be valid!
*/
uint64_t xcb_send_request_with_fds64(xcb_connection_t *c, int flags, struct iovec *vector,
const xcb_protocol_request_t *request, unsigned int num_fds, int *fds);
/** /**
* @brief Send a file descriptor to the server in the next call to xcb_send_request. * @brief Send a file descriptor to the server in the next call to xcb_send_request.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param fd The file descriptor to send. * @param fd: The file descriptor to send.
* *
* After this function returns, the file descriptor given is owned by xcb and * After this function returns, the file descriptor given is owned by xcb and
* will be closed eventually. * will be closed eventually.
* *
* @deprecated This function cannot be used in a thread-safe way. Two threads * FIXME: How the heck is this supposed to work in a thread-safe way? There is a
* that run xcb_send_fd(); xcb_send_request(); could mix up their file * race between two threads doing xcb_send_fd(); xcb_send_request(); at the same
* descriptors. Instead, xcb_send_request_with_fds() should be used. * time.
*/ */
void xcb_send_fd(xcb_connection_t *c, int fd); void xcb_send_fd(xcb_connection_t *c, int fd);
/** /**
* @brief Take over the write side of the socket * @brief Take over the write side of the socket
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param return_socket Callback function that will be called when xcb wants * @param return_socket: Callback function that will be called when xcb wants
* to use the socket again. * to use the socket again.
* @param closure Argument to the callback function. * @param closure: Argument to the callback function.
* @param flags A combination of flags from the xcb_send_request_flags_t enumeration. * @param flags: A combination of flags from the xcb_send_request_flags_t enumeration.
* @param sent Location to the sequence number of the last sequence request. * @param sent: Location to the sequence number of the last sequence request.
* Must not be NULL. * Must not be NULL.
* @return 1 on success, else 0. * @return 1 on success, else 0.
* *
@ -214,10 +151,10 @@ int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), v
/** /**
* @brief Send raw data to the X server. * @brief Send raw data to the X server.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param vector Array of data to be sent. * @param vector: Array of data to be sent.
* @param count Number of entries in @p vector. * @param count: Number of entries in @p vector.
* @param requests Number of requests that are being sent. * @param requests: Number of requests that are being sent.
* @return 1 on success, else 0. * @return 1 on success, else 0.
* *
* You must own the write-side of the socket (you've called * You must own the write-side of the socket (you've called
@ -238,9 +175,9 @@ int xcb_writev(xcb_connection_t *c, struct iovec *vector, int count, uint64_t re
/** /**
* @brief Wait for the reply of a given request. * @brief Wait for the reply of a given request.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param request Sequence number of the request as returned by xcb_send_request(). * @param request: Sequence number of the request as returned by xcb_send_request().
* @param e Location to store errors in, or NULL. Ignored for unchecked requests. * @param e: Location to store errors in, or NULL. Ignored for unchecked requests.
* *
* Returns the reply to the given request or returns null in the event of * Returns the reply to the given request or returns null in the event of
* errors. Blocks until the reply or error for the request arrives, or an I/O * errors. Blocks until the reply or error for the request arrives, or an I/O
@ -250,9 +187,9 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_
/** /**
* @brief Wait for the reply of a given request, with 64-bit sequence number * @brief Wait for the reply of a given request, with 64-bit sequence number
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param request 64-bit sequence number of the request as returned by xcb_send_request64(). * @param request: 64-bit sequence number of the request as returned by xcb_send_request64().
* @param e Location to store errors in, or NULL. Ignored for unchecked requests. * @param e: Location to store errors in, or NULL. Ignored for unchecked requests.
* *
* Returns the reply to the given request or returns null in the event of * Returns the reply to the given request or returns null in the event of
* errors. Blocks until the reply or error for the request arrives, or an I/O * errors. Blocks until the reply or error for the request arrives, or an I/O
@ -265,10 +202,10 @@ void *xcb_wait_for_reply64(xcb_connection_t *c, uint64_t request, xcb_generic_er
/** /**
* @brief Poll for the reply of a given request. * @brief Poll for the reply of a given request.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param request Sequence number of the request as returned by xcb_send_request(). * @param request: Sequence number of the request as returned by xcb_send_request().
* @param reply Location to store the reply in, must not be NULL. * @param reply: Location to store the reply in, must not be NULL.
* @param error Location to store errors in, or NULL. Ignored for unchecked requests. * @param e: Location to store errors in, or NULL. Ignored for unchecked requests.
* @return 1 when the reply to the request was returned, else 0. * @return 1 when the reply to the request was returned, else 0.
* *
* Checks if the reply to the given request already received. Does not block. * Checks if the reply to the given request already received. Does not block.
@ -277,10 +214,10 @@ int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply,
/** /**
* @brief Poll for the reply of a given request, with 64-bit sequence number. * @brief Poll for the reply of a given request, with 64-bit sequence number.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param request 64-bit sequence number of the request as returned by xcb_send_request(). * @param request: 64-bit sequence number of the request as returned by xcb_send_request().
* @param reply Location to store the reply in, must not be NULL. * @param reply: Location to store the reply in, must not be NULL.
* @param error Location to store errors in, or NULL. Ignored for unchecked requests. * @param e: Location to store errors in, or NULL. Ignored for unchecked requests.
* @return 1 when the reply to the request was returned, else 0. * @return 1 when the reply to the request was returned, else 0.
* *
* Checks if the reply to the given request already received. Does not block. * Checks if the reply to the given request already received. Does not block.
@ -292,30 +229,27 @@ int xcb_poll_for_reply64(xcb_connection_t *c, uint64_t request, void **reply, xc
/** /**
* @brief Don't use this, only needed by the generated code. * @brief Don't use this, only needed by the generated code.
* @param c The connection to the X server. * @param c: The connection to the X server.
* @param reply A reply that was received from the server * @param reply: A reply that was received from the server
* @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);
/* xcb_util.c */ /* xcb_util.c */
/** /**
* @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);
/** /**
* @param list The base of an array * @param list: The base of an array
* @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

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

View File

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

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 DPMS Name: XCB DPMS
Description: XCB DPMS Extension Description: XCB DPMS Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-dpms Libs: -L${libdir} -lxcb-dpms
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB DRI2 Name: XCB DRI2
Description: XCB DRI2 Extension Description: XCB DRI2 Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-dri2 Libs: -L${libdir} -lxcb-dri2
Cflags: -I${includedir} Cflags: -I${includedir}

View File

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

View File

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

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB GLX Name: XCB GLX
Description: XCB GLX Extension Description: XCB GLX Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-glx Libs: -L${libdir} -lxcb-glx
Cflags: -I${includedir} 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: xcb xcb-randr xcb-xfixes xcb-sync
Libs: -L${libdir} -lxcb-present Libs: -L${libdir} -lxcb-present
Cflags: -I${includedir} Cflags: -I${includedir}

View File

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

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Record Name: XCB Record
Description: XCB Record Extension Description: XCB Record Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-record Libs: -L${libdir} -lxcb-record
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Render Name: XCB Render
Description: XCB Render Extension Description: XCB Render Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-render Libs: -L${libdir} -lxcb-render
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Res Name: XCB Res
Description: XCB X-Resource Extension Description: XCB X-Resource Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-res Libs: -L${libdir} -lxcb-res
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Screensaver Name: XCB Screensaver
Description: XCB Screensaver Extension Description: XCB Screensaver Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-screensaver Libs: -L${libdir} -lxcb-screensaver
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Shape Name: XCB Shape
Description: XCB Shape Extension Description: XCB Shape Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-shape Libs: -L${libdir} -lxcb-shape
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Shm Name: XCB Shm
Description: XCB Shm Extension Description: XCB Shm Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-shm Libs: -L${libdir} -lxcb-shm
Cflags: -I${includedir} Cflags: -I${includedir}

View File

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

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Xevie Name: XCB Xevie
Description: XCB Xevie Extension Description: XCB Xevie Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-xevie Libs: -L${libdir} -lxcb-xevie
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XFree86-DRI Name: XCB XFree86-DRI
Description: XCB XFree86-DRI Extension Description: XCB XFree86-DRI Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-xf86dri Libs: -L${libdir} -lxcb-xf86dri
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XFixes Name: XCB XFixes
Description: XCB XFixes Extension Description: XCB XFixes Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb xcb-render xcb-shape Requires: xcb xcb-render xcb-shape
Libs: -L${libdir} -lxcb-xfixes Libs: -L${libdir} -lxcb-xfixes
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Xinerama Name: XCB Xinerama
Description: XCB Xinerama Extension Description: XCB Xinerama Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-xinerama Libs: -L${libdir} -lxcb-xinerama
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XInput Name: XCB XInput
Description: XCB XInput Extension (EXPERIMENTAL) Description: XCB XInput Extension (EXPERIMENTAL)
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb xcb-xfixes Requires: xcb xcb-xfixes
Libs: -L${libdir} -lxcb-xinput Libs: -L${libdir} -lxcb-xinput
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XKB Name: XCB XKB
Description: XCB Keyboard Extension (EXPERIMENTAL) Description: XCB Keyboard Extension (EXPERIMENTAL)
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-xkb Libs: -L${libdir} -lxcb-xkb
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Xprint Name: XCB Xprint
Description: XCB Xprint Extension Description: XCB Xprint Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-xprint Libs: -L${libdir} -lxcb-xprint
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB SELinux Name: XCB SELinux
Description: XCB SELinux Extension Description: XCB SELinux Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-xselinux Libs: -L${libdir} -lxcb-xselinux
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XTEST Name: XCB XTEST
Description: XCB XTEST Extension Description: XCB XTEST Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb Requires: xcb
Libs: -L${libdir} -lxcb-xtest Libs: -L${libdir} -lxcb-xtest
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB Xv Name: XCB Xv
Description: XCB Xv Extension Description: XCB Xv Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb xcb-shm Requires: xcb xcb-shm
Libs: -L${libdir} -lxcb-xv Libs: -L${libdir} -lxcb-xv
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -6,6 +6,6 @@ includedir=@includedir@
Name: XCB XvMC Name: XCB XvMC
Description: XCB XvMC Extension Description: XCB XvMC Extension
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Requires.private: xcb xcb-xv Requires: xcb xcb-xv
Libs: -L${libdir} -lxcb-xvmc Libs: -L${libdir} -lxcb-xvmc
Cflags: -I${includedir} Cflags: -I${includedir}