Remove xcl and CVSROOT.

This commit is contained in:
Josh Triplett 2006-02-18 16:49:41 -08:00 committed by Josh Triplett
commit 47ceed7861
41 changed files with 8995 additions and 0 deletions

17
.cvsignore Normal file
View File

@ -0,0 +1,17 @@
Makefile
Makefile.in
aclocal.m4
autom4te.cache
compile
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
libtool
ltmain.sh
missing
mkinstalldirs
*.pc

30
COPYING Normal file
View File

@ -0,0 +1,30 @@
Copyright (C) 2001-2004 Bart Massey, Jamey Sharp, and Josh Triplett.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall
be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the names of the authors
or their institutions shall not be used in advertising or
otherwise to promote the sale, use or other dealings in this
Software without prior written authorization from the
authors.

610
ChangeLog Normal file
View File

@ -0,0 +1,610 @@
2005-12-28 Jamey Sharp <jamey@minilop.net>
* configure.ac:
Replace obsolete AC_OUTPUT(...) call with AC_CONFIG_FILES(...)
and the no-argument AC_OUTPUT macro.
2005-12-24 Jamey Sharp <jamey@minilop.net>
* src/xcb_xlib.c, src/xcbxlib.h, src/Makefile.am:
New header and two functions specifically for Xlib's use, so
we can quit installing xcbint.h.
* src/xcb_out.c, src/xcbint.h:
Now that Xlib uses entirely public API, force_sequence_wrap is
purely internal to xcb_out.
2005-12-20 Jamey Sharp <jamey@minilop.net>
* src/xcb_util.c:
Use AF_UNIX instead of PF_UNIX, because they're interchangeable
on Linux (and 4.x BSD?) but on MacOS X the latter is not
available. Thanks to Ian Osgood for testing.
2005-12-12 Jamey Sharp <jamey@minilop.net>
* src/xcb_util.c:
Rewrite XCBParseDisplay to handle all error cases correctly.
Thanks to Travis Spencer for pointing out a problem with
the previous sscanf call; turns out that sscanf won't do what
I want anyway, so this version just uses strtoul.
2005-12-12 Jamey Sharp <jamey@minilop.net>
* tests/check_public.c:
Fix segfault in fail_unless calls and provide more useful error
messages. Also remove DISPLAY from the environment and test
ParseDisplay on a null pointer.
2005-12-07 Jamey Sharp <jamey@minilop.net>
* src/xcb.h, src/xcb_in.c:
Use GCC attribute extension, if available, to mark some
functions deprecated; and rename XCBWaitEvent to
XCBWaitForEvent, with a deprecated backwards compatibility
function.
2005-12-07 Jamey Sharp <jamey@minilop.net>
* src/xcb.h, src/xcb_conn.c, src/xcb_util.c:
Rename XCBConnect to XCBConnectToFD, and implement XCBConnect
and XCBConnectToDisplayWithAuthInfo, as specified by the XcbApi
documentation. Provide a trivial implementation of deprecated
XCBConnectBasic for backwards compatibility. Fix XCBParseDisplay
to accept a null screen pointer.
2005-09-30 Trevor Woerner <twoerner.x@gmail.com>
reviewer: Jamey Sharp <jamey@minilop.net>
* Makefile.am, configure.ac, src/Makefile.am, tests/Makefile.am,
src/check_all.c, src/check_public.c, src/check_suites.h:
Created a new directory called "tests" where the unit tests
will reside, separate from other files. Moved the unit
test files from the "src" directory into the new "tests"
directory.
* configure.ac, tests/CheckLog.xsl, tests/.cvsignore,
tests/Makefile.am, tests/check_all.c:
Added an XSLT transform to post-process the XML log file which
is generated by the unit test suite into an HTML page. Added
the necessary hooks into the build system to have this
translation occur when necessary as part of the build process.
2005-08-15 Trevor Woerner <twoerner.x@gmail.com>
reviewer: Jamey Sharp <jamey@minilop.net>
* src/Makefile.am:
Make builds work when the source and build directories
are different.
2005-08-03 Trevor Woerner <twoerner.x@gmail.com>
reviewer: Jamey Sharp <jamey@minilop.net>
* configure.ac:
Allow people to not have check as long as they have at
least automake version 1.9. Older versions of automake
still work as long as check is installed or the NoCheck
instructions are followed.
2005-07-21 Jamey Sharp <jamey@minilop.net>
* src/xcb_conn.c:
Fix one uninitialized memory warning from Valgrind.
More will have to wait.
2005-07-21 Jamey Sharp <jamey@minilop.net>
* src/xcb_ext.c:
Fix memory leak reported by Carl Worth (thanks Carl!).
2005-05-22 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
Permit unions to have fixed-length list fields.
2005-05-21 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
In function parameters and structure fields, line up field names in
the same starting column.
2005-05-17 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
Make header files self-sufficient, by including xcb.h in the
generated headers rather than the generated sources.
* src/xcbext.h:
Make xcbext.h self-sufficient, by including xcb.h.
2005-05-17 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
Line up function parameters with opening parenthesis.
2005-05-17 Jamey Sharp <jamey@minilop.net>
* src/c-client.xsl:
Improve whitespace output on function declarations.
2005-04-23 Jeremy Kolb <jkolb@brandeis.edu>
* src/c-client.xsl:
Added list support for typedefs.
GLX now compiles.
2005-04-23 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
Allow protocol descriptions to explicitly qualify types with a
namespace, which should be the value of the header attribute from
the protocol description containing the desired type.
2005-04-10 Jamey Sharp <jamey@minilop.net>
* src/xcb.h, src/xcb_in.c:
New public function XCBGetRequestRead: returns the last sequence
number that the server is known to have processed. This function
enables apps to determine whether forcing a cookie is going to
block.
2005-04-09 Jamey Sharp <jamey@minilop.net>
* src/xcb_ext.c:
Implement XCBPrefetchExtensionData. An extension can now be in
one of three states in a particular connection's cache: not
queried; query cookie available; and query reply available.
2005-04-09 Jamey Sharp <jamey@minilop.net>
* src/xcb_ext.c, src/xcbint.h:
Assign a display-independent unique integer to each XCBExtension
structure. Use a map instead of a list for the extension cache.
Key the map on the assigned integer.
2005-04-06 Jeremy Kolb <jkolb@brandeis.edu>
* src/c-client.xsl:
Added support for c types float and double.
Needed for GLX extension.
2005-04-02 Jamey Sharp <jamey@minilop.net>
* src/c-client.xsl:
Workaround for XSLT processors that can't understand attribute
values of the form '{{ "{...}" }}'. (What? That looks completely
clear to me. *grin*)
2005-04-01 Jamey Sharp <jamey@minilop.net>
* src/xcb_list.c:
Make the _destroy operations no-op on null pointers.
2005-03-31 Jamey Sharp <jamey@minilop.net>
* src/xcb.h, src/xcb_conn.c, src/xcb_out.c, src/xcbint.h:
Lazily check for BIG-REQUESTS support. The first call to
XCBGetMaximumRequestLength takes the two-round-trip penalty for
discovering BIG-REQUESTS support, and caches the result for
subsequent calls. Also XCBSendRequest is now careful to only ask
for the true maximum request length if the length from the
connection setup data isn't sufficient for the current request.
2005-03-31 Jamey Sharp <jamey@minilop.net>
* src/xcb_in.c:
Fix X error handling to, uh, not hang.
2005-03-30 Jamey Sharp <jamey@minilop.net>
* src/xcb_in.c, src/xcbint.h:
Accept zero or more replies to any request. Eliminates, for the
moment, nearly all run-time error checking regarding the number
of replies expected for a particular request. Also breaks the
unexpected reply callback, which is OK because I was going to
remove it anyway, and now I've done so.
2005-03-30 Jamey Sharp <jamey@minilop.net>
* src/xcb_list.c, src/xcbint.h:
Add a map ADT implemented using the list ADT.
2005-03-28 Vincent Torri <torri@iecn.u-nancy.fr>
* doc/tutorial/index.html, doc/tutorial/xcb.css:
Add a tutorial
2005-03-27 Jeremy Kolb <jkolb@brandeis.edu>
* src/Makefile.am:
Added xf86dri (xcb-proto/src/extensions/xf86dri.h).
Removed compilation of record as it's broken.
2005-03-25 Jamey Sharp <jamey@minilop.net>
* src/xcb_in.c:
Instead of storing a pending flag per reply record, look in the
readers list to find out whether there's a reader waiting for
the reply we've just been asked to wait for.
2005-03-25 Jamey Sharp <jamey@minilop.net>
* src/xcb_list.c, src/xcbint.h:
Add _xcb_queue_is_empty.
2005-03-25 Jamey Sharp <jamey@minilop.net>
* src/xcb_in.c, src/xcb_list.c, src/xcbint.h:
Add a queue ADT. Currently implemented using the list ADT, but
analysis will probably suggest a better data structure. The
split is intended to help that analysis.
2005-03-25 Jamey Sharp <jamey@minilop.net>
* src/xcb_in.c, src/xcb_list.c, src/xcbint.h:
Remove _xcb_list_length. (Two callers in xcb_in didn't actually
care about the returned value beyond "empty" or "non-empty",
which they can get other ways.) _xcb_in_events_length became
obsolete in the process, and I took _xcb_list_clear out of
xcbint.h while I was at it because only _xcb_list_delete calls
it these days.
2005-03-25 Jamey Sharp <jamey@minilop.net>
* src/xcb.h, src/xcb_in.c:
Remove XCBEventQueueLength and XCBEventQueueClear: they're not
part of the new API, and they interfere with analysis of the
_xcb_list implementation.
2005-03-24 Josh Triplett <josh@freedesktop.org>
* configure.ac:
Change pdx.freedesktop.org to lists.freedesktop.org in package
email address.
2005-03-23 Jamey Sharp <jamey@minilop.net>
* src/xcb_conn.c, src/xcb_in.c:
avn@daemon.hole.ru pointed out two memory leaks in XCB, which
this update fixes. I also introduced a third a couple of days
ago, which this fixes as well.
2005-03-23 Jamey Sharp <jamey@minilop.net>
* src/xcb_in.c:
Quit storing an "error" flag: it's redundant with the contents
of the packet that it was stored with.
2005-03-22 Jamey Sharp <jamey@minilop.net>
* src/xcb_in.c, src/xcbint.h:
My recent Xlib patch stressed XCB's pending reply queue in ways
it has never been stressed before, with thousands of entries.
Profiling revealed that wake_up_next_reader was taking most of
the cycles of my test app with its linear search of the reply
queue. So I gave it its own 'readers' queue, which can have at
most one entry per thread, and which can be no more than the
number of pending replies. In the current implementation the
readers queue uses only constant-time operations, too.
2005-03-20 Jamey Sharp <jamey@minilop.net>
* src/xcb_in.c:
Wait for the last known read sequence number to pass the request
we're waiting for, instead of checking whether data has arrived
for the current request. Causes null to be returned if somebody
screwed up by expecting a reply when none can come; relied on by
new Xlib/XCB bits that intentionally and routinely screw up this
way because the API doesn't give them enough information.
* src/xcb_list.c, src/xcbint.h:
Add _xcb_list_peek_head so Xlib doesn't have to repeatedly
remove and re-insert the item at the head of its new
pending_requests queue. Profiling showed that was a significant
performance hit for the above-mentioned patch and with this
three-line function apps are actually usable again.
2004-11-26 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
In do-request processing, use the existing num-parts variable
rather than recalculating the same expression.
2004-11-26 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
* Add a list of known core types, and don't search all the
protocol descriptions for types in that list. This
significantly shortens the processing time.
* Search for all definitions of a non-core type, not just the
first, in order to check for duplicate definitions.
* Add an error message for non-core types with no definitions
found.
2004-11-10 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
Don't create a separate local variable for exprfields, and change
an explicit xsl:for-each to an xsl:apply-templates.
2004-11-10 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
Prefix variables in request functions with "xcb_" to avoid
collisions with field names.
2004-11-09 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
* src/xcb_out.c:
* src/xcbext.h:
More API changes: Put constant request-specific data into a static
const structure in each request function.
2004-11-09 Josh Triplett <josh@freedesktop.org>
* src/c-client.xsl:
Add support for an <indent> tag in a function body, which indents
the <l>s it contains.
* debian/.cvsignore:
debian/copyright is a generated file, so add it to
debian/.cvsignore
2004-11-08 Jamey Sharp <jamey@minilop.net>
* src/xcb_conn.c:
Make the __thread-based assertion a compile-time
option, defaulting to off. It breaks on many systems
and isn't critical to XCB's functionality.
2004-11-07 Josh Triplett <josh@freedesktop.org>
* c-client.xsl:
Update XSLT to deal with change from extension element to
extension-name and extension-xname attributes on xcb element.
2004-11-06 Josh Triplett <josh@freedesktop.org>
* xcb.h:
* xcb_auth.c:
* xcb_conn.c:
* xcb_ext.c:
* xcb_in.c:
* xcb_list.c:
* xcb_out.c:
* xcb_util.c:
* xcb_xid.c:
* xcbext.h:
* xcbint.h:
Include license in every file rather than referencing COPYING.
Update copyright notices to 2004.
* COPYING:
Remove non-applicable licenses from COPYING file.
2004-11-06 Josh Triplett <josh@freedesktop.org>
* configure.ac:
* src/.cvsignore:
* src/Makefile.am:
* src/xcb.h:
Merged changes for XML-XCB project.
* src/c-client.xsl:
* src/xcb.h:
Add XSLT binding generator and non-M4 version of xcb.h.
* src/client-c.xcb:
* src/xcb.h.m4:
Remove M4 binding generator and M4 version of xcb.h.
* debian/changelog:
* debian/control:
* debian/copyright.debian:
* debian/rules:
Updated Debian packaging.
2004-09-30 Jamey Sharp <jamey@minilop.net>
* src/xcbext.h:
* src/xcb_in.c:
* src/client-c.xcb:
Renamed XCBWaitReply to XCBWaitForReply for new API.
2004-09-30 Jamey Sharp <jamey@minilop.net>
* src/Makefile.am:
Fix build failure when compiling tests.
2004-09-29 Jamey Sharp <jamey@minilop.net>
* src/xcb.h.m4:
* src/xcb_in.c:
Added XCBPollForEvent function from new API.
2004-09-29 Jamey Sharp <jamey@minilop.net>
* src/xcb.h.m4:
* src/xcbext.h:
* src/client-c.xcb:
* src/xcb_ext.c:
Update the extension cache for its new API. The
optimizations that this API enables are not yet
implemented, but the current implementation should
at least function correctly.
2004-09-29 Jamey Sharp <jamey@minilop.net>
* src/xcb_util.c:
* src/xcbext.h:
Oops, XCBPopcount was supposed to change argument
types too.
2004-09-29 Jamey Sharp <jamey@minilop.net>
* src/client-c.xcb:
* src/xcb_util.c:
* src/xcbext.h:
Renamed XCBOnes to XCBPopcount as per new API spec.
2004-09-29 Jamey Sharp <jamey@minilop.net>
* src/xcbext.h:
* src/xcb.h.m4:
* src/Makefile.am:
* src/client-c.xcb:
* src/xcb_in.c:
* src/xcb_out.c:
* src/xcb_util.c:
* src/xcb_xid.c:
Moved declarations that are only useful to protocol
implementations into a separate header file,
xcbext.h.
2004-09-28 Jamey Sharp <jamey@minilop.net>
* src/xcbint.h:
* src/xcb_conn.c:
Add internal sanity check macros for sequence
numbers, and invoke them every time _xcb_conn_wait
is entered.
2004-09-28 Jamey Sharp <jamey@minilop.net>
* src/client-c.xcb:
Allow LISTPARAMs to omit the length argument. When
generating C code, a LOCALPARAM is automatically
generated for the length if the length argument is
omitted.
2004-08-13 Jamey Sharp <jamey@minilop.net>
* configure.ac:
* src/Makefile.am:
* src/.cvsignore:
* src/check_all.c:
* src/check_suites.h:
* src/check_public.c:
Add the first unit tests for XCB. This adds a build
dependency on 'check'; I hope somebody will make it
more of a build recommendation.
2004-08-13 Jamey Sharp <jamey@minilop.net>
* src/xcb_conn.c:
Add a sanity check: assert() that _xcb_conn_wait
will not be re-entered within the same thread. This
turns out not to be true in some current buggy code.
Xlib re-enters from _XAsyncReplyHandler in
src/xcl/display.c; and the X Test Suite seems to
catch SIGABRT and continue running.
2004-08-10 Jamey Sharp <jamey@minilop.net>
* src/xcb_out.c:
I misread the BIG-REQUESTS specification. The long
length field needs to count itself too.
2004-07-24 Jamey Sharp <jamey@minilop.net>
* src/client-c.xcb:
Renamed functions that return new iterators to
*Iter, to avoid conflict with similar functions that
return arrays.
Deprecating ARRAYFIELD in favor of LISTFIELD, which
now generates both array and iterator accessors. You
get an array accessor as long as the element type is
fixed length; you get an interator accessor as long
as the base type has an iterator. You always get a
'Length' function.
2004-07-24 Jamey Sharp <jamey@minilop.net>
* src/xcb_auth.c:
Bart cleaned up some code that I made ugly, and
I'm fixing a warning that resulted from a static
function being created but not necessarily used.
2004-07-07 Jamey Sharp <jamey@minilop.net>
* src/xcb_xid.c:
OK, it might be a good idea to commit something
that compiles. I thought I'd tested this change...
2004-07-06 Jamey Sharp <jamey@minilop.net>
* src/xcbint.h:
* src/xcb_xid.c:
Added support for the XC-Misc extension's ability
to request more XIDs from the server when the
client runs out of them.
2004-07-06 Jamey Sharp <jamey@minilop.net>
* src/xcb.h.m4:
* src/xcb_auth.c:
* src/xcb_util.c:
Removed XCBNextNonce, and the nonce parameter of
XCBGetAuthInfo, from the API. XCB can compute
that just fine without help from the application.
2004-07-06 Jamey Sharp <jamey@minilop.net>
* src/Makefile.am:
Importing part of patches, adding SYNC, by
Mikko Markus Torni <mikko.markus.torni@iki.fi>.
This needed better padding computation in XCB
before it could be implemented cleanly.
2004-07-02 Jamey Sharp <jamey@minilop.net>
* src/Makefile.am:
Importing part of patches, adding XC-MISC, by
Mikko Markus Torni <mikko.markus.torni@iki.fi>.
2004-07-02 Jamey Sharp <jamey@minilop.net>
* src/xcb.h.m4:
* src/xcb_in.c:
Remove XCBEventQueueRemove and XCBEventQueueFind.
Their existence in the API constrains the
implementation, and they're not useful for real
code, like toolkits, anyway.
2004-07-02 Jamey Sharp <jamey@minilop.net>
* src/client-c.xcb:
* src/xcb.h.m4:
XCB headers are now compatible with C++ source.
2004-07-02 Jamey Sharp <jamey@minilop.net>
* src/client-c.xcb:
* src/xcb.h.m4:
Keith's fix for padding didn't quite work, despite
looking quite sensible at the time. Replaced
XCB_TYPE_CEIL with XCB_TYPE_PAD and made all the
iterators, lists, and arrays count the number of
bytes from the beginning of the current request.
2004-07-02 Jamey Sharp <jamey@minilop.net>
* src/xcb_out.c:
* src/xcbint.h:
Force a response from the server if we haven't seen
one in 65530 requests. If you don't do this, XCB
gets confused the next time it waits for a reply.
2004-06-16 Keith Packard <keithp@keithp.com>
* src/client-c.xcb:
* src/xcb.h.m4:
Must round datatype lengths to 4-byte boundary for
NEXTFIELD and End macros. Created new XCB_TYPE_CEIL
macro for this purpose and used it in a couple of
places. It is to be hoped that this represents all
of the locations that need changing...

