Compare commits
153 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
93e6da2e2e | ||
|
6a7661f60a | ||
|
daf2c53976 | ||
|
021e887de9 | ||
|
124690ba63 | ||
|
ebea71700f | ||
|
622152ee42 | ||
|
4574ab269b | ||
|
b78d304531 | ||
|
389f22d1cb | ||
|
86a478032b | ||
|
c268499c30 | ||
|
c671b9b30a | ||
|
3c946010c8 | ||
|
02a7bbed39 | ||
|
18c3f055e7 | ||
|
453115f7ee | ||
|
f11691a098 | ||
|
cc4b93c9cd | ||
|
1519334652 | ||
|
038636786a | ||
|
8935793f1f | ||
|
095255531b | ||
|
ccdef1a8a5 | ||
|
18e109d755 | ||
|
fd04ab24a5 | ||
|
4d1a578dd5 | ||
|
e2a3e80eb8 | ||
|
3333d5bde8 | ||
|
973b510e95 | ||
|
cb8c70f5a6 | ||
|
33f3dbe369 | ||
|
c9513aac2d | ||
|
06e1ef43bb | ||
|
d53ad60d77 | ||
|
e2ee5aabe9 | ||
|
9dcb081708 | ||
|
7d798d3ccb | ||
|
7071b4a13c | ||
|
ee60239b73 | ||
|
3123dfe723 | ||
|
816407655f | ||
|
c2c4a2cd19 | ||
|
ddafdba11f | ||
|
43fbf03e54 | ||
|
233d7b7f1f | ||
|
dc28118747 | ||
|
26396bf156 | ||
|
a503167f75 | ||
|
3c76c0579f | ||
|
bdc3f21a52 | ||
|
068af21cb3 | ||
|
4d678b162b | ||
|
21414e7c44 | ||
|
4b0d9d3868 | ||
|
cd0fba98a2 | ||
|
2ef8655987 | ||
|
4cbcac4eca | ||
|
f01f3c378e | ||
|
704e0a91b1 | ||
|
4b40b44cb6 | ||
|
78c492deaa | ||
|
8f7e4c4e9f | ||
|
f9f4b00aad | ||
|
59e271e15b | ||
|
21324989b7 | ||
|
656c08c542 | ||
|
be1745c8eb | ||
|
58f37377c8 | ||
|
7bac366953 | ||
|
02ff3eadf4 | ||
|
542befe40a | ||
|
8287ebd7b7 | ||
|
bbda345a71 | ||
|
7e0f166579 | ||
|
a3e9821bec | ||
|
c7aa4e682f | ||
|
d10194a321 | ||
|
fad81b6342 | ||
|
f830eb93c9 | ||
|
ee9dfc9a76 | ||
|
0c2c5d50f8 | ||
|
9bce1f72e3 | ||
|
65b298c7ca | ||
|
32a9084546 | ||
|
8740a288ca | ||
|
d34785a34f | ||
|
b11fca06f7 | ||
|
095353ff1a | ||
|
b3516102b4 | ||
|
c03388ff9e | ||
|
7758257567 | ||
|
32a2189183 | ||
|
6e0378ebbf | ||
|
4033d39d4d | ||
|
b15c96f950 | ||
|
c5d923d8ff | ||
|
5b40681c88 | ||
|
f85661c3bc | ||
|
8584c0e095 | ||
|
658fb4a5f0 | ||
|
b15aa6bd4e | ||
|
cc04cfb41b | ||
|
25f9e7e45a | ||
|
bbdf1d133f | ||
|
ff6cb3913b | ||
|
cb621341a6 | ||
|
c49aa98594 | ||
|
a90be9955d | ||
|
f9f925107e | ||
|
17f9bda6c2 | ||
|
c65005e9d0 | ||
|
6872e92582 | ||
|
8bf8b62316 | ||
|
ec435aebd6 | ||
|
89498d1d45 | ||
|
2871d4b1b8 | ||
|
30976e5255 | ||
|
0ab52cbcc6 | ||
|
80341d5df3 | ||
|
86ea6645d9 | ||
|
70d32ce7d8 | ||
|
12d23b934f | ||
|
1b37d6ad3a | ||
|
e3ec1f7463 | ||
|
5353c0216e | ||
|
c6f3fb2529 | ||
|
912cd97a6d | ||
|
422458b663 | ||
|
b1e4a3bbd8 | ||
|
6234225b4b | ||
|
18ff453edd | ||
|
d905b88618 | ||
|
17f6e04493 | ||
|
51a0d57acc | ||
|
4a915c0dba | ||
|
fda1fb4ed4 | ||
|
265d38882c | ||
|
bbca7b82f8 | ||
|
fdb291b414 | ||
|
a7c75be5b1 | ||
|
277ea629de | ||
|
382d306d6c | ||
|
d74d066949 | ||
|
b0e6c2de09 | ||
|
c4e40f646b | ||
|
355d4d6ab9 | ||
|
966fba6ba4 | ||
|
a5e90ae6a1 | ||
|
529e3bfc20 | ||
|
74f552c1b3 | ||
|
23f57ac8bf | ||
|
7f07b57be5 |
|
@ -21,3 +21,8 @@ libtool
|
|||
m4/l*.m4
|
||||
mkinstalldirs
|
||||
stamp-h1
|
||||
ChangeLog
|
||||
INSTALL
|
||||
check-pc-requires.log
|
||||
check-pc-requires.trs
|
||||
test-suite.log
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
# 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
229
INSTALL
|
@ -1,229 +0,0 @@
|
|||
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.
|
||||
|
19
Makefile.am
19
Makefile.am
|
@ -12,6 +12,9 @@ endif
|
|||
if BUILD_DAMAGE
|
||||
pkgconfig_DATA += xcb-damage.pc
|
||||
endif
|
||||
if BUILD_DBE
|
||||
pkgconfig_DATA += xcb-dbe.pc
|
||||
endif
|
||||
if BUILD_DPMS
|
||||
pkgconfig_DATA += xcb-dpms.pc
|
||||
endif
|
||||
|
@ -84,6 +87,9 @@ endif
|
|||
if BUILD_XVMC
|
||||
pkgconfig_DATA += xcb-xvmc.pc
|
||||
endif
|
||||
if BUILD_GE
|
||||
pkgconfig_DATA += xcb-ge.pc
|
||||
endif
|
||||
|
||||
|
||||
AM_TESTS_ENVIRONMENT = \
|
||||
|
@ -96,4 +102,17 @@ tools/README \
|
|||
tools/api_conv.pl \
|
||||
tools/constants \
|
||||
autogen.sh \
|
||||
README.md \
|
||||
$(TESTS)
|
||||
|
||||
MAINTAINERCLEANFILES = ChangeLog INSTALL
|
||||
|
||||
.PHONY: ChangeLog INSTALL
|
||||
|
||||
INSTALL:
|
||||
$(INSTALL_CMD)
|
||||
|
||||
ChangeLog:
|
||||
$(CHANGELOG_CMD)
|
||||
|
||||
dist-hook: ChangeLog INSTALL
|
||||
|
|
52
NEWS
52
NEWS
|
@ -1,3 +1,55 @@
|
|||
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)
|
||||
===========================
|
||||
* Expose 64-bit sequence numbers for XLib
|
||||
* Fix some hangs related to xcb_wait_for_special_event()
|
||||
|
||||
Release 1.11 (2014-08-01)
|
||||
=========================
|
||||
* Force structures with 64-bit fields to be packed
|
||||
|
|
|
@ -2,7 +2,7 @@ About libxcb
|
|||
============
|
||||
|
||||
libxcb provides an interface to the X Window System protocol, which
|
||||
replaces the current Xlib interface. It has several advantages over
|
||||
replaces the traditional Xlib interface. It has several advantages over
|
||||
Xlib, including:
|
||||
- size: small, simple library, and lower memory footprint
|
||||
- latency hiding: batch several requests and wait for the replies later
|
||||
|
@ -10,27 +10,32 @@ Xlib, including:
|
|||
- proven thread support: transparently access XCB from multiple threads
|
||||
- easy extension implementation: interfaces auto-generated from XML-XCB
|
||||
|
||||
Xlib can also use XCB as a transport layer, allowing software to make
|
||||
Xlib also uses XCB as a transport layer, allowing software to make
|
||||
requests and receive responses with both, which eases porting to XCB.
|
||||
However, client programs, libraries, and toolkits will gain the most
|
||||
benefit from a native XCB port.
|
||||
|
||||
More information about xcb is available from our website:
|
||||
|
||||
Please report any issues you find to the freedesktop.org bug tracker,
|
||||
at:
|
||||
https://xcb.freedesktop.org/
|
||||
|
||||
<https://bugs.freedesktop.org/enter_bug.cgi?product=XCB>
|
||||
Please report any issues you find to the freedesktop.org bug tracker at:
|
||||
|
||||
https://gitlab.freedesktop.org/xorg/lib/libxcb/issues
|
||||
|
||||
Discussion about XCB occurs on the XCB mailing list:
|
||||
|
||||
<mailto:xcb at lists.freedesktop.org>
|
||||
<http://lists.freedesktop.org/mailman/listinfo/xcb>
|
||||
https://lists.freedesktop.org/mailman/listinfo/xcb
|
||||
|
||||
You can obtain the latest development versions of XCB using GIT.
|
||||
For anonymous checkouts, use:
|
||||
You can obtain the latest development versions of XCB using GIT from
|
||||
the libxcb code repository at:
|
||||
|
||||
git clone git://anongit.freedesktop.org/git/xcb/libxcb
|
||||
https://gitlab.freedesktop.org/xorg/lib/libxcb
|
||||
|
||||
For developers, use:
|
||||
For anonymous checkouts, use:
|
||||
|
||||
git clone git+ssh://git.freedesktop.org/git/xcb/libxcb
|
||||
git clone https://gitlab.freedesktop.org/xorg/lib/libxcb.git
|
||||
|
||||
For developers, use:
|
||||
|
||||
git clone git@gitlab.freedesktop.org:xorg/lib/libxcb.git
|
11
autogen.sh
11
autogen.sh
|
@ -1,14 +1,17 @@
|
|||
#! /bin/sh
|
||||
|
||||
srcdir=`dirname $0`
|
||||
srcdir=`dirname "$0"`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
ORIGDIR=`pwd`
|
||||
cd $srcdir
|
||||
cd "$srcdir"
|
||||
|
||||
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
|
||||
$srcdir/configure "$@"
|
||||
exec "$srcdir"/configure "$@"
|
||||
fi
|
||||
|
|
|
@ -23,7 +23,7 @@ for inc in src/*.h; do
|
|||
included=`grep '# *include' $inc |
|
||||
sed -e 's/[^<"]*[<"]//' -e 's/[>"]//' |
|
||||
grep -v 'xcb.h\|xproto.h'`
|
||||
requires=`grep '^Requires:' $pcin`
|
||||
requires=`grep '^Requires.private:' $pcin`
|
||||
missing=""
|
||||
for i in $included; do
|
||||
ibase=`basename $i .h`
|
||||
|
@ -58,7 +58,7 @@ for inc in src/*.h; do
|
|||
*)
|
||||
if [ "$fix" = "y" ]; then
|
||||
echo $package adding dependency on $missing
|
||||
sed -i '/^Requires:/s/$/ '"$missing"'/' $pcin
|
||||
sed -i '/^Requires.private:/s/$/ '"$missing"'/' $pcin
|
||||
else
|
||||
echo $package missing $missing
|
||||
status=1
|
||||
|
|
114
configure.ac
114
configure.ac
|
@ -2,8 +2,8 @@ dnl Process this file with autoconf to produce a configure script.
|
|||
|
||||
# Initialize Autoconf
|
||||
AC_PREREQ([2.60])
|
||||
AC_INIT([libxcb],[1.11],
|
||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=xcb],
|
||||
AC_INIT([libxcb],[1.17.0],
|
||||
[https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues],
|
||||
[libxcb])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
@ -11,13 +11,14 @@ AC_CONFIG_SRCDIR([xcb.pc.in])
|
|||
AC_CONFIG_HEADERS([src/config.h])
|
||||
|
||||
# Initialize Automake
|
||||
AM_INIT_AUTOMAKE([foreign dist-bzip2])
|
||||
AM_PATH_PYTHON([2.6])
|
||||
AM_INIT_AUTOMAKE([foreign dist-xz])
|
||||
AM_PATH_PYTHON([3.0])
|
||||
|
||||
# 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)
|
||||
# to avoid autoconf errors.
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
# Initialize libtool
|
||||
LT_PREREQ([2.2])
|
||||
|
@ -36,7 +37,7 @@ if test x"$HAVE_DOT" = xno; then
|
|||
AC_MSG_WARN([dot not found - doxygen targets will be skipped])
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=yes], [HAVE_CHECK=no])
|
||||
PKG_CHECK_MODULES(CHECK, [check >= 0.9.6], [HAVE_CHECK=yes], [HAVE_CHECK=no])
|
||||
AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes)
|
||||
|
||||
XSLTPROC=no
|
||||
|
@ -50,8 +51,12 @@ fi
|
|||
AC_SUBST(HTML_CHECK_RESULT)
|
||||
|
||||
# Checks for pkg-config packages
|
||||
PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.11)
|
||||
NEEDED="pthread-stubs xau >= 0.99.2"
|
||||
PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.17.0)
|
||||
NEEDED="xau >= 0.99.2"
|
||||
case $host_os in
|
||||
linux*|darwin*|solaris*|dragonfly*|freebsd*|netbsd*) ;;
|
||||
*) NEEDED="$NEEDED pthread-stubs" ;;
|
||||
esac
|
||||
PKG_CHECK_MODULES(NEEDED, $NEEDED)
|
||||
|
||||
have_xdmcp="no"
|
||||
|
@ -86,18 +91,11 @@ XCBPROTO_XCBPYTHONDIR=`$PKG_CONFIG --variable=pythondir xcb-proto`
|
|||
AC_MSG_RESULT($XCBPROTO_XCBPYTHONDIR)
|
||||
AC_SUBST(XCBPROTO_XCBPYTHONDIR)
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_SEARCH_LIBS(getaddrinfo, socket)
|
||||
AC_SEARCH_LIBS(connect, socket)
|
||||
|
||||
AC_ARG_ENABLE(sendfds, AS_HELP_STRING([--disable-sendfds], [Support FD passing (default: auto)]),
|
||||
[sendfds=$enableval], [sendfds=auto])
|
||||
|
||||
case x$sendfds in
|
||||
xauto)
|
||||
AC_SEARCH_LIBS(sendmsg, socket, [sendfds="yes"], [sendfds="no"])
|
||||
;;
|
||||
esac
|
||||
# Find support for sending a message from a socket
|
||||
AC_SEARCH_LIBS(sendmsg, socket, [have_sendmsg="yes"], [have_sendmsg="no"])
|
||||
|
||||
# XPG4v2/UNIX95 added msg_control - check to see if we need to define
|
||||
# _XOPEN_SOURCE to get it (such as on Solaris)
|
||||
|
@ -126,14 +124,14 @@ if test "x$ac_cv_member_struct_msghdr_msg_control" = xno; then
|
|||
AC_CHECK_MEMBER([struct msghdr.msg_control],
|
||||
[AC_DEFINE([_XOPEN_SOURCE], [500],
|
||||
[Defined if needed to expose struct msghdr.msg_control])
|
||||
], [sendfds="no"], [
|
||||
], [have_sendmsg="no"], [
|
||||
#define _XOPEN_SOURCE 500
|
||||
AC_INCLUDES_DEFAULT
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
fi
|
||||
|
||||
case x$sendfds in
|
||||
case x$have_sendmsg in
|
||||
xyes)
|
||||
AC_DEFINE([HAVE_SENDMSG],1,[Define if your platform supports sendmsg])
|
||||
;;
|
||||
|
@ -212,42 +210,47 @@ case $host_os in
|
|||
;;
|
||||
esac
|
||||
|
||||
XCB_EXTENSION(Composite, "yes")
|
||||
XCB_EXTENSION(Damage, "yes")
|
||||
XCB_EXTENSION(DPMS, "yes")
|
||||
XCB_EXTENSION(DRI2, "yes")
|
||||
XCB_EXTENSION(DRI3, "$sendfds")
|
||||
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, "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")
|
||||
dnl Link with winsock for socket functions on MinGW
|
||||
case $host_os in
|
||||
*mingw*)
|
||||
AC_CHECK_LIB([ws2_32],[main])
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto])
|
||||
if test "x$LAUNCHD" = xauto; then
|
||||
unset LAUNCHD
|
||||
AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin])
|
||||
fi
|
||||
XCB_EXTENSION(Composite, yes)
|
||||
XCB_EXTENSION(Damage, yes)
|
||||
XCB_EXTENSION(Dbe, yes)
|
||||
XCB_EXTENSION(DPMS, yes)
|
||||
XCB_EXTENSION(DRI2, yes)
|
||||
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)
|
||||
|
||||
if test "x$LAUNCHD" = xyes ; then
|
||||
AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available])
|
||||
fi
|
||||
AC_ARG_WITH(serverside-support, AS_HELP_STRING([--with-serverside-support], [Build with support for server-side usage of xcb. This is still EXPERIMENTAL! ABI/API may change! (default: no)]), [XCB_SERVERSIDE_SUPPORT=$withval], [XCB_SERVERSIDE_SUPPORT=no])
|
||||
|
||||
AM_CONDITIONAL(XCB_SERVERSIDE_SUPPORT, test "x$XCB_SERVERSIDE_SUPPORT" = "xyes")
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
|
@ -261,9 +264,11 @@ AC_CONFIG_FILES([
|
|||
xcb.pc
|
||||
xcb-composite.pc
|
||||
xcb-damage.pc
|
||||
xcb-dbe.pc
|
||||
xcb-dpms.pc
|
||||
xcb-dri2.pc
|
||||
xcb-dri3.pc
|
||||
xcb-ge.pc
|
||||
xcb-glx.pc
|
||||
xcb-present.pc
|
||||
xcb-randr.pc
|
||||
|
@ -300,7 +305,7 @@ echo " Package: ${PACKAGE_NAME} ${PACKAGE_VERSION}"
|
|||
echo ""
|
||||
echo " Configuration"
|
||||
echo " XDM support.........: ${have_xdmcp}"
|
||||
echo " sendmsg fd passing..: ${sendfds}"
|
||||
echo " sendmsg fd passing..: ${have_sendmsg}"
|
||||
echo " Build unit tests....: ${HAVE_CHECK}"
|
||||
echo " with html results.: ${HTML_CHECK_RESULT}"
|
||||
echo " XCB buffer size.....: ${xcb_queue_buffer_size}"
|
||||
|
@ -308,9 +313,11 @@ echo ""
|
|||
echo " X11 extensions"
|
||||
echo " Composite...........: ${BUILD_COMPOSITE}"
|
||||
echo " Damage..............: ${BUILD_DAMAGE}"
|
||||
echo " Dbe.................: ${BUILD_DBE}"
|
||||
echo " Dpms................: ${BUILD_DPMS}"
|
||||
echo " Dri2................: ${BUILD_DRI2}"
|
||||
echo " Dri3................: ${BUILD_DRI3}"
|
||||
echo " GenericEvent........: ${BUILD_GE}"
|
||||
echo " Glx.................: ${BUILD_GLX}"
|
||||
echo " Randr...............: ${BUILD_RANDR}"
|
||||
echo " Record..............: ${BUILD_RECORD}"
|
||||
|
@ -335,7 +342,6 @@ echo ""
|
|||
echo " Used CFLAGS:"
|
||||
echo " CPPFLAGS............: ${CPPFLAGS}"
|
||||
echo " CFLAGS..............: ${CFLAGS}"
|
||||
echo " Warning CFLAGS......: ${BASE_CFLAGS}"
|
||||
echo ""
|
||||
echo " Installation:"
|
||||
echo " Prefix..............: ${prefix}"
|
||||
|
|
|
@ -2297,9 +2297,7 @@ int main ()
|
|||
values[0] = screen->white_pixel;
|
||||
values[1] =
|
||||
XCB_EVENT_MASK_KEY_RELEASE |
|
||||
XCB_EVENT_MASK_BUTTON_PRESS |
|
||||
XCB_EVENT_MASK_EXPOSURE |
|
||||
XCB_EVENT_MASK_POINTER_MOTION;
|
||||
XCB_EVENT_MASK_EXPOSURE;
|
||||
cookie_window = xcb_create_window_checked (c,
|
||||
screen->root_depth,
|
||||
window, screen->root,
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[wrap-git]
|
||||
url = https://gitea.gigo-games.dk/frederik/libxcb.git
|
||||
revision = HEAD
|
||||
depth = 1
|
23
m4/xcb.m4
23
m4/xcb.m4
|
@ -38,15 +38,32 @@ dnl XCB_EXTENSION(name, default)
|
|||
dnl set the X extension
|
||||
dnl
|
||||
AC_DEFUN([XCB_EXTENSION],
|
||||
[
|
||||
[dnl
|
||||
pushdef([UP], 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,
|
||||
[AS_HELP_STRING([--enable-[]DOWN], [Build XCB $1 Extension (default: $2)])],
|
||||
[AS_HELP_STRING([--enable-[]DOWN],
|
||||
[Build XCB $1 Extension (default: ]xcb_defopt[)])],
|
||||
[BUILD_[]UP=$enableval],
|
||||
[BUILD_[]UP=$2])
|
||||
[BUILD_[]UP=xcb_defopt])
|
||||
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"])
|
||||
])
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ void my_example(xcb_connection *conn) {
|
|||
cookie = xcb_intern_atom(conn, 0, strlen("_NET_WM_NAME"), "_NET_WM_NAME");
|
||||
/* ... do other work here if possible ... */
|
||||
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);
|
||||
}
|
||||
|
@ -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");
|
||||
/* ... do other work here if possible ... */
|
||||
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);
|
||||
} else {
|
||||
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");
|
||||
/* ... do other work here if possible ... */
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
bigreq.*
|
||||
composite.*
|
||||
damage.*
|
||||
dbe.*
|
||||
dpms.*
|
||||
dri2.*
|
||||
dri3.*
|
||||
ge.*
|
||||
glx.*
|
||||
present.*
|
||||
randr.*
|
||||
|
|
|
@ -40,6 +40,14 @@ libxcb_damage_la_LIBADD = $(XCB_LIBS)
|
|||
nodist_libxcb_damage_la_SOURCES = damage.c damage.h
|
||||
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
|
||||
if BUILD_DPMS
|
||||
lib_LTLIBRARIES += libxcb-dpms.la
|
||||
|
@ -59,7 +67,7 @@ endif
|
|||
EXTSOURCES += dri3.c
|
||||
if BUILD_DRI3
|
||||
lib_LTLIBRARIES += libxcb-dri3.la
|
||||
libxcb_dri3_la_LDFLAGS = -version-info 0:0:0 -no-undefined @lt_enable_auto_import@
|
||||
libxcb_dri3_la_LDFLAGS = -version-info 1:0:1 -no-undefined @lt_enable_auto_import@
|
||||
libxcb_dri3_la_LIBADD = $(XCB_LIBS)
|
||||
nodist_libxcb_dri3_la_SOURCES = dri3.c dri3.h
|
||||
endif
|
||||
|
@ -232,6 +240,13 @@ libxcb_xvmc_la_LIBADD = $(XCB_LIBS)
|
|||
nodist_libxcb_xvmc_la_SOURCES = xvmc.c xvmc.h
|
||||
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)
|
||||
xcbinclude_HEADERS = xcb.h xcbext.h
|
||||
|
@ -248,9 +263,15 @@ libman_DATA = $(BUILT_MAN_PAGES)
|
|||
BUILT_SOURCES = $(EXTSOURCES) $(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)
|
||||
$(AM_V_GEN)$(PYTHON) $(srcdir)/c_client.py -c "$(PACKAGE_STRING)" -l "$(XORG_MAN_PAGE)" \
|
||||
-s "$(LIB_MAN_SUFFIX)" -p $(XCBPROTO_XCBPYTHONDIR) \
|
||||
$(C_CLIENT_PY_EXTRA_ARGS) \
|
||||
$(XCBPROTO_XCBINCLUDEDIR)/$(@:.c=.xml)
|
||||
|
||||
$(BUILT_MAN_PAGES): $(EXTSOURCES)
|
||||
|
|
1052
src/c_client.py
1052
src/c_client.py
File diff suppressed because it is too large
Load Diff
158
src/xcb.h
158
src/xcb.h
|
@ -29,11 +29,7 @@
|
|||
#define __XCB_H__
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(__solaris__)
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/uio.h>
|
||||
|
@ -51,7 +47,35 @@ extern "C" {
|
|||
* @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__))
|
||||
#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
|
||||
|
@ -142,6 +166,18 @@ typedef struct {
|
|||
uint32_t full_sequence; /**< full sequence */
|
||||
} 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
|
||||
*
|
||||
|
@ -225,7 +261,7 @@ typedef struct xcb_auth_info_t {
|
|||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* Forces any buffered output to be written to the server. Blocks
|
||||
|
@ -235,7 +271,7 @@ int xcb_flush(xcb_connection_t *c);
|
|||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* In the absence of the BIG-REQUESTS extension, returns the
|
||||
|
@ -252,7 +288,7 @@ uint32_t xcb_get_maximum_request_length(xcb_connection_t *c);
|
|||
|
||||
/**
|
||||
* @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
|
||||
* the maximum request length accepted by the X server.
|
||||
|
@ -274,7 +310,7 @@ void xcb_prefetch_maximum_request_length(xcb_connection_t *c);
|
|||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* Returns the next event or error from the server, or returns null in
|
||||
|
@ -285,7 +321,7 @@ xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c);
|
|||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* Returns the next event or error from the server, if one is
|
||||
|
@ -298,7 +334,7 @@ xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c);
|
|||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* This is a version of xcb_poll_for_event that only examines the
|
||||
|
@ -346,8 +382,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.
|
||||
* @param c: The connection to the X server.
|
||||
* @param cookie: The request cookie.
|
||||
* @param c The connection to the X server.
|
||||
* @param cookie The request cookie.
|
||||
* @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
|
||||
|
@ -364,8 +400,8 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
|
|||
|
||||
/**
|
||||
* @brief Discards the reply for a request.
|
||||
* @param c: The connection to the X server.
|
||||
* @param sequence: The request sequence number from a cookie.
|
||||
* @param c The connection to the X server.
|
||||
* @param sequence The request sequence number from a cookie.
|
||||
*
|
||||
* Discards the reply for a request. Additionally, any error generated
|
||||
* by the request is also discarded (unless it was an _unchecked request
|
||||
|
@ -378,13 +414,33 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
|
|||
*/
|
||||
void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence);
|
||||
|
||||
/**
|
||||
* @brief Discards the reply for a request, given by a 64bit sequence number
|
||||
* @param c The connection to the X server.
|
||||
* @param sequence 64-bit sequence number as returned by xcb_send_request64().
|
||||
*
|
||||
* Discards the reply for a request. Additionally, any error generated
|
||||
* by the request is also discarded (unless it was an _unchecked request
|
||||
* and the error has already arrived).
|
||||
*
|
||||
* This function will not block even if the reply is not yet available.
|
||||
*
|
||||
* Note that the sequence really does have to come from xcb_send_request64();
|
||||
* the cookie sequence number is defined as "unsigned" int and therefore
|
||||
* not 64-bit on all platforms.
|
||||
* This function is not designed to operate on socket-handoff replies.
|
||||
*
|
||||
* Unlike its xcb_discard_reply() counterpart, the given sequence number is not
|
||||
* automatically "widened" to 64-bit.
|
||||
*/
|
||||
void xcb_discard_reply64(xcb_connection_t *c, uint64_t sequence);
|
||||
|
||||
/* xcb_ext.c */
|
||||
|
||||
/**
|
||||
* @brief Caches reply information from QueryExtension requests.
|
||||
* @param c: The connection.
|
||||
* @param ext: The extension data.
|
||||
* @param c The connection.
|
||||
* @param ext The extension data.
|
||||
* @return A pointer to the xcb_query_extension_reply_t for the extension.
|
||||
*
|
||||
* This function is the primary interface to the "extension cache",
|
||||
|
@ -401,8 +457,8 @@ const struct xcb_query_extension_reply_t *xcb_get_extension_data(xcb_connection_
|
|||
|
||||
/**
|
||||
* @brief Prefetch of extension data into the extension cache
|
||||
* @param c: The connection.
|
||||
* @param ext: The extension data.
|
||||
* @param c The connection.
|
||||
* @param ext The extension data.
|
||||
*
|
||||
* This function allows a "prefetch" of extension data into the
|
||||
* extension cache. Invoking the function may cause a call to
|
||||
|
@ -417,7 +473,7 @@ void xcb_prefetch_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
|
|||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* Accessor for the data returned by the server when the xcb_connection_t
|
||||
|
@ -433,21 +489,23 @@ void xcb_prefetch_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
|
|||
*
|
||||
* The result must not be freed.
|
||||
*/
|
||||
XCB_PURE_FUNCTION
|
||||
const struct xcb_setup_t *xcb_get_setup(xcb_connection_t *c);
|
||||
|
||||
/**
|
||||
* @brief Access the file descriptor of the connection.
|
||||
* @param c: The connection.
|
||||
* @param c The connection.
|
||||
* @return The file descriptor.
|
||||
*
|
||||
* Accessor for the file descriptor that was passed to the
|
||||
* xcb_connect_to_fd call that returned @p c.
|
||||
*/
|
||||
XCB_PURE_FUNCTION
|
||||
int xcb_get_file_descriptor(xcb_connection_t *c);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* Some errors that occur in the context of an xcb_connection_t
|
||||
|
@ -463,12 +521,13 @@ int xcb_get_file_descriptor(xcb_connection_t *c);
|
|||
* @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.
|
||||
*/
|
||||
XCB_PURE_FUNCTION
|
||||
int xcb_connection_has_error(xcb_connection_t *c);
|
||||
|
||||
/**
|
||||
* @brief Connects to the X server.
|
||||
* @param fd: The file descriptor.
|
||||
* @param auth_info: Authentication data.
|
||||
* @param fd The file descriptor.
|
||||
* @param auth_info Authentication data.
|
||||
* @return A newly allocated xcb_connection_t structure.
|
||||
*
|
||||
* Connects to an X server, given the open socket @p fd and the
|
||||
|
@ -486,7 +545,7 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info);
|
|||
|
||||
/**
|
||||
* @brief Closes the connection.
|
||||
* @param c: The connection.
|
||||
* @param c The connection.
|
||||
*
|
||||
* Closes the file descriptor and frees all memory associated with the
|
||||
* connection @c c. If @p c is @c NULL, nothing is done.
|
||||
|
@ -498,10 +557,10 @@ void xcb_disconnect(xcb_connection_t *c);
|
|||
|
||||
/**
|
||||
* @brief Parses a display string name in the form documented by X(7x).
|
||||
* @param name: The name of the display.
|
||||
* @param host: A pointer to a malloc'd copy of the hostname.
|
||||
* @param display: A pointer to the display number.
|
||||
* @param screen: A pointer to the screen number.
|
||||
* @param name The name of the display.
|
||||
* @param host A pointer to a malloc'd copy of the hostname.
|
||||
* @param display A pointer to the display number.
|
||||
* @param screen A pointer to the screen number.
|
||||
* @return 0 on failure, non 0 otherwise.
|
||||
*
|
||||
* Parses the display string name @p display_name in the form
|
||||
|
@ -517,8 +576,8 @@ int xcb_parse_display(const char *name, char **host, int *display, int *screen);
|
|||
|
||||
/**
|
||||
* @brief Connects to the X server.
|
||||
* @param displayname: The name of the display.
|
||||
* @param screenp: A pointer to a preferred screen number.
|
||||
* @param displayname The name of the display.
|
||||
* @param screenp A pointer to a preferred screen number.
|
||||
* @return A newly allocated xcb_connection_t structure.
|
||||
*
|
||||
* Connects to the X server specified by @p displayname. If @p
|
||||
|
@ -536,9 +595,9 @@ xcb_connection_t *xcb_connect(const char *displayname, int *screenp);
|
|||
|
||||
/**
|
||||
* @brief Connects to the X server, using an authorization information.
|
||||
* @param display: The name of the display.
|
||||
* @param auth: The authorization information.
|
||||
* @param screen: A pointer to a preferred screen number.
|
||||
* @param display The name of the display.
|
||||
* @param auth The authorization information.
|
||||
* @param screen A pointer to a preferred screen number.
|
||||
* @return A newly allocated xcb_connection_t structure.
|
||||
*
|
||||
* Connects to the X server specified by @p displayname, using the
|
||||
|
@ -558,8 +617,8 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *display, xcb
|
|||
|
||||
/**
|
||||
* @brief Allocates an XID for a new object.
|
||||
* @param c: The connection.
|
||||
* @return A newly allocated XID.
|
||||
* @param c The connection.
|
||||
* @return A newly allocated XID, or -1 on failure.
|
||||
*
|
||||
* Allocates an XID for a new object. Typically used just prior to
|
||||
* various object creation functions, such as xcb_create_window.
|
||||
|
@ -567,6 +626,35 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *display, xcb
|
|||
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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -31,9 +31,8 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <X11/Xauth.h>
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __INTERIX
|
||||
/* _don't_ ask. interix has INADDR_LOOPBACK in here. */
|
||||
|
@ -48,6 +47,8 @@
|
|||
#endif
|
||||
#include "xcb_windefs.h"
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
@ -72,7 +73,7 @@ enum auth_protos {
|
|||
#define AUTH_PROTO_XDM_AUTHORIZATION "XDM-AUTHORIZATION-1"
|
||||
#define AUTH_PROTO_MIT_MAGIC_COOKIE "MIT-MAGIC-COOKIE-1"
|
||||
|
||||
static char *authnames[N_AUTH_PROTOS] = {
|
||||
static const char *authnames[N_AUTH_PROTOS] = {
|
||||
#ifdef HASXDMAUTH
|
||||
AUTH_PROTO_XDM_AUTHORIZATION,
|
||||
#endif
|
||||
|
@ -133,6 +134,7 @@ static Xauth *get_authptr(struct sockaddr *sockname, int display)
|
|||
}
|
||||
addr += 12;
|
||||
/* if v4-mapped, fall through. */
|
||||
XCB_ALLOW_FALLTHRU
|
||||
#endif
|
||||
case AF_INET:
|
||||
if(!addr)
|
||||
|
@ -163,7 +165,7 @@ static Xauth *get_authptr(struct sockaddr *sockname, int display)
|
|||
return XauGetBestAuthByAddr (family,
|
||||
(unsigned short) addrlen, addr,
|
||||
(unsigned short) dispbuflen, dispbuf,
|
||||
N_AUTH_PROTOS, authnames, authnameslen);
|
||||
N_AUTH_PROTOS, (char **)authnames, authnameslen);
|
||||
}
|
||||
|
||||
#ifdef HASXDMAUTH
|
||||
|
@ -269,10 +271,17 @@ static int compute_auth(xcb_auth_info_t *info, Xauth *authptr, struct sockaddr *
|
|||
to the value returned by either getpeername() or getsockname()
|
||||
(according to POSIX, applications should not assume a particular
|
||||
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,
|
||||
struct sockaddr *,
|
||||
socklen_t *),
|
||||
int fd)
|
||||
#endif
|
||||
{
|
||||
socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK;
|
||||
socklen_t actual_socknamelen = socknamelen;
|
||||
|
|
134
src/xcb_conn.c
134
src/xcb_conn.c
|
@ -32,7 +32,6 @@
|
|||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
@ -48,7 +47,9 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
#include "xcb_windefs.h"
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#endif /* _WIN32 */
|
||||
|
@ -64,6 +65,26 @@ typedef struct {
|
|||
uint16_t length;
|
||||
} 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()! */
|
||||
static const int xcb_con_error = XCB_CONN_ERROR;
|
||||
static const int xcb_con_closed_mem_er = XCB_CONN_CLOSED_MEM_INSUFFICIENT;
|
||||
|
@ -149,6 +170,8 @@ static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info)
|
|||
|
||||
static int read_setup(xcb_connection_t *c)
|
||||
{
|
||||
const char newline = '\n';
|
||||
|
||||
/* Read the server response */
|
||||
c->setup = malloc(sizeof(xcb_setup_generic_t));
|
||||
if(!c->setup)
|
||||
|
@ -174,6 +197,7 @@ static int read_setup(xcb_connection_t *c)
|
|||
{
|
||||
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, &newline, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -181,6 +205,7 @@ static int read_setup(xcb_connection_t *c)
|
|||
{
|
||||
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, &newline, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -191,33 +216,47 @@ static int read_setup(xcb_connection_t *c)
|
|||
/* precondition: there must be something for us to write. */
|
||||
static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
int n;
|
||||
#endif
|
||||
|
||||
assert(!c->out.queue_len);
|
||||
|
||||
#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
|
||||
an iovec would require more work and I'm not sure of the benefit....works for now */
|
||||
vec = *vector;
|
||||
while(i < *count)
|
||||
while (*count)
|
||||
{
|
||||
ret = send(c->fd,vec->iov_base,vec->iov_len,0);
|
||||
if(ret == SOCKET_ERROR)
|
||||
{
|
||||
err = WSAGetLastError();
|
||||
if(err == WSAEWOULDBLOCK)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
n += ret;
|
||||
*vec++;
|
||||
i++;
|
||||
struct iovec *vec = *vector;
|
||||
if (vec->iov_len)
|
||||
{
|
||||
int ret = send(c->fd, vec->iov_base, vec->iov_len, 0);
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
int err = WSAGetLastError();
|
||||
if (err == WSAEWOULDBLOCK)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
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
|
||||
n = *count;
|
||||
if (n > IOV_MAX)
|
||||
|
@ -259,28 +298,32 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
if(n <= 0)
|
||||
{
|
||||
_xcb_conn_shutdown(c, XCB_CONN_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c->out.total_written += n;
|
||||
for(; *count; --*count, ++*vector)
|
||||
{
|
||||
int cur = (*vector)->iov_len;
|
||||
if(cur > n)
|
||||
cur = n;
|
||||
(*vector)->iov_len -= cur;
|
||||
(*vector)->iov_base = (char *) (*vector)->iov_base + cur;
|
||||
n -= cur;
|
||||
if(cur) {
|
||||
(*vector)->iov_len -= cur;
|
||||
(*vector)->iov_base = (char *) (*vector)->iov_base + cur;
|
||||
n -= cur;
|
||||
}
|
||||
if((*vector)->iov_len)
|
||||
break;
|
||||
}
|
||||
if(!*count)
|
||||
*vector = 0;
|
||||
assert(n == 0);
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -288,15 +331,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)
|
||||
{
|
||||
if(c->has_error)
|
||||
return 0;
|
||||
if(is_static_error_conn(c))
|
||||
return &xcb_error_setup;
|
||||
/* doesn't need locking because it's never written to. */
|
||||
return c->setup;
|
||||
}
|
||||
|
||||
int xcb_get_file_descriptor(xcb_connection_t *c)
|
||||
{
|
||||
if(c->has_error)
|
||||
if(is_static_error_conn(c))
|
||||
return -1;
|
||||
/* doesn't need locking because it's never written to. */
|
||||
return c->fd;
|
||||
|
@ -324,7 +367,11 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info)
|
|||
|
||||
c = calloc(1, sizeof(xcb_connection_t));
|
||||
if(!c) {
|
||||
#ifdef _WIN32
|
||||
closesocket(fd);
|
||||
#else
|
||||
close(fd);
|
||||
#endif
|
||||
return _xcb_conn_ret_error(XCB_CONN_CLOSED_MEM_INSUFFICIENT) ;
|
||||
}
|
||||
|
||||
|
@ -357,7 +404,11 @@ void xcb_disconnect(xcb_connection_t *c)
|
|||
|
||||
/* disallow further sends and receives */
|
||||
shutdown(c->fd, SHUT_RDWR);
|
||||
#ifdef _WIN32
|
||||
closesocket(c->fd);
|
||||
#else
|
||||
close(c->fd);
|
||||
#endif
|
||||
|
||||
pthread_mutex_destroy(&c->iolock);
|
||||
_xcb_in_destroy(&c->in);
|
||||
|
@ -508,3 +559,30 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
132
src/xcb_in.c
132
src/xcb_in.c
|
@ -32,7 +32,6 @@
|
|||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -40,6 +39,7 @@
|
|||
#include <poll.h>
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
@ -97,6 +97,11 @@ typedef struct reader_list {
|
|||
struct reader_list *next;
|
||||
} reader_list;
|
||||
|
||||
typedef struct special_list {
|
||||
xcb_special_event_t *se;
|
||||
struct special_list *next;
|
||||
} special_list;
|
||||
|
||||
static void remove_finished_readers(reader_list **prev_reader, uint64_t completed)
|
||||
{
|
||||
while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, completed))
|
||||
|
@ -234,9 +239,15 @@ static int read_packet(xcb_connection_t *c)
|
|||
if(pend && pend->workaround == WORKAROUND_GLX_GET_FB_CONFIGS_BUG)
|
||||
{
|
||||
uint32_t *p = (uint32_t *) c->in.queue;
|
||||
genrep.length = p[2] * p[3] * 2;
|
||||
uint64_t new_length = ((uint64_t)p[2]) * ((uint64_t)p[3]);
|
||||
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 * 4;
|
||||
length += genrep.length * UINT64_C(4);
|
||||
|
||||
/* XXX a bit of a hack -- we "know" that all FD replys place
|
||||
* the number of fds in the pad0 byte */
|
||||
|
@ -246,7 +257,7 @@ static int read_packet(xcb_connection_t *c)
|
|||
|
||||
/* XGE events may have sizes > 32 */
|
||||
if ((genrep.response_type & 0x7f) == XCB_XGE_EVENT)
|
||||
eventlength = genrep.length * 4;
|
||||
eventlength = genrep.length * UINT64_C(4);
|
||||
|
||||
bufsize = length + eventlength + nfd * sizeof(int) +
|
||||
(genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t));
|
||||
|
@ -360,7 +371,7 @@ static void free_reply_list(struct reply_list *head)
|
|||
}
|
||||
}
|
||||
|
||||
static int read_block(const int fd, void *buf, const ssize_t len)
|
||||
static int read_block(const int fd, void *buf, const intptr_t len)
|
||||
{
|
||||
int done = 0;
|
||||
while(done < len)
|
||||
|
@ -475,6 +486,26 @@ static void remove_reader(reader_list **prev_reader, reader_list *reader)
|
|||
}
|
||||
}
|
||||
|
||||
static void insert_special(special_list **prev_special, special_list *special, xcb_special_event_t *se)
|
||||
{
|
||||
special->se = se;
|
||||
special->next = *prev_special;
|
||||
*prev_special = special;
|
||||
}
|
||||
|
||||
static void remove_special(special_list **prev_special, special_list *special)
|
||||
{
|
||||
while(*prev_special)
|
||||
{
|
||||
if(*prev_special == special)
|
||||
{
|
||||
*prev_special = (*prev_special)->next;
|
||||
break;
|
||||
}
|
||||
prev_special = &(*prev_special)->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void *wait_for_reply(xcb_connection_t *c, uint64_t request, xcb_generic_error_t **e)
|
||||
{
|
||||
void *ret = 0;
|
||||
|
@ -523,6 +554,20 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_
|
|||
return ret;
|
||||
}
|
||||
|
||||
void *xcb_wait_for_reply64(xcb_connection_t *c, uint64_t request, xcb_generic_error_t **e)
|
||||
{
|
||||
void *ret;
|
||||
if(e)
|
||||
*e = 0;
|
||||
if(c->has_error)
|
||||
return 0;
|
||||
|
||||
pthread_mutex_lock(&c->iolock);
|
||||
ret = wait_for_reply(c, request, e);
|
||||
pthread_mutex_unlock(&c->iolock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int *xcb_get_reply_fds(xcb_connection_t *c, void *reply, size_t reply_size)
|
||||
{
|
||||
return (int *) (&((char *) reply)[reply_size]);
|
||||
|
@ -595,6 +640,20 @@ void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence)
|
|||
pthread_mutex_unlock(&c->iolock);
|
||||
}
|
||||
|
||||
void xcb_discard_reply64(xcb_connection_t *c, uint64_t sequence)
|
||||
{
|
||||
if(c->has_error)
|
||||
return;
|
||||
|
||||
/* If an error occurred when issuing the request, fail immediately. */
|
||||
if(!sequence)
|
||||
return;
|
||||
|
||||
pthread_mutex_lock(&c->iolock);
|
||||
discard_reply(c, sequence);
|
||||
pthread_mutex_unlock(&c->iolock);
|
||||
}
|
||||
|
||||
int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, xcb_generic_error_t **error)
|
||||
{
|
||||
int ret;
|
||||
|
@ -608,6 +667,27 @@ int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply,
|
|||
assert(reply != 0);
|
||||
pthread_mutex_lock(&c->iolock);
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xcb_poll_for_reply64(xcb_connection_t *c, uint64_t request, void **reply, xcb_generic_error_t **error)
|
||||
{
|
||||
int ret;
|
||||
if(c->has_error)
|
||||
{
|
||||
*reply = 0;
|
||||
if(error)
|
||||
*error = 0;
|
||||
return 1; /* would not block */
|
||||
}
|
||||
assert(reply != 0);
|
||||
pthread_mutex_lock(&c->iolock);
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
@ -662,11 +742,16 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
|
|||
return 0;
|
||||
pthread_mutex_lock(&c->iolock);
|
||||
request = widen(c, cookie.sequence);
|
||||
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_completed))
|
||||
{
|
||||
_xcb_out_send_sync(c);
|
||||
_xcb_out_flush_to(c, c->out.request);
|
||||
if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected))
|
||||
{
|
||||
_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);
|
||||
assert(!reply);
|
||||
|
@ -698,6 +783,8 @@ xcb_generic_event_t *xcb_poll_for_special_event(xcb_connection_t *c,
|
|||
return 0;
|
||||
pthread_mutex_lock(&c->iolock);
|
||||
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);
|
||||
return event;
|
||||
}
|
||||
|
@ -705,17 +792,23 @@ xcb_generic_event_t *xcb_poll_for_special_event(xcb_connection_t *c,
|
|||
xcb_generic_event_t *xcb_wait_for_special_event(xcb_connection_t *c,
|
||||
xcb_special_event_t *se)
|
||||
{
|
||||
special_list special;
|
||||
xcb_generic_event_t *event;
|
||||
|
||||
if(c->has_error)
|
||||
return 0;
|
||||
pthread_mutex_lock(&c->iolock);
|
||||
|
||||
insert_special(&c->in.special_waiters, &special, se);
|
||||
|
||||
/* get_special_event returns 0 on empty list. */
|
||||
while(!(event = get_special_event(c, se)))
|
||||
if(!_xcb_conn_wait(c, &se->special_event_cond, 0, 0))
|
||||
break;
|
||||
|
||||
remove_special(&c->in.special_waiters, &special);
|
||||
|
||||
_xcb_in_wake_up_next_reader(c);
|
||||
pthread_mutex_unlock(&c->iolock);
|
||||
return event;
|
||||
}
|
||||
|
@ -843,6 +936,8 @@ void _xcb_in_wake_up_next_reader(xcb_connection_t *c)
|
|||
int pthreadret;
|
||||
if(c->in.readers)
|
||||
pthreadret = pthread_cond_signal(c->in.readers->data);
|
||||
else if(c->in.special_waiters)
|
||||
pthreadret = pthread_cond_signal(&c->in.special_waiters->se->special_event_cond);
|
||||
else
|
||||
pthreadret = pthread_cond_signal(&c->in.event_cond);
|
||||
assert(pthreadret == 0);
|
||||
|
@ -874,8 +969,20 @@ void _xcb_in_replies_done(xcb_connection_t *c)
|
|||
pend = container_of(c->in.pending_replies_tail, struct pending_reply, next);
|
||||
if(pend->workaround == WORKAROUND_EXTERNAL_SOCKET_OWNER)
|
||||
{
|
||||
pend->last_request = c->out.request;
|
||||
pend->workaround = WORKAROUND_NONE;
|
||||
if (XCB_SEQUENCE_COMPARE(pend->first_request, <=, c->out.request)) {
|
||||
pend->last_request = c->out.request;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -929,6 +1036,7 @@ int _xcb_in_read(xcb_connection_t *c)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
c->in.total_read += n;
|
||||
c->in.queue_len += n;
|
||||
}
|
||||
while(read_packet(c))
|
||||
|
@ -955,7 +1063,7 @@ int _xcb_in_read(xcb_connection_t *c)
|
|||
}
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
if((n > 0) || (n < 0 && errno == EAGAIN))
|
||||
if((n > 0) || (n < 0 && (errno == EAGAIN || errno == EINTR)))
|
||||
#else
|
||||
if((n > 0) || (n < 0 && WSAGetLastError() == WSAEWOULDBLOCK))
|
||||
#endif /* !_WIN32 */
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
typedef struct node {
|
||||
struct node *next;
|
||||
unsigned int key;
|
||||
uint64_t key;
|
||||
void *data;
|
||||
} node;
|
||||
|
||||
|
@ -73,7 +73,7 @@ void _xcb_map_delete(_xcb_map *list, xcb_list_free_func_t do_free)
|
|||
free(list);
|
||||
}
|
||||
|
||||
int _xcb_map_put(_xcb_map *list, unsigned int key, void *data)
|
||||
int _xcb_map_put(_xcb_map *list, uint64_t key, void *data)
|
||||
{
|
||||
node *cur = malloc(sizeof(node));
|
||||
if(!cur)
|
||||
|
@ -86,7 +86,7 @@ int _xcb_map_put(_xcb_map *list, unsigned int key, void *data)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void *_xcb_map_remove(_xcb_map *list, unsigned int key)
|
||||
void *_xcb_map_remove(_xcb_map *list, uint64_t key)
|
||||
{
|
||||
node **cur;
|
||||
for(cur = &list->head; *cur; cur = &(*cur)->next)
|
||||
|
|
110
src/xcb_out.c
110
src/xcb_out.c
|
@ -31,7 +31,11 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "xcb.h"
|
||||
|
@ -177,15 +181,59 @@ uint32_t xcb_get_maximum_request_length(xcb_connection_t *c)
|
|||
return c->out.maximum_request_length.value;
|
||||
}
|
||||
|
||||
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
|
||||
static void close_fds(int *fds, unsigned int num_fds)
|
||||
{
|
||||
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;
|
||||
uint32_t prefix[2];
|
||||
int veclen = req->count;
|
||||
enum workarounds workaround = WORKAROUND_NONE;
|
||||
|
||||
if(c->has_error)
|
||||
if(c->has_error) {
|
||||
close_fds(fds, num_fds);
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(c != 0);
|
||||
assert(vector != 0);
|
||||
|
@ -204,6 +252,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
|
|||
const xcb_query_extension_reply_t *extension = xcb_get_extension_data(c, req->ext);
|
||||
if(!(extension && extension->present))
|
||||
{
|
||||
close_fds(fds, num_fds);
|
||||
_xcb_conn_shutdown(c, XCB_CONN_CLOSED_EXT_NOTSUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
@ -234,6 +283,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
|
|||
}
|
||||
else if(longlen > xcb_get_maximum_request_length(c))
|
||||
{
|
||||
close_fds(fds, num_fds);
|
||||
_xcb_conn_shutdown(c, XCB_CONN_CLOSED_REQ_LEN_EXCEED);
|
||||
return 0; /* server can't take this; maybe need BIGREQUESTS? */
|
||||
}
|
||||
|
@ -264,6 +314,11 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
|
|||
/* get a sequence number and arrange for delivery. */
|
||||
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);
|
||||
|
||||
/* send GetInputFocus (sync_req) when 64k-2 requests have been sent without
|
||||
|
@ -272,7 +327,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
|
|||
* applications see sequence 0 as that is used to indicate
|
||||
* an error in sending the request
|
||||
*/
|
||||
|
||||
|
||||
while ((req->isvoid && c->out.request == c->in.request_expected + (1 << 16) - 2) ||
|
||||
(unsigned int) (c->out.request + 1) == 0)
|
||||
{
|
||||
|
@ -286,22 +341,36 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
|
|||
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 */
|
||||
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
|
||||
{
|
||||
return xcb_send_request64(c, flags, vector, req);
|
||||
}
|
||||
|
||||
void
|
||||
xcb_send_fd(xcb_connection_t *c, int fd)
|
||||
{
|
||||
#if HAVE_SENDMSG
|
||||
if (c->has_error)
|
||||
int fds[1] = { fd };
|
||||
|
||||
if (c->has_error) {
|
||||
close(fd);
|
||||
return;
|
||||
pthread_mutex_lock(&c->iolock);
|
||||
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_lock(&c->iolock);
|
||||
send_fds(c, &fds[0], 1);
|
||||
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)
|
||||
|
@ -322,8 +391,14 @@ int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), v
|
|||
{
|
||||
c->out.return_socket = return_socket;
|
||||
c->out.socket_closure = closure;
|
||||
if(flags)
|
||||
_xcb_in_expect_reply(c, c->out.request, WORKAROUND_EXTERNAL_SOCKET_OWNER, flags);
|
||||
if(flags) {
|
||||
/* c->out.request + 1 will be the first request sent by the external
|
||||
* 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);
|
||||
*sent = c->out.request;
|
||||
}
|
||||
|
@ -372,6 +447,7 @@ int _xcb_out_init(_xcb_out *out)
|
|||
|
||||
out->request = 0;
|
||||
out->request_written = 0;
|
||||
out->request_expected_written = 0;
|
||||
|
||||
if(pthread_mutex_init(&out->reqlenlock, 0))
|
||||
return 0;
|
||||
|
@ -382,8 +458,9 @@ int _xcb_out_init(_xcb_out *out)
|
|||
|
||||
void _xcb_out_destroy(_xcb_out *out)
|
||||
{
|
||||
pthread_cond_destroy(&out->cond);
|
||||
pthread_mutex_destroy(&out->reqlenlock);
|
||||
pthread_cond_destroy(&out->cond);
|
||||
pthread_cond_destroy(&out->socket_cond);
|
||||
}
|
||||
|
||||
int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count)
|
||||
|
@ -392,6 +469,7 @@ int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count)
|
|||
while(ret && count)
|
||||
ret = _xcb_conn_wait(c, &c->out.cond, &vector, &count);
|
||||
c->out.request_written = c->out.request;
|
||||
c->out.request_expected_written = c->in.request_expected;
|
||||
pthread_cond_broadcast(&c->out.cond);
|
||||
_xcb_in_wake_up_next_reader(c);
|
||||
return ret;
|
||||
|
|
164
src/xcb_util.c
164
src/xcb_util.c
|
@ -36,12 +36,12 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "xcb_windefs.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
@ -60,16 +60,27 @@
|
|||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LAUNCHD
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef __has_builtin
|
||||
# define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
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;
|
||||
y = (mask >> 1) & 033333333333;
|
||||
y = mask - y - ((y >> 1) & 033333333333);
|
||||
return ((y + (y >> 3)) & 030707070707) % 077;
|
||||
#endif
|
||||
}
|
||||
|
||||
int xcb_sumof(uint8_t *list, int len)
|
||||
|
@ -82,7 +93,6 @@ int xcb_sumof(uint8_t *list, int len)
|
|||
return s;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LAUNCHD
|
||||
/* Return true and parse if name matches <path to socket>[.<screen>]
|
||||
* Upon success:
|
||||
* host = <path to socket>
|
||||
|
@ -94,20 +104,33 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
|
|||
int *displayp, int *screenp)
|
||||
{
|
||||
struct stat sbuf;
|
||||
char path[PATH_MAX];
|
||||
int _screen = 0;
|
||||
/* In addition to the AF_UNIX path, there may be a screen number.
|
||||
* The trailing \0 is already accounted in the size of sun_path. */
|
||||
char path[sizeof(((struct sockaddr_un*)0)->sun_path) + 1 + 10];
|
||||
size_t len;
|
||||
int _screen = 0, res;
|
||||
|
||||
strlcpy(path, name, sizeof(path));
|
||||
if (0 != stat(path, &sbuf)) {
|
||||
char *dot = strrchr(path, '.');
|
||||
if (!dot)
|
||||
len = strlen(name);
|
||||
if (len >= sizeof(path))
|
||||
return 0;
|
||||
memcpy(path, name, len + 1);
|
||||
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;
|
||||
*dot = '\0';
|
||||
|
||||
errno = 0;
|
||||
lscreen = strtoul(dot + 1, &endptr, 10);
|
||||
if (lscreen > INT_MAX || !endptr || *endptr || errno)
|
||||
return 0;
|
||||
if (0 != stat(path, &sbuf))
|
||||
return 0;
|
||||
|
||||
_screen = atoi(dot + 1);
|
||||
_screen = (int)lscreen;
|
||||
}
|
||||
|
||||
if (host) {
|
||||
|
@ -133,7 +156,6 @@ static int _xcb_parse_display_path_to_socket(const char *name, char **host, char
|
|||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _xcb_parse_display(const char *name, char **host, char **protocol,
|
||||
int *displayp, int *screenp)
|
||||
|
@ -146,11 +168,12 @@ static int _xcb_parse_display(const char *name, char **host, char **protocol,
|
|||
if(!name)
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_LAUNCHD
|
||||
/* First check for <path to socket>[.<screen>] */
|
||||
if (_xcb_parse_display_path_to_socket(name, host, protocol, displayp, screenp))
|
||||
return 1;
|
||||
#endif
|
||||
if (name[0] == '/')
|
||||
return _xcb_parse_display_path_to_socket(name, host, protocol, displayp, screenp);
|
||||
|
||||
if (strncmp(name, "unix:", 5) == 0)
|
||||
return _xcb_parse_display_path_to_socket(name + 5, host, protocol, displayp, screenp);
|
||||
|
||||
slash = strrchr(name, '/');
|
||||
|
||||
|
@ -236,39 +259,46 @@ static int _xcb_open(const char *host, char *protocol, const int display)
|
|||
char *file = NULL;
|
||||
int actual_filelen;
|
||||
|
||||
/* 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
|
||||
if (protocol && strcmp("unix", protocol) == 0 && host && host[0] == '/') {
|
||||
/* Full path to socket provided, ignore everything else */
|
||||
filelen = strlen(host) + 1;
|
||||
if (filelen > INT_MAX)
|
||||
return -1;
|
||||
file = malloc(filelen);
|
||||
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
|
||||
#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED)
|
||||
/* Check special path for Unix sockets under Solaris Trusted Extensions */
|
||||
if (is_system_labeled())
|
||||
{
|
||||
struct stat sbuf;
|
||||
const char *tsol_base = "/var/tsol/doors/.X11-unix/X";
|
||||
char tsol_socket[PATH_MAX];
|
||||
/* Check special path for Unix sockets under Solaris Trusted Extensions */
|
||||
if (is_system_labeled())
|
||||
{
|
||||
const char *tsol_base = "/var/tsol/doors/.X11-unix/X";
|
||||
char tsol_socket[PATH_MAX];
|
||||
struct stat sbuf;
|
||||
|
||||
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)
|
||||
base = tsol_base;
|
||||
}
|
||||
if (stat(tsol_socket, &sbuf) == 0)
|
||||
base = tsol_base;
|
||||
else if (errno != ENOENT)
|
||||
return 0;
|
||||
}
|
||||
#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;
|
||||
file = malloc(filelen);
|
||||
if(file == NULL)
|
||||
|
@ -276,24 +306,23 @@ static int _xcb_open(const char *host, char *protocol, const int display)
|
|||
|
||||
/* display specifies Unix socket */
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
free(file);
|
||||
|
||||
|
@ -387,7 +416,11 @@ 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);
|
||||
if (_xcb_do_connect(fd, addr->ai_addr, addr->ai_addrlen) >= 0)
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
closesocket(fd);
|
||||
#else
|
||||
close(fd);
|
||||
#endif
|
||||
fd = -1;
|
||||
}
|
||||
freeaddrinfo(results);
|
||||
|
@ -413,7 +446,11 @@ static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short
|
|||
if(_xcb_do_connect(fd, (struct sockaddr*)&_s, sizeof(_s)) >= 0)
|
||||
break;
|
||||
|
||||
#ifdef _WIN32
|
||||
closesocket(fd);
|
||||
#else
|
||||
close(fd);
|
||||
#endif
|
||||
fd = -1;
|
||||
++_c;
|
||||
}
|
||||
|
@ -428,6 +465,8 @@ static int _xcb_open_unix(char *protocol, const char *file)
|
|||
{
|
||||
int fd;
|
||||
struct sockaddr_un addr;
|
||||
socklen_t len = sizeof(int);
|
||||
int val;
|
||||
|
||||
if (protocol && strcmp("unix",protocol))
|
||||
return -1;
|
||||
|
@ -440,6 +479,11 @@ static int _xcb_open_unix(char *protocol, const char *file)
|
|||
fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if(fd == -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) {
|
||||
close(fd);
|
||||
return -1;
|
||||
|
@ -515,10 +559,8 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname,
|
|||
|
||||
if(auth) {
|
||||
c = xcb_connect_to_fd(fd, auth);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(_xcb_get_auth_info(fd, &ourauth, display))
|
||||
else if(_xcb_get_auth_info(fd, &ourauth, display))
|
||||
{
|
||||
c = xcb_connect_to_fd(fd, &ourauth);
|
||||
free(ourauth.name);
|
||||
|
|
|
@ -55,7 +55,7 @@ uint32_t xcb_generate_id(xcb_connection_t *c)
|
|||
/* check for extension */
|
||||
const xcb_query_extension_reply_t *xc_misc_reply =
|
||||
xcb_get_extension_data(c, &xcb_xc_misc_id);
|
||||
if (!xc_misc_reply) {
|
||||
if (!xc_misc_reply || !xc_misc_reply->present) {
|
||||
pthread_mutex_unlock(&c->xid.lock);
|
||||
return -1;
|
||||
}
|
||||
|
|
186
src/xcbext.h
186
src/xcbext.h
|
@ -60,21 +60,21 @@ enum xcb_send_request_flags_t {
|
|||
|
||||
/**
|
||||
* @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 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.
|
||||
* @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 neccessary management information are given in the @p request
|
||||
* array and the necessary management information are given in the @p request
|
||||
* argument.
|
||||
*
|
||||
* 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 prefered way for sending requests.
|
||||
* 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,
|
||||
|
@ -82,28 +82,115 @@ 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);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @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.
|
||||
* @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.
|
||||
*
|
||||
* 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_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.
|
||||
* @param c: The connection to the X server.
|
||||
* @param fd: The file descriptor to send.
|
||||
* @param c The connection to the X server.
|
||||
* @param fd The file descriptor to send.
|
||||
*
|
||||
* After this function returns, the file descriptor given is owned by xcb and
|
||||
* will be closed eventually.
|
||||
*
|
||||
* FIXME: How the heck is this supposed to work in a thread-safe way? There is a
|
||||
* race between two threads doing xcb_send_fd(); xcb_send_request(); at the same
|
||||
* time.
|
||||
* @deprecated This function cannot be used in a thread-safe way. Two threads
|
||||
* that run xcb_send_fd(); xcb_send_request(); could mix up their file
|
||||
* descriptors. Instead, xcb_send_request_with_fds() should be used.
|
||||
*/
|
||||
void xcb_send_fd(xcb_connection_t *c, int fd);
|
||||
|
||||
/**
|
||||
* @brief Take over the write side of the socket
|
||||
* @param c: The connection to the X server.
|
||||
* @param return_socket: Callback function that will be called when xcb wants
|
||||
* @param c The connection to the X server.
|
||||
* @param return_socket Callback function that will be called when xcb wants
|
||||
* to use the socket again.
|
||||
* @param closure: Argument to the callback function.
|
||||
* @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 closure Argument to the callback function.
|
||||
* @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.
|
||||
* Must not be NULL.
|
||||
* @return 1 on success, else 0.
|
||||
*
|
||||
|
@ -127,10 +214,10 @@ int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), v
|
|||
|
||||
/**
|
||||
* @brief Send raw data to the X server.
|
||||
* @param c: The connection to the X server.
|
||||
* @param vector: Array of data to be sent.
|
||||
* @param count: Number of entries in @p vector.
|
||||
* @param requests: Number of requests that are being sent.
|
||||
* @param c The connection to the X server.
|
||||
* @param vector Array of data to be sent.
|
||||
* @param count Number of entries in @p vector.
|
||||
* @param requests Number of requests that are being sent.
|
||||
* @return 1 on success, else 0.
|
||||
*
|
||||
* You must own the write-side of the socket (you've called
|
||||
|
@ -151,9 +238,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.
|
||||
* @param c: The connection to the X server.
|
||||
* @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 c The connection to the X server.
|
||||
* @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.
|
||||
*
|
||||
* 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
|
||||
|
@ -161,41 +248,74 @@ int xcb_writev(xcb_connection_t *c, struct iovec *vector, int count, uint64_t re
|
|||
*/
|
||||
void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e);
|
||||
|
||||
/**
|
||||
* @brief Wait for the reply of a given request, with 64-bit sequence number
|
||||
* @param c The connection to the X server.
|
||||
* @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.
|
||||
*
|
||||
* 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
|
||||
* error occurs.
|
||||
*
|
||||
* Unlike its xcb_wait_for_reply() counterpart, the given sequence number is not
|
||||
* automatically "widened" to 64-bit.
|
||||
*/
|
||||
void *xcb_wait_for_reply64(xcb_connection_t *c, uint64_t request, xcb_generic_error_t **e);
|
||||
|
||||
/**
|
||||
* @brief Poll for the reply of a given request.
|
||||
* @param c: The connection to the X server.
|
||||
* @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 e: Location to store errors in, or NULL. Ignored for unchecked requests.
|
||||
* @param c The connection to the X server.
|
||||
* @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 error Location to store errors in, or NULL. Ignored for unchecked requests.
|
||||
* @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.
|
||||
*/
|
||||
int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, xcb_generic_error_t **error);
|
||||
|
||||
/**
|
||||
* @brief Poll for the reply of a given request, with 64-bit sequence number.
|
||||
* @param c The connection to the X server.
|
||||
* @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 error Location to store errors in, or NULL. Ignored for unchecked requests.
|
||||
* @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.
|
||||
*
|
||||
* Unlike its xcb_poll_for_reply() counterpart, the given sequence number is not
|
||||
* automatically "widened" to 64-bit.
|
||||
*/
|
||||
int xcb_poll_for_reply64(xcb_connection_t *c, uint64_t request, void **reply, xcb_generic_error_t **error);
|
||||
|
||||
/**
|
||||
* @brief Don't use this, only needed by the generated code.
|
||||
* @param c: The connection to the X server.
|
||||
* @param reply: A reply that was received from the server
|
||||
* @param replylen: The size of the reply.
|
||||
* @param c The connection to the X server.
|
||||
* @param reply A reply that was received from the server
|
||||
* @param replylen The size of the reply.
|
||||
* @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);
|
||||
|
||||
|
||||
/* xcb_util.c */
|
||||
|
||||
/**
|
||||
* @param mask: The mask to check
|
||||
* @param mask The mask to check
|
||||
* @return The number of set bits in the mask
|
||||
*/
|
||||
XCB_CONST_FUNCTION
|
||||
int xcb_popcount(uint32_t mask);
|
||||
|
||||
/**
|
||||
* @param list: The base of an array
|
||||
* @param len: The length of the array
|
||||
* @param list The base of an array
|
||||
* @param len The length of the array
|
||||
* @return The sum of all entries in the array.
|
||||
*/
|
||||
XCB_PURE_FUNCTION
|
||||
int xcb_sumof(uint8_t *list, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
19
src/xcbint.h
19
src/xcbint.h
|
@ -38,6 +38,16 @@
|
|||
#pragma GCC visibility push(hidden)
|
||||
#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 {
|
||||
WORKAROUND_NONE,
|
||||
WORKAROUND_GLX_GET_FB_CONFIGS_BUG,
|
||||
|
@ -73,8 +83,8 @@ typedef struct _xcb_map _xcb_map;
|
|||
|
||||
_xcb_map *_xcb_map_new(void);
|
||||
void _xcb_map_delete(_xcb_map *q, xcb_list_free_func_t do_free);
|
||||
int _xcb_map_put(_xcb_map *q, unsigned int key, void *data);
|
||||
void *_xcb_map_remove(_xcb_map *q, unsigned int key);
|
||||
int _xcb_map_put(_xcb_map *q, uint64_t key, void *data);
|
||||
void *_xcb_map_remove(_xcb_map *q, uint64_t key);
|
||||
|
||||
|
||||
/* xcb_out.c */
|
||||
|
@ -103,6 +113,8 @@ typedef struct _xcb_out {
|
|||
|
||||
uint64_t request;
|
||||
uint64_t request_written;
|
||||
uint64_t request_expected_written;
|
||||
uint64_t total_written;
|
||||
|
||||
pthread_mutex_t reqlenlock;
|
||||
enum lazy_reply_tag maximum_request_length_tag;
|
||||
|
@ -135,6 +147,7 @@ typedef struct _xcb_in {
|
|||
uint64_t request_expected;
|
||||
uint64_t request_read;
|
||||
uint64_t request_completed;
|
||||
uint64_t total_read;
|
||||
struct reply_list *current_reply;
|
||||
struct reply_list **current_reply_tail;
|
||||
|
||||
|
@ -142,6 +155,7 @@ typedef struct _xcb_in {
|
|||
struct event_list *events;
|
||||
struct event_list **events_tail;
|
||||
struct reader_list *readers;
|
||||
struct special_list *special_waiters;
|
||||
|
||||
struct pending_reply *pending_replies;
|
||||
struct pending_reply **pending_replies_tail;
|
||||
|
@ -211,6 +225,7 @@ struct xcb_connection_t {
|
|||
|
||||
void _xcb_conn_shutdown(xcb_connection_t *c, int err);
|
||||
|
||||
XCB_CONST_FUNCTION
|
||||
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);
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
#include <stdlib.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)
|
||||
#else
|
||||
void suite_add_test(Suite *s, const TTest *tt, const char *name)
|
||||
#endif
|
||||
{
|
||||
TCase *tc = tcase_create(name);
|
||||
|
||||
#if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 13
|
||||
tcase_add_test(tc, tf);
|
||||
#else
|
||||
tcase_add_test(tc, tt);
|
||||
#endif
|
||||
suite_add_tcase(s, tc);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#include <check.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __unix__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "check_suites.h"
|
||||
#include "xcb.h"
|
||||
#include "xcbext.h"
|
||||
|
@ -12,6 +16,10 @@ typedef enum test_type_t {
|
|||
} test_type_t;
|
||||
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)
|
||||
{
|
||||
int success;
|
||||
|
@ -25,7 +33,7 @@ static void parse_display_pass(const char *name, const char *host, const int dis
|
|||
if(test_type == TEST_ARGUMENT)
|
||||
{
|
||||
argument = name;
|
||||
putenv("DISPLAY=");
|
||||
putenv(display_env);
|
||||
}
|
||||
else if(test_type == TEST_ENVIRONMENT)
|
||||
{
|
||||
|
@ -37,20 +45,20 @@ static void parse_display_pass(const char *name, const char *host, const int dis
|
|||
got_display = got_screen = -42;
|
||||
mark_point();
|
||||
success = xcb_parse_display(argument, &got_host, &got_display, &got_screen);
|
||||
fail_unless(success, "unexpected parse failure %sfor '%s'", test_string[test_type], name);
|
||||
fail_unless(strcmp(host, got_host) == 0, "parse %sproduced unexpected hostname '%s' for '%s': expected '%s'", test_string[test_type], got_host, name, host);
|
||||
fail_unless(display == got_display, "parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display);
|
||||
fail_unless(screen == got_screen, "parse %sproduced unexpected screen '%d' for '%s': expected '%d'", test_string[test_type], got_screen, name, screen);
|
||||
ck_assert_msg(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);
|
||||
ck_assert_msg(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);
|
||||
|
||||
got_host = (char *) -1;
|
||||
got_display = got_screen = -42;
|
||||
mark_point();
|
||||
success = xcb_parse_display(argument, &got_host, &got_display, 0);
|
||||
fail_unless(success, "unexpected screenless parse failure %sfor '%s'", test_string[test_type], name);
|
||||
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);
|
||||
fail_unless(display == got_display, "screenless parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display);
|
||||
ck_assert_msg(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);
|
||||
ck_assert_msg(display == got_display, "screenless parse %sproduced unexpected display '%d' for '%s': expected '%d'", test_string[test_type], got_display, name, display);
|
||||
}
|
||||
putenv("DISPLAY=");
|
||||
putenv(display_env);
|
||||
}
|
||||
|
||||
static void parse_display_fail(const char *name)
|
||||
|
@ -66,7 +74,7 @@ static void parse_display_fail(const char *name)
|
|||
if(test_type == TEST_ARGUMENT)
|
||||
{
|
||||
argument = name;
|
||||
putenv("DISPLAY=");
|
||||
putenv(display_env);
|
||||
}
|
||||
else if(test_type == TEST_ENVIRONMENT)
|
||||
{
|
||||
|
@ -79,24 +87,55 @@ static void parse_display_fail(const char *name)
|
|||
got_display = got_screen = -42;
|
||||
mark_point();
|
||||
success = xcb_parse_display(argument, &got_host, &got_display, &got_screen);
|
||||
fail_unless(!success, "unexpected parse success %sfor '%s'", test_string[test_type], name);
|
||||
fail_unless(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host);
|
||||
fail_unless(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display);
|
||||
fail_unless(got_screen == -42, "screen changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_screen);
|
||||
ck_assert_msg(!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);
|
||||
ck_assert_msg(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);
|
||||
|
||||
got_host = (char *) -1;
|
||||
got_display = got_screen = -42;
|
||||
mark_point();
|
||||
success = xcb_parse_display(argument, &got_host, &got_display, 0);
|
||||
fail_unless(!success, "unexpected screenless parse success %sfor '%s'", test_string[test_type], name);
|
||||
fail_unless(got_host == (char *) -1, "host changed on parse failure %sfor '%s': got %p", test_string[test_type], name, got_host);
|
||||
fail_unless(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display);
|
||||
ck_assert_msg(!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);
|
||||
ck_assert_msg(got_display == -42, "display changed on parse failure %sfor '%s': got %d", test_string[test_type], name, got_display);
|
||||
}
|
||||
putenv("DISPLAY=");
|
||||
putenv(display_env);
|
||||
}
|
||||
|
||||
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(":1", "", 1, 0);
|
||||
parse_display_pass(":0.1", "", 0, 1);
|
||||
|
@ -183,7 +222,7 @@ END_TEST
|
|||
|
||||
static void popcount_eq(uint32_t bits, int count)
|
||||
{
|
||||
fail_unless(xcb_popcount(bits) == count, "unexpected popcount(%08x) != %d", bits, count);
|
||||
ck_assert_msg(xcb_popcount(bits) == count, "unexpected popcount(%08x) != %d", bits, count);
|
||||
}
|
||||
|
||||
START_TEST(popcount)
|
||||
|
@ -206,7 +245,7 @@ END_TEST
|
|||
Suite *public_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("Public API");
|
||||
putenv("DISPLAY=");
|
||||
putenv(display_env);
|
||||
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_ipv4, "xcb_parse_display ipv4");
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
#include <check.h>
|
||||
|
||||
#if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 13
|
||||
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);
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Composite
|
||||
Description: XCB Composite Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb xcb-xfixes
|
||||
Requires.private: xcb xcb-xfixes
|
||||
Libs: -L${libdir} -lxcb-composite
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Damage
|
||||
Description: XCB Damage Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb xcb-xfixes
|
||||
Requires.private: xcb xcb-xfixes
|
||||
Libs: -L${libdir} -lxcb-damage
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
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}
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB DPMS
|
||||
Description: XCB DPMS Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-dpms
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB DRI2
|
||||
Description: XCB DRI2 Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-dri2
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB DRI3
|
||||
Description: XCB DRI3 Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-dri3
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
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}
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB GLX
|
||||
Description: XCB GLX Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-glx
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Present
|
||||
Description: XCB Present Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb xcb-randr xcb-xfixes xcb-sync
|
||||
Requires.private: xcb xcb-randr xcb-xfixes xcb-sync xcb-dri3
|
||||
Libs: -L${libdir} -lxcb-present
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB RandR
|
||||
Description: XCB RandR Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb xcb-render
|
||||
Requires.private: xcb xcb-render
|
||||
Libs: -L${libdir} -lxcb-randr
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Record
|
||||
Description: XCB Record Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-record
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Render
|
||||
Description: XCB Render Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-render
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Res
|
||||
Description: XCB X-Resource Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-res
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Screensaver
|
||||
Description: XCB Screensaver Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-screensaver
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Shape
|
||||
Description: XCB Shape Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-shape
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Shm
|
||||
Description: XCB Shm Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-shm
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Sync
|
||||
Description: XCB Sync Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-sync
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Xevie
|
||||
Description: XCB Xevie Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-xevie
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB XFree86-DRI
|
||||
Description: XCB XFree86-DRI Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-xf86dri
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB XFixes
|
||||
Description: XCB XFixes Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb xcb-render xcb-shape
|
||||
Requires.private: xcb xcb-render xcb-shape
|
||||
Libs: -L${libdir} -lxcb-xfixes
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Xinerama
|
||||
Description: XCB Xinerama Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-xinerama
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB XInput
|
||||
Description: XCB XInput Extension (EXPERIMENTAL)
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb xcb-xfixes
|
||||
Requires.private: xcb xcb-xfixes
|
||||
Libs: -L${libdir} -lxcb-xinput
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB XKB
|
||||
Description: XCB Keyboard Extension (EXPERIMENTAL)
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-xkb
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Xprint
|
||||
Description: XCB Xprint Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-xprint
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB SELinux
|
||||
Description: XCB SELinux Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-xselinux
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB XTEST
|
||||
Description: XCB XTEST Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb
|
||||
Requires.private: xcb
|
||||
Libs: -L${libdir} -lxcb-xtest
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB Xv
|
||||
Description: XCB Xv Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb xcb-shm
|
||||
Requires.private: xcb xcb-shm
|
||||
Libs: -L${libdir} -lxcb-xv
|
||||
Cflags: -I${includedir}
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: XCB XvMC
|
||||
Description: XCB XvMC Extension
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: xcb xcb-xv
|
||||
Requires.private: xcb xcb-xv
|
||||
Libs: -L${libdir} -lxcb-xvmc
|
||||
Cflags: -I${includedir}
|
||||
|
|
Loading…
Reference in New Issue