229
INSTALL Normal file
View File

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

6
Makefile.am Normal file
View File

@ -0,0 +1,6 @@
SUBDIRS=src tests
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = xcb.pc
EXTRA_DIST=xcb.pc.in

3
autogen.sh Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
autoreconf -v --install || exit 1
./configure "$@"

84
configure.ac Normal file
View File

@ -0,0 +1,84 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT([libXCB],
0.9,
[xcb@lists.freedesktop.org])
AC_CONFIG_SRCDIR([xcb.pc.in])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
dnl This ifdef has no useful effect prior to automake 1.9, but in 1.9
dnl it allows the user to not have check.m4 installed.
m4_ifdef([AM_PATH_CHECK],[
AM_PATH_CHECK(0.8.2, [HAVE_CHECK=true], [HAVE_CHECK=false])
])
AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xtrue)
AC_CONFIG_HEADERS([src/config.h])
AC_PROG_LIBTOOL
AC_PROG_CC
AC_PATH_PROG(XSLTPROC, xsltproc, no)
if test "$XSLTPROC" = "no"; then
AC_MSG_ERROR([XCB requires xsltproc.])
fi
HTML_CHECK_RESULT=false
if test x"$HAVE_CHECK" = xtrue; then
if test x"$XSLTPROC" != xno; then
HTML_CHECK_RESULT=true
fi
fi
AC_SUBST(HTML_CHECK_RESULT)
# Checks for pkg-config packages
PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 0.9)
PKG_CHECK_MODULES(XPROTO, xproto)
PKG_CHECK_MODULES(XAU, xau)
# Find the xcb-proto protocol descriptions
AC_MSG_CHECKING(XCBPROTO_XCBINCLUDEDIR)
XCBPROTO_XCBINCLUDEDIR=`$PKG_CONFIG --variable=xcbincludedir xcb-proto`
AC_MSG_RESULT($XCBPROTO_XCBINCLUDEDIR)
AC_SUBST(XCBPROTO_XCBINCLUDEDIR)
AC_HEADER_STDC
AC_SEARCH_LIBS(gethostbyname, nsl)
AC_SEARCH_LIBS(connect, socket)
xcbincludedir='${includedir}/X11/XCB'
AC_SUBST(xcbincludedir)
AC_ARG_WITH(opt,
AC_HELP_STRING([--with-opt], [compile with reasonable optimizations])
AC_HELP_STRING([--with-opt=FLAGS], [compile with specified FLAGS])
AC_HELP_STRING([--with-opt=small], [compile for smallest code])
AC_HELP_STRING([--with-opt=debug], [compile for debugging (default)]),
[
case "$withval" in
yes)
optflags="-O3"
;;
small)
optflags="-Os -fomit-frame-pointer -DNDEBUG"
;;
no|debug)
optflags="-g"
;;
*)
optflags="$withval"
;;
esac
])
AC_CACHE_CHECK([what compiler optimizations to apply], [optflags], [optflags="-g"])
AC_DEFINE(_XOPEN_SOURCE, 500, [Conform to Single Unix Specification.])
CDEBUGFLAGS="$optflags -Wall -pedantic -Wpointer-arith \
-Wstrict-prototypes -Wmissing-declarations -Wnested-externs"
AC_SUBST(CDEBUGFLAGS)
AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile])
AC_CONFIG_FILES([xcb.pc])
AC_OUTPUT

6
debian/.cvsignore vendored Normal file
View File

@ -0,0 +1,6 @@
compat
copyright
fd.o-*
stamp-*
tmp
files

41
debian/changelog vendored Normal file
View File

@ -0,0 +1,41 @@
libxcb0 (0.9-1pre2v4) unstable; urgency=low
pre2v1:
* Split into libxcb0 and libxcb0-dev.
* Change control file for new packages.
* Add install and dirs files for new packages.
* Update Build-Depends for renaming of fd.o-xau, fd.o-xproto, and
fd.o-xcb-proto.
* Remove fd.o prefix from package name.
* Change Maintainer to xcb@lists.freedesktop.org, move myself to
Uploaders, and add Jamey Sharp to Uploaders. Update copyright.debian
accordingly.
* Add Bugs field pointing to xcb@lists.freedesktop.org.
* Update homepage URL in description and copyright.debian to
http://xcb.freedesktop.org, and put it in a Homepage: field in the
description.
pre2v2:
* Add libxcb0-dbg package.
pre2v3:
* New upstream snapshot.
pre2v4:
* New upstream snapshot.
-- Josh Triplett <josh@freedesktop.org> Tue, 17 May 2005 12:53:53 -0700
fd.o-xcb (0.9-1) unstable; urgency=low
* New version using XSLT; works with XML descriptions in xcb-proto 0.9.
* Updated Debian packaging.
-- Josh Triplett <josh@freedesktop.org> Fri, 29 Oct 2004 15:11:09 -0700
fd.o-xcb (0.8-1) unstable; urgency=low
* Initial Release.
-- Jamey Sharp <sharpone@debian.org> Thu, 18 Mar 2004 00:09:03 -0800

56
debian/control vendored Normal file
View File

@ -0,0 +1,56 @@
Source: libxcb0
Priority: optional
Maintainer: XCB Developers <xcb@lists.freedesktop.org>
Uploaders: Jamey Sharp <sharpone@debian.org>, Josh Triplett <josh@freedesktop.org>
Build-Depends: x-dev, libxau-dev, xcb-proto, cdbs, debhelper (>= 4.1.76), pkg-config, autoconf, automake1.9 | automaken, libtool, xsltproc, check, binutils (>= 2.12.90.0.9)
Build-Conflicts: automake1.4, automake1.5, automake1.6
Standards-Version: 3.6.1
Bugs: mailto:xcb@lists.freedesktop.org
Package: libxcb0
Section: libs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: X C Binding
Xlib has been the standard C binding for the X Window System protocol for
many years now. It is an excellent piece of work, but there are applications
for which it is not ideal. XCB builds on nearly two decades of experience
with X specifically and software engineering in general in an effort to
replace the aging Xlib code base.
.
This package contains the library files needed to run software using
XCB.
.
Homepage: http://xcb.freedesktop.org
Package: libxcb0-dev
Section: libdevel
Architecture: any
Depends: libxcb0 (= ${Source-Version}), x-dev
Description: X C Binding, development files
Xlib has been the standard C binding for the X Window System protocol for
many years now. It is an excellent piece of work, but there are applications
for which it is not ideal. XCB builds on nearly two decades of experience
with X specifically and software engineering in general in an effort to
replace the aging Xlib code base.
.
This package contains the header and library files needed to build software
using XCB.
.
Homepage: http://xcb.freedesktop.org
Package: libxcb0-dbg
Section: libdevel
Architecture: any
Depends: libxcb0 (= ${Source-Version})
Description: X C Binding, debugging symbols
Xlib has been the standard C binding for the X Window System protocol for
many years now. It is an excellent piece of work, but there are applications
for which it is not ideal. XCB builds on nearly two decades of experience
with X specifically and software engineering in general in an effort to
replace the aging Xlib code base.
.
This package contains the debugging symbols associated with libxcb0. gdb will
automatically use these symbols when debugging libxcb0.
.
Homepage: http://xcb.freedesktop.org

12
debian/copyright.debian vendored Normal file
View File

@ -0,0 +1,12 @@
This package was debianized by Jamey Sharp <sharpone@debian.org> on
Thu, 18 Mar 2004 00:48:42 -0800, and later updated by Josh Triplett
<josh@freedesktop.org>. The package is co-maintained by the XCB developers
via the XCB mailing list <xcb@lists.freedesktop.org>.
It was downloaded from http://xcb.freedesktop.org.
Upstream Authors: Jamey Sharp <sharpone@debian.org>
Josh Triplett <josh@freedesktop.org>
Copyright:

2
debian/libxcb0-dev.dirs vendored Normal file
View File

@ -0,0 +1,2 @@
usr/lib
usr/include

5
debian/libxcb0-dev.install vendored Normal file
View File

@ -0,0 +1,5 @@
usr/X11R6/include/X11/*
usr/lib/lib*.a
usr/lib/lib*.so
usr/lib/pkgconfig/*
usr/lib/*.la

1
debian/libxcb0.dirs vendored Normal file
View File

@ -0,0 +1 @@
usr/lib

1
debian/libxcb0.install vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/lib*.so.*

22
debian/rules vendored Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/make -f
DEB_DH_INSTALL_SOURCEDIR=debian/tmp
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/autotools.mk
DEB_CONFIGURE_EXTRA_FLAGS = --with-opt
DEB_CONFIGURE_INCLUDEDIR = "\$${prefix}/X11R6/include"
DEB_DH_STRIP_ARGS=--dbg-package=libxcb0
debian/stamp-autotools-files:
autoreconf -v --install
touch debian/stamp-autotools-files
debian/copyright: debian/copyright.debian COPYING
cat $+ > $@
clean::
-rm -f debian/copyright
common-install-prehook-arch common-install-prehook-indep:: debian/copyright

3772
doc/tutorial/index.html Executable file

File diff suppressed because it is too large Load Diff

82
doc/tutorial/xcb.css Executable file
View File

@ -0,0 +1,82 @@
body
{
background-color: #dddddd;
color: #000000;
padding: 8px;
margin: 0px;
}
div.title
{
text-align: center;
font-weight: bold;
font-size: 28px;
}
div.emph
{
text-align: left;
font-weight: bold;
}
div.section li.title
{
font-weight: bold;
font-size: 22px;
}
div.section li.subtitle
{
font-weight: bold;
font-size: 18px;
}
div.section li.subsubtitle
{
font-weight: bold;
font-size: 16px;
}
div.comp
{
border: thin solid #000000;
background-color: #ffffe0;
padding: 14px;
}
div.comp div.title
{
font-weight: bold;
font-size: 16px;
text-align: center;
}
div.comp div.xlib
{
font-family: monospace;
position: absolute;
width: 49%;
margin-left: 0px;
margin-top: 10px;
}
div.comp div.xcb
{
font-family: monospace;
position: relative;
margin-left: 51%;
margin-top: 10px;
}
pre.code
{
border: thin solid #000000;
background-color: #efefef;
padding: 4px;
text-align: left;
font-size: 10;
}
pre.text
{
border: thin solid #000000;
background-color: #efefef;
padding: 4px;
text-align: left;
font-size: 10;
}
span.code
{
font-family: monospace;
font-size: 10;
}

17
src/.cvsignore Normal file
View File

@ -0,0 +1,17 @@
.deps
.libs
Makefile
Makefile.in
config.h
config.h.in
stamp-h1
*.lo
*.loT
*.la
xproto.c
xproto.h
xcb_types.c
xcb_types.h
extensions
X11
check_all

83
src/Makefile.am Normal file
View File

@ -0,0 +1,83 @@
lib_LTLIBRARIES = libXCB.la
EXTHEADERS = \
extensions/bigreq.h \
extensions/composite.h \
extensions/damage.h \
extensions/glx.h \
extensions/shm.h \
extensions/shape.h \
extensions/randr.h \
extensions/record.h \
extensions/render.h \
extensions/res.h \
extensions/dpms.h \
extensions/sync.h \
extensions/xc_misc.h \
extensions/xevie.h \
extensions/xf86dri.h \
extensions/xfixes.h \
extensions/xprint.h \
extensions/xv.h \
extensions/xvmc.h
EXTSOURCES = \
extensions/bigreq.c \
extensions/composite.c \
extensions/damage.c \
extensions/glx.c \
extensions/shm.c \
extensions/shape.c \
extensions/randr.c \
extensions/record.c \
extensions/render.c \
extensions/res.c \
extensions/dpms.c \
extensions/sync.c \
extensions/xc_misc.c \
extensions/xevie.c \
extensions/xf86dri.c \
extensions/xfixes.c \
extensions/xprint.c \
extensions/xv.c \
extensions/xvmc.c
EXTENSIONS = $(EXTSOURCES) $(EXTHEADERS)
COREHEADERS = xproto.h xcb_types.h
CORESOURCES = xproto.c xcb_types.c
COREPROTO = $(CORESOURCES) $(COREHEADERS)
xcbinclude_HEADERS = xcb.h xcbext.h xcbxlib.h $(COREHEADERS) $(EXTHEADERS)
CFLAGS =
AM_CFLAGS = -include config.h $(CDEBUGFLAGS) $(XCBPROTO_CFLAGS) $(XPROTO_CFLAGS) $(XAU_CFLAGS)
libXCB_la_LIBADD = $(XCBPROTO_LIBS) $(XPROTO_LIBS) $(XAU_LIBS)
libXCB_la_SOURCES = \
xcb_conn.c xcb_out.c xcb_in.c xcb_ext.c xcb_xid.c \
xcb_list.c xcb_util.c xcb_xlib.c xcb_auth.c xcb_des.c \
$(COREPROTO) $(EXTENSIONS)
xcb_des.c:
touch xcb_des.c
BUILT_SOURCES = $(COREPROTO) $(EXTENSIONS)
CLEANFILES = $(COREPROTO) $(EXTENSIONS)
clean-local:
rmdir extensions || true
vpath %.xml $(XCBPROTO_XCBINCLUDEDIR) $(XCBPROTO_XCBINCLUDEDIR)/extensions
%.h: %.xml c-client.xsl
@n=`dirname $*`; test -d $$n || (echo mkdir $$n; mkdir $$n)
$(XSLTPROC) --stringparam mode header \
--stringparam base-path $(XCBPROTO_XCBINCLUDEDIR)/ \
--stringparam extension-path \
$(XCBPROTO_XCBINCLUDEDIR)/extensions/ \
-o $@ $(srcdir)/c-client.xsl $<
%.c: %.xml c-client.xsl
@n=`dirname $*`; test -d $$n || (echo mkdir $$n; mkdir $$n)
$(XSLTPROC) --stringparam mode source \
--stringparam base-path $(XCBPROTO_XCBINCLUDEDIR)/ \
--stringparam extension-path \
$(XCBPROTO_XCBINCLUDEDIR)/extensions/ \
-o $@ $(srcdir)/c-client.xsl $<

1301
src/c-client.xsl Normal file

File diff suppressed because it is too large Load Diff

165
src/xcb.h Normal file
View File

@ -0,0 +1,165 @@
/*
* Copyright (C) 2001-2004 Bart Massey, Jamey Sharp, and Josh Triplett.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
#ifndef __XCB_H
#define __XCB_H
#include <X11/Xmd.h>
#include <X11/X.h>
#include <sys/uio.h>
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define deprecated __attribute__((__deprecated__))
#else
#define deprecated
#endif
/* Pre-defined constants */
/* current protocol version */
#define X_PROTOCOL 11
/* current minor version */
#define X_PROTOCOL_REVISION 0
/* X_TCP_PORT + display number = server port for TCP transport */
#define X_TCP_PORT 6000
#define XCB_TYPE_PAD(T,I) (-(I) & (sizeof(T) > 4 ? 3 : sizeof(T) - 1))
/* Opaque structures */
typedef struct XCBConnection XCBConnection;
/* Other types */
typedef struct {
void *data;
int rem;
int index;
} XCBGenericIter;
typedef struct {
BYTE response_type;
CARD8 pad0;
CARD16 sequence;
CARD32 length;
} XCBGenericRep;
typedef struct {
BYTE response_type;
CARD8 pad0;
CARD16 sequence;
} XCBGenericEvent;
typedef struct {
BYTE response_type;
BYTE error_code;
CARD16 sequence;
} XCBGenericError;
typedef struct {
unsigned int sequence;
} XCBVoidCookie;
/* Include the generated xproto and xcb_types headers. */
#include "xcb_types.h"
#include "xproto.h"
/* xcb_auth.c */
typedef struct XCBAuthInfo {
int namelen;
char *name;
int datalen;
char *data;
} XCBAuthInfo;
int XCBGetAuthInfo(int fd, XCBAuthInfo *info) deprecated;
/* xcb_out.c */
int XCBFlush(XCBConnection *c);
CARD32 XCBGetMaximumRequestLength(XCBConnection *c);
/* xcb_in.c */
XCBGenericEvent *XCBWaitEvent(XCBConnection *c) deprecated;
XCBGenericEvent *XCBWaitForEvent(XCBConnection *c);
XCBGenericEvent *XCBPollForEvent(XCBConnection *c, int *error);
unsigned int XCBGetRequestRead(XCBConnection *c);
/* xcb_ext.c */
typedef struct XCBExtension XCBExtension;
/* Do not free the returned XCBQueryExtensionRep - on return, it's aliased
* from the cache. */
const XCBQueryExtensionRep *XCBGetExtensionData(XCBConnection *c, XCBExtension *ext);
void XCBPrefetchExtensionData(XCBConnection *c, XCBExtension *ext);
/* xcb_conn.c */
XCBConnSetupSuccessRep *XCBGetSetup(XCBConnection *c);
int XCBGetFileDescriptor(XCBConnection *c);
XCBConnection *XCBConnectToFD(int fd, XCBAuthInfo *auth_info);
void XCBDisconnect(XCBConnection *c);
/* xcb_util.c */
int XCBParseDisplay(const char *name, char **host, int *display, int *screen);
int XCBOpen(const char *host, int display) deprecated;
int XCBOpenTCP(const char *host, unsigned short port) deprecated;
int XCBOpenUnix(const char *file) deprecated;
XCBConnection *XCBConnectBasic(void) deprecated;
XCBConnection *XCBConnect(const char *displayname, int *screenp);
XCBConnection *XCBConnectToDisplayWithAuthInfo(const char *display, XCBAuthInfo *auth, int *screen);
int XCBSync(XCBConnection *c, XCBGenericError **e);
#ifdef __cplusplus
}
#endif
#endif

296
src/xcb_auth.c Normal file
View File

@ -0,0 +1,296 @@
/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
/* Authorization systems for the X protocol. */
#include <assert.h>
#include <X11/Xauth.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <sys/param.h>
#include <unistd.h>
#include <stdlib.h>
#include "xcb.h"
#include "xcbint.h"
#ifdef HAS_AUTH_XA1
#include "xcb_des.h"
#endif
enum auth_protos {
#ifdef HAS_AUTH_XA1
AUTH_XA1,
#endif
AUTH_MC1,
N_AUTH_PROTOS
};
static char *authnames[N_AUTH_PROTOS] = {
#ifdef HAS_AUTH_XA1
"XDM-AUTHORIZATION-1",
#endif
"MIT-MAGIC-COOKIE-1",
};
#ifdef HAS_AUTH_XA1
static int next_nonce(void)
{
static int nonce = 0;
static pthread_mutex_t nonce_mutex = PTHREAD_MUTEX_INITIALIZER;
int ret;
pthread_mutex_lock(&nonce_mutex);
ret = nonce++;
pthread_mutex_unlock(&nonce_mutex);
return ret;
}
/*
* This code and the code it calls is taken from libXdmcp,
* specifically from Wrap.c, Wrap.h, and Wraphelp.c. The US
* has changed, thank goodness, and it should be OK to bury
* DES code in an open source product without a maze of
* twisty wrapper functions stored offshore. Or maybe
* not. --Bart Massey 2003/11/5
*/
static void
Wrap (
des_cblock input,
des_cblock key,
des_cblock output,
int bytes)
{
int i, j;
int len;
des_cblock tmp;
des_cblock expand_key;
des_key_schedule schedule;
XCBDESKeyToOddParity (key, expand_key);
XCBDESKeySchedule (expand_key, schedule);
for (j = 0; j < bytes; j += 8)
{
len = 8;
if (bytes - j < len)
len = bytes - j;
/* block chaining */
for (i = 0; i < len; i++)
{
if (j == 0)
tmp[i] = input[i];
else
tmp[i] = input[j + i] ^ output[j - 8 + i];
}
for (; i < 8; i++)
{
if (j == 0)
tmp[i] = 0;
else
tmp[i] = 0 ^ output[j - 8 + i];
}
XCBDESEncrypt (tmp, (output + j), schedule, 1);
}
}
#endif
static size_t memdup(char **dst, void *src, size_t len)
{
if(len)
*dst = malloc(len);
else
*dst = 0;
if(!*dst)
return 0;
memcpy(*dst, src, len);
return len;
}
static int authname_match(enum auth_protos kind, char *name, int namelen)
{
if(strlen(authnames[kind]) != namelen)
return 0;
if(memcmp(authnames[kind], name, namelen))
return 0;
return 1;
}
static Xauth *get_authptr(struct sockaddr *sockname, unsigned int socknamelen)
{
char *addr = 0;
int addrlen = 0;
unsigned short family;
char hostnamebuf[256]; /* big enough for max hostname */
char dispbuf[40]; /* big enough to hold more than 2^64 base 10 */
char *display;
int authnamelens[N_AUTH_PROTOS];
int i;
family = FamilyLocal; /* 256 */
switch (sockname->sa_family) {
case AF_INET:
/*block*/ {
struct sockaddr_in *si = (struct sockaddr_in *) sockname;
assert(sizeof(*si) == socknamelen);
addr = (char *) &si->sin_addr;
addrlen = 4;
if (ntohl(si->sin_addr.s_addr) != 0x7f000001)
family = FamilyInternet; /* 0 */
snprintf(dispbuf, sizeof(dispbuf), "%d", ntohs(si->sin_port) - X_TCP_PORT);
display = dispbuf;
}
break;
case AF_UNIX:
/*block*/ {
struct sockaddr_un *su = (struct sockaddr_un *) sockname;
assert(sizeof(*su) >= socknamelen);
display = strrchr(su->sun_path, 'X');
if (display == 0)
return 0; /* sockname is mangled somehow */
display++;
}
break;
default:
return 0; /* cannot authenticate this family */
}
if (family == FamilyLocal) {
if (gethostname(hostnamebuf, sizeof(hostnamebuf)) == -1)
return 0; /* do not know own hostname */
addr = hostnamebuf;
addrlen = strlen(addr);
}
for (i = 0; i < N_AUTH_PROTOS; i++)
authnamelens[i] = strlen(authnames[i]);
return XauGetBestAuthByAddr (family,
(unsigned short) addrlen, addr,
(unsigned short) strlen(display), display,
N_AUTH_PROTOS, authnames, authnamelens);
}
#ifdef HAS_AUTH_XA1
static void do_append(char *buf, int *idxp, void *val, size_t valsize) {
memcpy(buf + *idxp, val, valsize);
*idxp += valsize;
}
#endif
static int compute_auth(XCBAuthInfo *info, Xauth *authptr, struct sockaddr *sockname)
{
if (authname_match(AUTH_MC1, authptr->name, authptr->name_length)) {
info->datalen = memdup(&info->data, authptr->data, authptr->data_length);
if(!info->datalen)
return 0;
return 1;
}
#ifdef HAS_AUTH_XA1
#define APPEND(buf,idx,val) do_append((buf),&(idx),(val),sizeof(val))
if (authname_match(AUTH_XA1, authptr->name, authptr->name_length)) {
int j;
info->data = malloc(192 / 8);
if(!info->data)
return 0;
for (j = 0; j < 8; j++)
info->data[j] = authptr->data[j];
switch(sockname->sa_family) {
case AF_INET:
/*block*/ {
struct sockaddr_in *si = (struct sockaddr_in *) sockname;
APPEND(info->data, j, si->sin_addr.s_addr);
APPEND(info->data, j, si->sin_port);
}
break;
case AF_UNIX:
/*block*/ {
long fakeaddr = htonl(0xffffffff - next_nonce());
short fakeport = htons(getpid());
APPEND(info->data, j, fakeaddr);
APPEND(info->data, j, fakeport);
}
break;
default:
free(info->data);
return 0; /* do not know how to build this */
}
{
long now;
time(&now);
now = htonl(now);
APPEND(info->data, j, now);
}
assert(j <= 192 / 8);
while (j < 192 / 8)
info->data[j++] = 0;
info->datalen = j;
Wrap (info->data, authptr->data + 8, info->data, info->datalen);
return 1;
}
#undef APPEND
#endif
return 0; /* Unknown authorization type */
}
int XCBGetAuthInfo(int fd, XCBAuthInfo *info)
{
/* code adapted from Xlib/ConnDis.c, xtrans/Xtranssocket.c,
xtrans/Xtransutils.c */
char sockbuf[sizeof(struct sockaddr) + MAXPATHLEN];
unsigned int socknamelen = sizeof(sockbuf); /* need extra space */
struct sockaddr *sockname = (struct sockaddr *) &sockbuf;
Xauth *authptr = 0;
int ret = 1;
/* ensure info has reasonable contents */
/* XXX This should be removed, but Jamey depends on it
somehow but can't remember how. Principle: don't touch
someone else's data if you're borken. */
info->namelen = info->datalen = 0;
info->name = info->data = 0;
if (getpeername(fd, sockname, &socknamelen) == -1)
return 0; /* can only authenticate sockets */
authptr = get_authptr(sockname, socknamelen);
if (authptr == 0)
return 0; /* cannot find good auth data */
info->namelen = memdup(&info->name, authptr->name, authptr->name_length);
if(info->namelen)
ret = compute_auth(info, authptr, sockname);
if(!ret)
{
free(info->name);
info->name = 0;
info->namelen = 0;
}
XauDisposeAuth(authptr);
return ret;
}

239
src/xcb_conn.c Normal file
View File

@ -0,0 +1,239 @@
/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
/* Connection management: the core of XCB. */
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/select.h>
#include "xcb.h"
#include "xcbint.h"
static int write_setup(XCBConnection *c, XCBAuthInfo *auth_info)
{
XCBConnSetupReq out;
struct iovec parts[3];
int count = 0;
int endian = 0x01020304;
int ret;
memset(&out, 0, sizeof(out));
/* B = 0x42 = MSB first, l = 0x6c = LSB first */
if(htonl(endian) == endian)
out.byte_order = 0x42;
else
out.byte_order = 0x6c;
out.protocol_major_version = X_PROTOCOL;
out.protocol_minor_version = X_PROTOCOL_REVISION;
out.authorization_protocol_name_len = 0;
out.authorization_protocol_data_len = 0;
parts[count].iov_len = sizeof(XCBConnSetupReq);
parts[count++].iov_base = &out;
if(auth_info)
{
parts[count].iov_len = out.authorization_protocol_name_len = auth_info->namelen;
parts[count++].iov_base = auth_info->name;
parts[count].iov_len = out.authorization_protocol_data_len = auth_info->datalen;
parts[count++].iov_base = auth_info->data;
}
pthread_mutex_lock(&c->iolock);
_xcb_out_write_block(c, parts, count);
ret = _xcb_out_flush(c);
pthread_mutex_unlock(&c->iolock);
if(ret <= 0)
return 0;
return 1;
}
static int read_setup(XCBConnection *c)
{
/* Read the server response */
c->setup = malloc(sizeof(XCBConnSetupGenericRep));
if(!c->setup)
return 0;
if(_xcb_read_block(c->fd, c->setup, sizeof(XCBConnSetupGenericRep)) != sizeof(XCBConnSetupGenericRep))
return 0;
{
void *tmp = realloc(c->setup, c->setup->length * 4 + sizeof(XCBConnSetupGenericRep));
if(!tmp)
return 0;
c->setup = tmp;
}
if(_xcb_read_block(c->fd, (char *) c->setup + sizeof(XCBConnSetupGenericRep), c->setup->length * 4) <= 0)
return 0;
/* 0 = failed, 2 = authenticate, 1 = success */
switch(c->setup->status)
{
case 0: /* failed */
{
XCBConnSetupFailedRep *setup = (XCBConnSetupFailedRep *) c->setup;
write(STDERR_FILENO, XCBConnSetupFailedRepReason(setup), XCBConnSetupFailedRepReasonLength(setup));
return 0;
}
case 2: /* authenticate */
{
XCBConnSetupAuthenticateRep *setup = (XCBConnSetupAuthenticateRep *) c->setup;
write(STDERR_FILENO, XCBConnSetupAuthenticateRepReason(setup), XCBConnSetupAuthenticateRepReasonLength(setup));
return 0;
}
}
return 1;
}
/* Public interface */
XCBConnSetupSuccessRep *XCBGetSetup(XCBConnection *c)
{
/* doesn't need locking because it's never written to. */
return c->setup;
}
int XCBGetFileDescriptor(XCBConnection *c)
{
/* doesn't need locking because it's never written to. */
return c->fd;
}
XCBConnection *XCBConnectToFD(int fd, XCBAuthInfo *auth_info)
{
XCBConnection* c;
c = calloc(1, sizeof(XCBConnection));
if(!c)
return 0;
c->fd = fd;
if(!(
_xcb_set_fd_flags(fd) &&
pthread_mutex_init(&c->iolock, 0) == 0 &&
_xcb_in_init(&c->in) &&
_xcb_out_init(&c->out) &&
write_setup(c, auth_info) &&
read_setup(c) &&
_xcb_ext_init(c) &&
_xcb_xid_init(c)
))
{
XCBDisconnect(c);
return 0;
}
return c;
}
void XCBDisconnect(XCBConnection *c)
{
if(!c)
return;
free(c->setup);
close(c->fd);
pthread_mutex_destroy(&c->iolock);
_xcb_in_destroy(&c->in);
_xcb_out_destroy(&c->out);
_xcb_ext_destroy(c);
_xcb_xid_destroy(c);
free(c);
}
/* Private interface */
int _xcb_conn_wait(XCBConnection *c, const int should_write, pthread_cond_t *cond)
{
int ret = 1;
fd_set rfds, wfds;
#if USE_THREAD_ASSERT
static __thread int already_here = 0;
assert(!already_here);
++already_here;
#endif
_xcb_assert_valid_sequence(c);
/* If the thing I should be doing is already being done, wait for it. */
if(should_write ? c->out.writing : c->in.reading)
{
pthread_cond_wait(cond, &c->iolock);
#if USE_THREAD_ASSERT
--already_here;
#endif
return 1;
}
FD_ZERO(&rfds);
FD_SET(c->fd, &rfds);
++c->in.reading;
FD_ZERO(&wfds);
if(should_write)
{
FD_SET(c->fd, &wfds);
++c->out.writing;
}
pthread_mutex_unlock(&c->iolock);
ret = select(c->fd + 1, &rfds, &wfds, 0, 0);
pthread_mutex_lock(&c->iolock);
if(ret <= 0) /* error: select failed */
goto done;
if(FD_ISSET(c->fd, &rfds))
if((ret = _xcb_in_read(c)) <= 0)
goto done;
if(FD_ISSET(c->fd, &wfds))
if((ret = _xcb_out_write(c)) <= 0)
goto done;
done:
if(should_write)
--c->out.writing;
--c->in.reading;
#if USE_THREAD_ASSERT
--already_here;
#endif
return ret;
}

122
src/xcb_ext.c Normal file
View File

@ -0,0 +1,122 @@
/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
/* A cache for QueryExtension results. */
#include <stdlib.h>
#include <string.h>
#include "xcb.h"
#include "xcbext.h"
#include "xcbint.h"
typedef struct {
enum { LAZY_COOKIE, LAZY_FORCED } tag;
union {
XCBQueryExtensionCookie cookie;
XCBQueryExtensionRep *reply;
} value;
} lazyreply;
static lazyreply *get_lazyreply(XCBConnection *c, XCBExtension *ext)
{
static pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER;
static int next_global_id;
lazyreply *data;
pthread_mutex_lock(&global_lock);
if(!ext->global_id)
ext->global_id = ++next_global_id;
pthread_mutex_unlock(&global_lock);
data = _xcb_map_get(c->ext.extensions, ext->global_id);
if(!data)
{
/* cache miss: query the server */
data = malloc(sizeof(lazyreply));
if(!data)
return 0;
data->tag = LAZY_COOKIE;
data->value.cookie = XCBQueryExtension(c, strlen(ext->name), ext->name);
_xcb_map_put(c->ext.extensions, ext->global_id, data);
}
return data;
}
static void free_lazyreply(void *p)
{
lazyreply *data = p;
if(data->tag == LAZY_FORCED)
free(data->value.reply);
free(data);
}
/* Public interface */
/* Do not free the returned XCBQueryExtensionRep - on return, it's aliased
* from the cache. */
const XCBQueryExtensionRep *XCBGetExtensionData(XCBConnection *c, XCBExtension *ext)
{
lazyreply *data;
pthread_mutex_lock(&c->ext.lock);
data = get_lazyreply(c, ext);
if(data && data->tag == LAZY_COOKIE)
{
data->tag = LAZY_FORCED;
data->value.reply = XCBQueryExtensionReply(c, data->value.cookie, 0);
}
pthread_mutex_unlock(&c->ext.lock);
return data ? data->value.reply : 0;
}
void XCBPrefetchExtensionData(XCBConnection *c, XCBExtension *ext)
{
pthread_mutex_lock(&c->ext.lock);
get_lazyreply(c, ext);
pthread_mutex_unlock(&c->ext.lock);
}
/* Private interface */
int _xcb_ext_init(XCBConnection *c)
{
if(pthread_mutex_init(&c->ext.lock, 0))
return 0;
c->ext.extensions = _xcb_map_new();
if(!c->ext.extensions)
return 0;
return 1;
}
void _xcb_ext_destroy(XCBConnection *c)
{
pthread_mutex_destroy(&c->ext.lock);
_xcb_map_delete(c->ext.extensions, free_lazyreply);
}

319
src/xcb_in.c Normal file
View File

@ -0,0 +1,319 @@
/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
/* Stuff that reads stuff from the server. */
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "xcb.h"
#include "xcbext.h"
#include "xcbint.h"
typedef struct XCBReplyData {
unsigned int request;
void *data;
XCBGenericError **error;
} XCBReplyData;
static int match_request_error(const void *request, const void *data)
{
const XCBGenericError *e = data;
return e->response_type == 0 && e->sequence == ((*(unsigned int *) request) & 0xffff);
}
static int match_reply(const void *request, const void *data)
{
return ((XCBReplyData *) data)->request == *(unsigned int *) request;
}
static void wake_up_next_reader(XCBConnection *c)
{
XCBReplyData *cur = _xcb_list_peek_head(c->in.readers);
int pthreadret;
if(cur)
pthreadret = pthread_cond_signal(cur->data);
else
pthreadret = pthread_cond_signal(&c->in.event_cond);
assert(pthreadret == 0);
}
/* Public interface */
void *XCBWaitForReply(XCBConnection *c, unsigned int request, XCBGenericError **e)
{
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
XCBReplyData reader;
void *ret = 0;
if(e)
*e = 0;
pthread_mutex_lock(&c->iolock);
/* If this request has not been written yet, write it. */
if((signed int) (c->out.request_written - request) < 0)
if(_xcb_out_flush(c) <= 0)
goto done; /* error */
if(_xcb_list_find(c->in.readers, match_reply, &request))
goto done; /* error */
if(e)
{
*e = _xcb_list_remove(c->in.events, match_request_error, &request);
if(*e)
goto done;
}
reader.request = request;
reader.data = &cond;
reader.error = e;
_xcb_list_append(c->in.readers, &reader);
/* If this request has not been read yet, wait for it. */
while(!(e && *e) && ((signed int) (c->in.request_read - request) < 0 ||
(c->in.request_read == request &&
_xcb_queue_is_empty(c->in.current_reply))))
if(_xcb_conn_wait(c, /*should_write*/ 0, &cond) <= 0)
goto done;
if(c->in.request_read != request)
{
_xcb_queue *q = _xcb_map_get(c->in.replies, request);
if(q)
{
ret = _xcb_queue_dequeue(q);
if(_xcb_queue_is_empty(q))
_xcb_queue_delete(_xcb_map_remove(c->in.replies, request), free);
}
}
else
ret = _xcb_queue_dequeue(c->in.current_reply);
done:
_xcb_list_remove(c->in.readers, match_reply, &request);
pthread_cond_destroy(&cond);
wake_up_next_reader(c);
pthread_mutex_unlock(&c->iolock);
return ret;
}
XCBGenericEvent *XCBWaitEvent(XCBConnection *c)
{
return XCBWaitForEvent(c);
}
XCBGenericEvent *XCBWaitForEvent(XCBConnection *c)
{
XCBGenericEvent *ret;
#if XCBTRACEEVENT
fprintf(stderr, "Entering XCBWaitEvent\n");
#endif
pthread_mutex_lock(&c->iolock);
/* _xcb_list_remove_head returns 0 on empty list. */
while(!(ret = _xcb_queue_dequeue(c->in.events)))
if(_xcb_conn_wait(c, /*should_write*/ 0, &c->in.event_cond) <= 0)
break;
wake_up_next_reader(c);
pthread_mutex_unlock(&c->iolock);
#if XCBTRACEEVENT
fprintf(stderr, "Leaving XCBWaitEvent, event type %d\n", ret ? ret->response_type : -1);
#endif
return ret;
}
XCBGenericEvent *XCBPollForEvent(XCBConnection *c, int *error)
{
XCBGenericEvent *ret = 0;
pthread_mutex_lock(&c->iolock);
if(error)
*error = 0;
/* FIXME: follow X meets Z architecture changes. */
if(_xcb_in_read(c) >= 0)
ret = _xcb_queue_dequeue(c->in.events);
else if(error)
*error = -1;
else
{
fprintf(stderr, "XCBPollForEvent: I/O error occured, but no handler provided.\n");
abort();
}
pthread_mutex_unlock(&c->iolock);
return ret;
}
unsigned int XCBGetRequestRead(XCBConnection *c)
{
unsigned int ret;
pthread_mutex_lock(&c->iolock);
/* FIXME: follow X meets Z architecture changes. */
_xcb_in_read(c);
ret = c->in.request_read;
pthread_mutex_unlock(&c->iolock);
return ret;
}
/* Private interface */
int _xcb_in_init(_xcb_in *in)
{
if(pthread_cond_init(&in->event_cond, 0))
return 0;
in->reading = 0;
in->queue_len = 0;
in->request_read = 0;
in->current_reply = _xcb_queue_new();
in->replies = _xcb_map_new();
in->events = _xcb_queue_new();
in->readers = _xcb_list_new();
if(!in->current_reply || !in->replies || !in->events || !in->readers)
return 0;
return 1;
}
void _xcb_in_destroy(_xcb_in *in)
{
pthread_cond_destroy(&in->event_cond);
_xcb_queue_delete(in->current_reply, free);
_xcb_map_delete(in->replies, free);
_xcb_queue_delete(in->events, free);
_xcb_list_delete(in->readers, 0);
}
int _xcb_in_expect_reply(XCBConnection *c, unsigned int request)
{
/* XXX: currently a no-op */
return 1;
}
int _xcb_in_read_packet(XCBConnection *c)
{
XCBGenericRep genrep;
int length = 32;
unsigned char *buf;
/* Wait for there to be enough data for us to read a whole packet */
if(c->in.queue_len < length)
return 0;
/* Get the response type, length, and sequence number. */
memcpy(&genrep, c->in.queue, sizeof(genrep));
/* For reply packets, check that the entire packet is available. */
if(genrep.response_type == 1)
length += genrep.length * 4;
buf = malloc(length);
if(!buf)
return 0;
if(_xcb_in_read_block(c, buf, length) <= 0)
{
free(buf);
return 0;
}
/* Compute 32-bit sequence number of this packet. */
/* XXX: do "sequence lost" check here */
if((genrep.response_type & 0x7f) != KeymapNotify)
{
int lastread = c->in.request_read;
c->in.request_read = (lastread & 0xffff0000) | genrep.sequence;
if(c->in.request_read != lastread && !_xcb_queue_is_empty(c->in.current_reply))
{
_xcb_map_put(c->in.replies, lastread, c->in.current_reply);
c->in.current_reply = _xcb_queue_new();
}
if(c->in.request_read < lastread)
c->in.request_read += 0x10000;
}
if(buf[0] == 1) /* response is a reply */
{
XCBReplyData *reader = _xcb_list_find(c->in.readers, match_reply, &c->in.request_read);
_xcb_queue_enqueue(c->in.current_reply, buf);
if(reader)
pthread_cond_signal(reader->data);
return 1;
}
if(buf[0] == 0) /* response is an error */
{
XCBReplyData *reader = _xcb_list_find(c->in.readers, match_reply, &c->in.request_read);
if(reader && reader->error)
{
*reader->error = (XCBGenericError *) buf;
pthread_cond_signal(reader->data);
return 1;
}
}
/* event, or error without a waiting reader */
_xcb_queue_enqueue(c->in.events, buf);
pthread_cond_signal(&c->in.event_cond);
return 1; /* I have something for you... */
}
int _xcb_in_read(XCBConnection *c)
{
int n = _xcb_readn(c->fd, c->in.queue, sizeof(c->in.queue), &c->in.queue_len);
if(n < 0 && errno == EAGAIN)
n = 1;
while(_xcb_in_read_packet(c) > 0)
/* empty */;
return n;
}
int _xcb_in_read_block(XCBConnection *c, void *buf, int len)
{
int done = c->in.queue_len;
if(len < done)
done = len;
memcpy(buf, c->in.queue, done);
c->in.queue_len -= done;
memmove(c->in.queue, c->in.queue + done, c->in.queue_len);
if(len > done)
{
int ret = _xcb_read_block(c->fd, (char *) buf + done, len - done);
if(ret <= 0)
return ret;
}
return len;
}

215
src/xcb_list.c Normal file
View File

@ -0,0 +1,215 @@
/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
/* A generic implementation of a list of void-pointers. */
#include <stdlib.h>
#include "xcb.h"
#include "xcbint.h"
typedef struct node {
struct node *next;
void *data;
} node;
struct _xcb_list {
node *head;
node **tail;
};
/* Private interface */
_xcb_list *_xcb_list_new()
{
_xcb_list *list;
list = malloc(sizeof(_xcb_list));
if(!list)
return 0;
list->head = 0;
list->tail = &list->head;
return list;
}
static void _xcb_list_clear(_xcb_list *list, XCBListFreeFunc do_free)
{
void *tmp;
while((tmp = _xcb_list_remove_head(list)))
if(do_free)
do_free(tmp);
}
void _xcb_list_delete(_xcb_list *list, XCBListFreeFunc do_free)
{
if(!list)
return;
_xcb_list_clear(list, do_free);
free(list);
}
int _xcb_list_insert(_xcb_list *list, void *data)
{
node *cur;
cur = malloc(sizeof(node));
if(!cur)
return 0;
cur->data = data;
cur->next = list->head;
list->head = cur;
return 1;
}
int _xcb_list_append(_xcb_list *list, void *data)
{
node *cur;
cur = malloc(sizeof(node));
if(!cur)
return 0;
cur->data = data;
cur->next = 0;
*list->tail = cur;
list->tail = &cur->next;
return 1;
}
void *_xcb_list_peek_head(_xcb_list *list)
{
if(!list->head)
return 0;
return list->head->data;
}
void *_xcb_list_remove_head(_xcb_list *list)
{
void *ret;
node *tmp = list->head;
if(!tmp)
return 0;
ret = tmp->data;
list->head = tmp->next;
if(!list->head)
list->tail = &list->head;
free(tmp);
return ret;
}
void *_xcb_list_remove(_xcb_list *list, int (*cmp)(const void *, const void *), const void *data)
{
node **cur;
for(cur = &list->head; *cur; cur = &(*cur)->next)
if(cmp(data, (*cur)->data))
{
node *tmp = *cur;
void *ret = (*cur)->data;
*cur = (*cur)->next;
if(!*cur)
list->tail = cur;
free(tmp);
return ret;
}
return 0;
}
void *_xcb_list_find(_xcb_list *list, int (*cmp)(const void *, const void *), const void *data)
{
node *cur;
for(cur = list->head; cur; cur = cur->next)
if(cmp(data, cur->data))
return cur->data;
return 0;
}
_xcb_queue *_xcb_queue_new(void) __attribute__ ((alias ("_xcb_list_new")));
void _xcb_queue_delete(_xcb_queue *q, XCBListFreeFunc do_free) __attribute__ ((alias ("_xcb_list_delete")));
int _xcb_queue_enqueue(_xcb_queue *q, void *data) __attribute__ ((alias ("_xcb_list_append")));
void *_xcb_queue_dequeue(_xcb_queue *q) __attribute__ ((alias ("_xcb_list_remove_head")));
int _xcb_queue_is_empty(_xcb_queue *q)
{
return q->head == 0;
}
typedef struct {
unsigned int key;
void *value;
} map_pair;
_xcb_map *_xcb_map_new(void) __attribute__ ((alias ("_xcb_list_new")));
void _xcb_map_delete(_xcb_map *q, XCBListFreeFunc do_free)
{
map_pair *tmp;
if(!q)
return;
while((tmp = _xcb_list_remove_head(q)))
{
if(do_free)
do_free(tmp->value);
free(tmp);
}
free(q);
}
int _xcb_map_put(_xcb_map *q, unsigned int key, void *data)
{
map_pair *cur = malloc(sizeof(map_pair));
if(!cur)
return 0;
cur->key = key;
cur->value = data;
if(!_xcb_list_append(q, cur))
{
free(cur);
return 0;
}
return 1;
}
static int match_map_pair(const void *key, const void *pair)
{
return ((map_pair *) pair)->key == *(unsigned int *) key;
}
void *_xcb_map_get(_xcb_map *q, unsigned int key)
{
map_pair *cur = _xcb_list_find(q, match_map_pair, &key);
if(!cur)
return 0;
return cur->value;
}
void *_xcb_map_remove(_xcb_map *q, unsigned int key)
{
map_pair *cur = _xcb_list_remove(q, match_map_pair, &key);
void *ret;
if(!cur)
return 0;
ret = cur->value;
free(cur);
return ret;
}

272
src/xcb_out.c Normal file
View File

@ -0,0 +1,272 @@
/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
/* Stuff that sends stuff to the server. */
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "xcb.h"
#include "xcbext.h"
#include "xcbint.h"
#include "extensions/bigreq.h"
static int force_sequence_wrap(XCBConnection *c)
{
int ret = 1;
if((c->out.request - c->in.request_read) > 65530)
{
pthread_mutex_unlock(&c->iolock);
ret = XCBSync(c, 0);
pthread_mutex_lock(&c->iolock);
}
return ret;
}
/* Public interface */
CARD32 XCBGetMaximumRequestLength(XCBConnection *c)
{
pthread_mutex_lock(&c->out.reqlenlock);
if(!c->out.maximum_request_length)
{
const XCBQueryExtensionRep *ext;
c->out.maximum_request_length = c->setup->maximum_request_length;
ext = XCBGetExtensionData(c, &XCBBigRequestsId);
if(ext && ext->present)
{
XCBBigRequestsEnableRep *r = XCBBigRequestsEnableReply(c, XCBBigRequestsEnable(c), 0);
c->out.maximum_request_length = r->maximum_request_length;
free(r);
}
}
pthread_mutex_unlock(&c->out.reqlenlock);
return c->out.maximum_request_length;
}
int XCBSendRequest(XCBConnection *c, unsigned int *request, struct iovec *vector, const XCBProtocolRequest *req)
{
int ret;
int i;
struct iovec prefix[2];
CARD16 shortlen = 0;
CARD32 longlen = 0;
assert(c != 0);
assert(request != 0);
assert(vector != 0);
assert(req->count > 0);
/* put together the length field, possibly using BIGREQUESTS */
for(i = 0; i < req->count; ++i)
longlen += XCB_CEIL(vector[i].iov_len) >> 2;
if(longlen > c->setup->maximum_request_length)
{
if(longlen > XCBGetMaximumRequestLength(c))
return 0; /* server can't take this; maybe need BIGREQUESTS? */
}
else
{
/* we don't need BIGREQUESTS. */
shortlen = longlen;
longlen = 0;
}
/* set the length field. */
i = 0;
prefix[i].iov_base = vector[0].iov_base;
prefix[i].iov_len = sizeof(CARD32);
vector[0].iov_base = ((char *) vector[0].iov_base) + sizeof(CARD32);
vector[0].iov_len -= sizeof(CARD32);
((CARD16 *) prefix[i].iov_base)[1] = shortlen;
++i;
if(!shortlen)
{
++longlen;
prefix[i].iov_base = &longlen;
prefix[i].iov_len = sizeof(CARD32);
++i;
}
/* set the major opcode, and the minor opcode for extensions */
if(req->ext)
{
const XCBQueryExtensionRep *extension = XCBGetExtensionData(c, req->ext);
/* TODO: better error handling here, please! */
assert(extension && extension->present);
((CARD8 *) prefix[0].iov_base)[0] = extension->major_opcode;
((CARD8 *) prefix[0].iov_base)[1] = req->opcode;
}
else
((CARD8 *) prefix[0].iov_base)[0] = req->opcode;
/* get a sequence number and arrange for delivery. */
pthread_mutex_lock(&c->iolock);
if(req->isvoid && !force_sequence_wrap(c))
{
pthread_mutex_unlock(&c->iolock);
return -1;
}
*request = ++c->out.request;
if(!req->isvoid)
_xcb_in_expect_reply(c, *request);
ret = _xcb_out_write_block(c, prefix, i);
if(ret > 0)
ret = _xcb_out_write_block(c, vector, req->count);
pthread_mutex_unlock(&c->iolock);
return ret;
}
int XCBFlush(XCBConnection *c)
{
int ret;
pthread_mutex_lock(&c->iolock);
ret = _xcb_out_flush(c);
pthread_mutex_unlock(&c->iolock);
return ret;
}
/* Private interface */
int _xcb_out_init(_xcb_out *out)
{
if(pthread_cond_init(&out->cond, 0))
return 0;
out->writing = 0;
out->queue_len = 0;
out->vec = 0;
out->vec_len = 0;
out->last_request = 0;
out->request = 0;
out->request_written = 0;
if(pthread_mutex_init(&out->reqlenlock, 0))
return 0;
out->maximum_request_length = 0;
return 1;
}
void _xcb_out_destroy(_xcb_out *out)
{
pthread_cond_destroy(&out->cond);
pthread_mutex_destroy(&out->reqlenlock);
free(out->vec);
}
int _xcb_out_write(XCBConnection *c)
{
int n;
if(c->out.vec_len)
n = _xcb_writev(c->fd, c->out.vec, c->out.vec_len);
else
n = _xcb_write(c->fd, &c->out.queue, &c->out.queue_len);
if(n < 0 && errno == EAGAIN)
n = 1;
if(c->out.vec_len)
{
int i;
for(i = 0; i < c->out.vec_len; ++i)
if(c->out.vec[i].iov_len)
return n;
c->out.vec_len = 0;
}
return n;
}
int _xcb_out_write_block(XCBConnection *c, struct iovec *vector, size_t count)
{
static const char pad[3];
int i;
int len = 0;
for(i = 0; i < count; ++i)
len += XCB_CEIL(vector[i].iov_len);
/* Is the queue about to overflow? */
if(c->out.queue_len + len < sizeof(c->out.queue))
{
/* No, this will fit. */
for(i = 0; i < count; ++i)
{
memcpy(c->out.queue + c->out.queue_len, vector[i].iov_base, vector[i].iov_len);
if(vector[i].iov_len & 3)
memset(c->out.queue + c->out.queue_len + vector[i].iov_len, 0, XCB_PAD(vector[i].iov_len));
c->out.queue_len += XCB_CEIL(vector[i].iov_len);
}
return len;
}
assert(!c->out.vec_len);
assert(!c->out.vec);
c->out.vec = malloc(sizeof(struct iovec) * (1 + count * 2));
if(!c->out.vec)
return -1;
if(c->out.queue_len)
{
c->out.vec[c->out.vec_len].iov_base = c->out.queue;
c->out.vec[c->out.vec_len++].iov_len = c->out.queue_len;
c->out.queue_len = 0;
}
for(i = 0; i < count; ++i)
{
if(!vector[i].iov_len)
continue;
c->out.vec[c->out.vec_len].iov_base = vector[i].iov_base;
c->out.vec[c->out.vec_len++].iov_len = vector[i].iov_len;
if(!XCB_PAD(vector[i].iov_len))
continue;
c->out.vec[c->out.vec_len].iov_base = (void *) pad;
c->out.vec[c->out.vec_len++].iov_len = XCB_PAD(vector[i].iov_len);
}
if(_xcb_out_flush(c) <= 0)
len = -1;
free(c->out.vec);
c->out.vec = 0;
return len;
}
int _xcb_out_flush(XCBConnection *c)
{
int ret = 1;
while(ret > 0 && (c->out.queue_len || c->out.vec_len))
ret = _xcb_conn_wait(c, /*should_write*/ 1, &c->out.cond);
c->out.last_request = 0;
c->out.request_written = c->out.request;
pthread_cond_broadcast(&c->out.cond);
return ret;
}

279
src/xcb_util.c Normal file
View File

@ -0,0 +1,279 @@
/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
/* Utility functions implementable using only public APIs. */
#include <assert.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/fcntl.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "xcb.h"
#include "xcbext.h"
int XCBPopcount(CARD32 mask)
{
unsigned long y;
y = (mask >> 1) & 033333333333;
y = mask - y - ((y >> 1) & 033333333333);
return ((y + (y >> 3)) & 030707070707) % 077;
}
int XCBParseDisplay(const char *name, char **host, int *displayp, int *screenp)
{
int len, display, screen;
char *colon, *dot, *end;
if(!name || !*name)
name = getenv("DISPLAY");
if(!name)
return 0;
colon = strrchr(name, ':');
if(!colon)
return 0;
len = colon - name;
++colon;
display = strtoul(colon, &dot, 10);
if(dot == colon)
return 0;
if(*dot == '\0')
screen = 0;
else
{
if(*dot != '.')
return 0;
++dot;
screen = strtoul(dot, &end, 10);
if(end == dot || *end != '\0')
return 0;
}
/* At this point, the display string is fully parsed and valid, but
* the caller's memory is untouched. */
*host = malloc(len + 1);
if(!*host)
return 0;
memcpy(*host, name, len);
(*host)[len] = '\0';
*displayp = display;
if(screenp)
*screenp = screen;
return 1;
}
int XCBOpen(const char *host, const int display)
{
int fd;
if(*host)
{
/* display specifies TCP */
unsigned short port = X_TCP_PORT + display;
fd = XCBOpenTCP(host, port);
}
else
{
/* display specifies Unix socket */
static const char base[] = "/tmp/.X11-unix/X";
char file[sizeof(base) + 20];
snprintf(file, sizeof(file), "%s%d", base, display);
fd = XCBOpenUnix(file);
}
return fd;
}
int XCBOpenTCP(const char *host, const unsigned short port)
{
int fd;
struct sockaddr_in addr;
struct hostent *hostaddr = gethostbyname(host);
if(!hostaddr)
return -1;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
memcpy(&addr.sin_addr, hostaddr->h_addr_list[0], sizeof(addr.sin_addr));
fd = socket(PF_INET, SOCK_STREAM, 0);
if(fd == -1)
return -1;
if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
return -1;
return fd;
}
int XCBOpenUnix(const char *file)
{
int fd;
struct sockaddr_un addr = { AF_UNIX };
strcpy(addr.sun_path, file);
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if(fd == -1)
return -1;
if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
return -1;
return fd;
}
XCBConnection *XCBConnect(const char *displayname, int *screenp)
{
int fd, display = 0;
char *host;
XCBConnection *c;
XCBAuthInfo auth;
if(!XCBParseDisplay(displayname, &host, &display, screenp))
return 0;
fd = XCBOpen(host, display);
free(host);
if(fd == -1)
return 0;
XCBGetAuthInfo(fd, &auth);
c = XCBConnectToFD(fd, &auth);
free(auth.name);
free(auth.data);
return c;
}
XCBConnection *XCBConnectToDisplayWithAuthInfo(const char *displayname, XCBAuthInfo *auth, int *screenp)
{
int fd, display = 0;
char *host;
if(!XCBParseDisplay(displayname, &host, &display, screenp))
return 0;
fd = XCBOpen(host, display);
free(host);
if(fd == -1)
return 0;
return XCBConnectToFD(fd, auth);
}
/* backwards compatible interface: remove before 1.0 release */
XCBConnection *XCBConnectBasic()
{
XCBConnection *c = XCBConnect(0, 0);
if(c)
return c;
perror("XCBConnect");
abort();
}
int XCBSync(XCBConnection *c, XCBGenericError **e)
{
XCBGetInputFocusRep *reply = XCBGetInputFocusReply(c, XCBGetInputFocus(c), e);
free(reply);
return reply != 0;
}
/* The functions beyond this point still use only public interfaces,
* but are not themselves part of the public interface. So their
* prototypes are in xcbint.h. */
#include "xcbint.h"
int _xcb_set_fd_flags(const int fd)
{
long flags = fcntl(fd, F_GETFL, 0);
if(flags == -1)
return 0;
flags |= O_NONBLOCK;
if(fcntl(fd, F_SETFL, flags) == -1)
return 0;
if(fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
return 0;
return 1;
}
int _xcb_readn(const int fd, void *buf, const int buflen, int *count)
{
int n = read(fd, ((char *) buf) + *count, buflen - *count);
if(n > 0)
*count += n;
return n;
}
int _xcb_read_block(const int fd, void *buf, const size_t len)
{
int done = 0;
while(done < len)
{
int ret = _xcb_readn(fd, buf, len, &done);
if(ret < 0 && errno == EAGAIN)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
ret = select(fd + 1, &fds, 0, 0, 0);
}
if(ret <= 0)
return ret;
}
return len;
}
int _xcb_write(const int fd, char (*buf)[], int *count)
{
int n = write(fd, *buf, *count);
if(n > 0)
{
*count -= n;
if(*count)
memmove(*buf, *buf + n, *count);
}
return n;
}
int _xcb_writev(const int fd, struct iovec *vec, int count)
{
int n = writev(fd, vec, count);
if(n > 0)
{
int rem = n;
for(; count; --count, ++vec)
{
int cur = vec->iov_len;
if(cur > rem)
cur = rem;
vec->iov_len -= cur;
vec->iov_base = (char *) vec->iov_base + cur;
rem -= cur;
if(vec->iov_len)
break;
}
assert(rem == 0);
}
return n;
}

70
src/xcb_xid.c Normal file
View File

@ -0,0 +1,70 @@
/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
/* XID allocators. */
#include <stdlib.h>
#include "xcb.h"
#include "xcbext.h"
#include "xcbint.h"
#include "extensions/xc_misc.h"
/* Public interface */
CARD32 XCBGenerateID(XCBConnection *c)
{
CARD32 ret;
pthread_mutex_lock(&c->xid.lock);
if(c->xid.last == c->xid.max)
{
XCBXCMiscGetXIDRangeRep *range;
range = XCBXCMiscGetXIDRangeReply(c, XCBXCMiscGetXIDRange(c), 0);
c->xid.last = range->start_id;
c->xid.max = range->start_id + (range->count - 1) * c->xid.inc;
free(range);
}
ret = c->xid.last | c->xid.base;
c->xid.last += c->xid.inc;
pthread_mutex_unlock(&c->xid.lock);
return ret;
}
/* Private interface */
int _xcb_xid_init(XCBConnection *c)
{
if(pthread_mutex_init(&c->xid.lock, 0))
return 0;
c->xid.last = 0;
c->xid.base = c->setup->resource_id_base;
c->xid.max = c->setup->resource_id_mask;
c->xid.inc = c->setup->resource_id_mask & -(c->setup->resource_id_mask);
return 1;
}
void _xcb_xid_destroy(XCBConnection *c)
{
pthread_mutex_destroy(&c->xid.lock);
}

41
src/xcb_xlib.c Normal file
View File

@ -0,0 +1,41 @@
/* Copyright (C) 2005 Bart Massey and Jamey Sharp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
#include "xcbxlib.h"
#include "xcbint.h"
unsigned int XCBGetRequestSent(XCBConnection *c)
{
unsigned int ret;
pthread_mutex_lock(&c->iolock);
ret = c->out.request;
pthread_mutex_unlock(&c->iolock);
return ret;
}
pthread_mutex_t *XCBGetIOLock(XCBConnection *c)
{
return &c->iolock;
}

75
src/xcbext.h Normal file
View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
#ifndef __XCBEXT_H
#define __XCBEXT_H
#include "xcb.h"
#ifdef __cplusplus
extern "C" {
#endif
/* xcb_ext.c */
struct XCBExtension {
const char *name;
int global_id;
};
/* xcb_out.c */
typedef struct {
size_t count;
XCBExtension *ext;
CARD8 opcode;
BOOL isvoid;
} XCBProtocolRequest;
int XCBSendRequest(XCBConnection *c, unsigned int *sequence, struct iovec *vector, const XCBProtocolRequest *request);
/* xcb_in.c */
void *XCBWaitForReply(XCBConnection *c, unsigned int request, XCBGenericError **e);
/* xcb_xid.c */
CARD32 XCBGenerateID(XCBConnection *c);
/* xcb_util.c */
int XCBPopcount(CARD32 mask);
#ifdef __cplusplus
}
#endif
#endif

183
src/xcbint.h Normal file
View File

@ -0,0 +1,183 @@
/*
* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
#ifndef __XCBINT_H
#define __XCBINT_H
/* Not simply (a <= b) because eventually the 32-bit sequence number
* will wrap, causing earlier sequence numbers to be higher than later
* ones for a brief but fatal period. (a and b must be unsigned.) */
#define _xcb_assert_sequence_less(a,b) assert((b) - (a) < 65536)
#define _xcb_assert_valid_sequence(c) do { \
_xcb_assert_sequence_less((c)->in.request_read, (c)->out.request_written); \
_xcb_assert_sequence_less((c)->out.request_written, (c)->out.request); \
} while(0)
/* xcb_list.c */
typedef struct _xcb_list _xcb_list;
typedef void (*XCBListFreeFunc)(void *);
_xcb_list *_xcb_list_new(void);
void _xcb_list_delete(_xcb_list *list, XCBListFreeFunc do_free);
int _xcb_list_insert(_xcb_list *list, void *data);
int _xcb_list_append(_xcb_list *list, void *data);
void *_xcb_list_peek_head(_xcb_list *list);
void *_xcb_list_remove_head(_xcb_list *list);
void *_xcb_list_remove(_xcb_list *list, int (*cmp)(const void *, const void *), const void *data);
void *_xcb_list_find(_xcb_list *list, int (*cmp)(const void *, const void *), const void *data);
typedef _xcb_list _xcb_queue;
_xcb_queue *_xcb_queue_new(void);
void _xcb_queue_delete(_xcb_queue *q, XCBListFreeFunc do_free);
int _xcb_queue_enqueue(_xcb_queue *q, void *data);
void *_xcb_queue_dequeue(_xcb_queue *q);
int _xcb_queue_is_empty(_xcb_queue *q);
typedef _xcb_list _xcb_map;
_xcb_map *_xcb_map_new(void);
void _xcb_map_delete(_xcb_map *q, XCBListFreeFunc do_free);
int _xcb_map_put(_xcb_map *q, unsigned int key, void *data);
void *_xcb_map_get(_xcb_map *q, unsigned int key);
void *_xcb_map_remove(_xcb_map *q, unsigned int key);
/* xcb_util.c */
/* Index of nearest 4-byte boundary following E. */
#define XCB_CEIL(E) (((E)+3)&~3)
#define XCB_PAD(i) ((4 - (i & 3)) & 3)
int _xcb_set_fd_flags(const int fd);
int _xcb_readn(const int fd, void *buf, const int buflen, int *count);
int _xcb_read_block(const int fd, void *buf, const size_t len);
int _xcb_write(const int fd, char (*buf)[], int *count);
int _xcb_writev(const int fd, struct iovec *vec, int count);
/* xcb_out.c */
typedef struct _xcb_out {
pthread_cond_t cond;
int writing;
char queue[4096];
int queue_len;
struct iovec *vec;
int vec_len;
void *last_request;
unsigned int request;
unsigned int request_written;
pthread_mutex_t reqlenlock;
CARD32 maximum_request_length;
} _xcb_out;
int _xcb_out_init(_xcb_out *out);
void _xcb_out_destroy(_xcb_out *out);
int _xcb_out_write(XCBConnection *c);
int _xcb_out_write_block(XCBConnection *c, struct iovec *vector, size_t count);
int _xcb_out_flush(XCBConnection *c);
/* xcb_in.c */
typedef struct _xcb_in {
pthread_cond_t event_cond;
int reading;
char queue[4096];
int queue_len;
unsigned int request_read;
_xcb_queue *current_reply;
_xcb_map *replies;
_xcb_queue *events;
_xcb_list *readers;
} _xcb_in;
int _xcb_in_init(_xcb_in *in);
void _xcb_in_destroy(_xcb_in *in);
int _xcb_in_expect_reply(XCBConnection *c, unsigned int request);
int _xcb_in_read_packet(XCBConnection *c);
int _xcb_in_read(XCBConnection *c);
int _xcb_in_read_block(XCBConnection *c, void *buf, int nread);
/* xcb_xid.c */
typedef struct _xcb_xid {
pthread_mutex_t lock;
CARD32 last;
CARD32 base;
CARD32 max;
CARD32 inc;
} _xcb_xid;
int _xcb_xid_init(XCBConnection *c);
void _xcb_xid_destroy(XCBConnection *c);
/* xcb_ext.c */
typedef struct _xcb_ext {
pthread_mutex_t lock;
_xcb_map *extensions;
} _xcb_ext;
int _xcb_ext_init(XCBConnection *c);
void _xcb_ext_destroy(XCBConnection *c);
/* xcb_conn.c */
struct XCBConnection {
/* constant data */
XCBConnSetupSuccessRep *setup;
int fd;
/* I/O data */
pthread_mutex_t iolock;
_xcb_in in;
_xcb_out out;
/* misc data */
_xcb_ext ext;
_xcb_xid xid;
};
int _xcb_conn_wait(XCBConnection *c, const int should_write, pthread_cond_t *cond);
#endif

38
src/xcbxlib.h Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2005 Bart Massey and Jamey Sharp.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the names of the authors or their
* institutions shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization from the authors.
*/
#ifndef __XCBXLIB_H
#define __XCBXLIB_H
#include <pthread.h>
#include "xcb.h"
unsigned int XCBGetRequestSent(XCBConnection *c);
pthread_mutex_t *XCBGetIOLock(XCBConnection *c);
#endif

2
tests/.cvsignore Normal file
View File

@ -0,0 +1,2 @@
Makefile.in
CheckLog.html

104
tests/CheckLog.xsl Normal file
View File

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:check="http://check.sourceforge.net/ns"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/REC-html40">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<head>
<title>Test Suite Results</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="datetime">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="duration">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="check:suite">
<xsl:apply-templates select="check:title"/>
<center>
<table width="80%" border="1">
<thead>
<tr>
<td>Test Path</td>
<td>Test Function Location</td>
<td>C Identifier</td>
<td>Test Case</td>
<td>Result</td>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="check:test"/>
</tbody>
</table>
</center>
</xsl:template>
<xsl:template match="check:testsuites">
<xsl:apply-templates select="check:suite"/>
<h3>Unit Test Statistics</h3>
<ul>
<li>date/time: <xsl:apply-templates select="check:datetime"/></li>
<li>duration: <xsl:apply-templates select="check:duration"/></li>
</ul>
<hr></hr>
</xsl:template>
<xsl:template match="check:title">
<h2>Test Suite: <xsl:apply-templates/></h2>
</xsl:template>
<xsl:template match="check:test[@result='success']">
<tr bgcolor="lime">
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="check:test[@result='failure']">
<tr bgcolor="red">
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="check:test[@result='error']">
<tr bgcolor="yellow">
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="check:path">
<td><xsl:apply-templates/></td>
</xsl:template>
<xsl:template match="check:fn">
<td><xsl:apply-templates/></td>
</xsl:template>
<xsl:template match="check:id">
<td><xsl:apply-templates/></td>
</xsl:template>
<xsl:template match="check:description">
<td><xsl:apply-templates/></td>
</xsl:template>
<xsl:template match="check:message">
<td><xsl:apply-templates/></td>
</xsl:template>
</xsl:stylesheet>

32
tests/Makefile.am Normal file
View File

@ -0,0 +1,32 @@
########################
## tests/Makefile.am
########################
SUBDIRS =
EXTRA_DIST = CheckLog.xsl
AM_MAKEFLAGS = -k
AM_CFLAGS = -Wall -Werror $(XPROTO_CFLAGS) @CHECK_CFLAGS@ -I$(top_srcdir)/src
LDADD = @CHECK_LIBS@ $(top_builddir)/src/libXCB.la
if HAVE_CHECK
TESTS = check_all
check_PROGRAMS = check_all
check_all_SOURCES = check_all.c check_suites.h check_public.c
all-local::
$(RM) CheckLog*.xml
check-local:
$(RM) CheckLog.html
if test x$(HTML_CHECK_RESULT) = xtrue; then \
$(XSLTPROC) $(srcdir)/CheckLog.xsl CheckLog*.xml > CheckLog.html; \
else \
touch CheckLog.html; \
fi
CheckLog.html: $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) check;
endif
clean-local::
$(RM) CheckLog.html CheckLog*.txt CheckLog*.xml

20
tests/check_all.c Normal file
View File

@ -0,0 +1,20 @@
#include <stdlib.h>
#include "check_suites.h"
void suite_add_test(Suite *s, TFun tf, const char *name)
{
TCase *tc = tcase_create(name);
tcase_add_test(tc, tf);
suite_add_tcase(s, tc);
}
int main(void)
{
int nf;
SRunner *sr = srunner_create(public_suite());
srunner_set_xml(sr, "CheckLog_xcb.xml");
srunner_run_all(sr, CK_NORMAL);
nf = srunner_ntests_failed(sr);
srunner_free(sr);
return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

129
tests/check_public.c Normal file
View File

@ -0,0 +1,129 @@
#include <check.h>
#include <string.h>
#include <stdlib.h>
#include "check_suites.h"
#include "xcb.h"
/* XCBParseDisplay tests {{{ */
static void parse_display_pass(const char *name, const char *host, const int display, const int screen)
{
int success;
char *got_host;
int got_display, got_screen;
got_host = (char *) -1;
got_display = got_screen = -42;
mark_point();
success = XCBParseDisplay(name, &got_host, &got_display, &got_screen);
fail_unless(success, "unexpected parse failure for '%s'", name);
fail_unless(strcmp(host, got_host) == 0, "parse produced unexpected hostname '%s' for '%s': expected '%s'", got_host, name, host);
fail_unless(display == got_display, "parse produced unexpected display '%d' for '%s': expected '%d'", got_display, name, display);
fail_unless(screen == got_screen, "parse produced unexpected screen '%d' for '%s': expected '%d'", got_screen, name, screen);
got_host = (char *) -1;
got_display = got_screen = -42;
mark_point();
success = XCBParseDisplay(name, &got_host, &got_display, 0);
fail_unless(success, "unexpected screenless parse failure for '%s'", name);
fail_unless(strcmp(host, got_host) == 0, "screenless parse produced unexpected hostname '%s' for '%s': expected '%s'", got_host, name, host);
fail_unless(display == got_display, "screenless parse produced unexpected display '%d' for '%s': expected '%d'", got_display, name, display);
}
static void parse_display_fail(const char *name)
{
int success;
char *got_host;
int got_display, got_screen;
got_host = (char *) -1;
got_display = got_screen = -42;
mark_point();
success = XCBParseDisplay(name, &got_host, &got_display, &got_screen);
fail_unless(!success, "unexpected parse success for '%s'", name);
fail_unless(got_host == (char *) -1, "host changed on failure for '%s': got %p", got_host);
fail_unless(got_display == -42, "display changed on failure for '%s': got %d", got_display);
fail_unless(got_screen == -42, "screen changed on failure for '%s': got %d", got_screen);
got_host = (char *) -1;
got_display = got_screen = -42;
mark_point();
success = XCBParseDisplay(name, &got_host, &got_display, 0);
fail_unless(!success, "unexpected screenless parse success for '%s'", name);
fail_unless(got_host == (char *) -1, "host changed on failure for '%s': got %p", got_host);
fail_unless(got_display == -42, "display changed on failure for '%s': got %d", got_display);
}
START_TEST(parse_display_unix)
{
parse_display_pass(":0", "", 0, 0);
parse_display_pass(":1", "", 1, 0);
parse_display_pass(":0.1", "", 0, 1);
}
END_TEST
START_TEST(parse_display_ip)
{
parse_display_pass("x.org:0", "x.org", 0, 0);
parse_display_pass("expo:0", "expo", 0, 0);
parse_display_pass("bigmachine:1", "bigmachine", 1, 0);
parse_display_pass("hydra:0.1", "hydra", 0, 1);
}
END_TEST
START_TEST(parse_display_ipv4)
{
parse_display_pass("198.112.45.11:0", "198.112.45.11", 0, 0);
parse_display_pass("198.112.45.11:0.1", "198.112.45.11", 0, 1);
}
END_TEST
START_TEST(parse_display_ipv6)
{
parse_display_pass("::1:0", "::1", 0, 0);
parse_display_pass("::1:0.1", "::1", 0, 1);
parse_display_pass("2002:83fc:d052::1:0", "2002:83fc:d052::1", 0, 0);
parse_display_pass("2002:83fc:d052::1:0.1", "2002:83fc:d052::1", 0, 1);
}
END_TEST
START_TEST(parse_display_decnet)
{
parse_display_pass("myws::0", "myws:", 0, 0);
parse_display_pass("big::1", "big:", 1, 0);
parse_display_pass("hydra::0.1", "hydra:", 0, 1);
}
END_TEST
START_TEST(parse_display_negative)
{
parse_display_fail(0);
parse_display_fail("");
parse_display_fail(":");
parse_display_fail("::");
parse_display_fail(":.");
parse_display_fail(":a");
parse_display_fail(":a.");
parse_display_fail(":0.");
parse_display_fail(":0.a");
parse_display_fail(":0.0.");
parse_display_fail("localhost");
parse_display_fail("localhost:");
}
END_TEST
/* }}} */
Suite *public_suite(void)
{
Suite *s = suite_create("Public API");
putenv("DISPLAY");
suite_add_test(s, parse_display_unix, "XCBParseDisplay unix");
suite_add_test(s, parse_display_ip, "XCBParseDisplay ip");
suite_add_test(s, parse_display_ipv4, "XCBParseDisplay ipv4");
suite_add_test(s, parse_display_ipv6, "XCBParseDisplay ipv6");
suite_add_test(s, parse_display_decnet, "XCBParseDisplay decnet");
suite_add_test(s, parse_display_negative, "XCBParseDisplay negative");
return s;
}

4
tests/check_suites.h Normal file
View File

@ -0,0 +1,4 @@
#include <check.h>
void suite_add_test(Suite *s, TFun tf, const char *name);
Suite *public_suite(void);

10
xcb.pc.in Normal file
View File

@ -0,0 +1,10 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: XCB
Description: X-protocol C Binding
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lXCB @XPROTO_LIBS@ @LIBS@
Cflags: -I${includedir} @XPROTO_CFLAGS@