summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyungKyu Song <hk76.song@samsung.com>2013-02-16 00:19:35 +0900
committerHyungKyu Song <hk76.song@samsung.com>2013-02-16 00:19:35 +0900
commit7c78c4439637b931665c1f8d0d594b67c043bc9d (patch)
tree8cd57ebf46397e24f3f89e4ad381636d2306ea9c
parente249e7565267f422b71da199144629bffcbda185 (diff)
downloadlibxtst-tizen_2.0.tar.gz
libxtst-tizen_2.0.tar.bz2
libxtst-tizen_2.0.zip
-rw-r--r--COPYING66
-rw-r--r--ChangeLog943
-rw-r--r--INSTALL291
-rw-r--r--Makefile.am42
-rw-r--r--README33
-rw-r--r--configure.ac66
-rw-r--r--docbook.am105
-rw-r--r--include/X11/extensions/XTest.h144
-rw-r--r--include/X11/extensions/record.h183
-rw-r--r--man/Makefile.am78
-rw-r--r--man/XTest.xml413
-rw-r--r--man/XTestCompareCurrentCursorWithWindow.man1
-rw-r--r--man/XTestCompareCursorWithWindow.man1
-rw-r--r--man/XTestDiscard.man1
-rw-r--r--man/XTestFakeButtonEvent.man1
-rw-r--r--man/XTestFakeKeyEvent.man1
-rw-r--r--man/XTestFakeMotionEvent.man1
-rw-r--r--man/XTestFakeRelativeMotionEvent.man1
-rw-r--r--man/XTestGrabControl.man1
-rw-r--r--man/XTestQueryExtension.man288
-rw-r--r--man/XTestSetGContextOfGC.man1
-rw-r--r--man/XTestSetVisualIDOfVisual.man1
-rw-r--r--man/x.stamp0
-rw-r--r--packaging/libXtst.spec83
-rw-r--r--specs/Makefile.am13
-rw-r--r--specs/recordlib.xml1509
-rw-r--r--specs/xtestlib.xml458
-rw-r--r--src/Makefile.am27
-rw-r--r--src/XRecord.c1073
-rw-r--r--src/XTest.c445
-rw-r--r--xtst.pc.in12
31 files changed, 6282 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..3011710
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,66 @@
+Copyright 1990, 1991 by UniSoft Group Limited
+Copyright 1992, 1993, 1995, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+***************************************************************************
+
+Copyright 1995 Network Computing Devices
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Network Computing Devices
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+NETWORK COMPUTING DEVICES DISCLAIMs ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+***************************************************************************
+
+Copyright 2005 Red Hat, Inc.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Red Hat not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission. Red Hat makes no
+representations about the suitability of this software for any purpose. It
+is provided "as is" without express or implied warranty.
+
+RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..4677bec
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,943 @@
+commit eb177d24ffb459af6205d2658c3a158449660caf
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Wed Mar 7 21:11:34 2012 -0800
+
+ libXtst 1.2.1
+
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 6150958c2ae61ce82aa15f3a80107dd01278b255
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Thu Nov 10 21:43:16 2011 -0800
+
+ Fix gcc -Wwrite-strings warnings
+
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 558ec1d7194307d7ce73aeae2f4f61df9d44bba0
+Author: Matt Dew <marcoz@osource.org>
+Date: Tue Oct 4 21:50:03 2011 -0600
+
+ Cleanup IDs and links in doc
+
+ 1 - fix the capitalization of the ID attributes to match either the
+ <title> or <funcdef> string it goes with.
+ 2 - fix any <linkend>'s that were affected by 1.
+ 3 - any <function> in the docs that has an actual funcdef,
+ will become an olink.
+
+ Signed-off-by: Matt Dew <marcoz@osource.org>
+
+commit 262904c22154d5a703ef92a7f954e52956b13663
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Tue Sep 20 15:30:22 2011 -0400
+
+ specs: refactor copyright legal text for multi licensing
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 8f68b59f2b66f035ad97e3fe99e9eae983d1f44b
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Fri Sep 16 22:55:23 2011 -0700
+
+ Strip trailing whitespace
+
+ Performed with: find * -type f | xargs perl -i -p -e 's{[ \t]+$}{}'
+ git diff -w & git diff -b show no diffs from this change
+
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 01dc43ee0fbdb1ed2397a735dfb69b0434600a20
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Fri Sep 16 16:57:52 2011 -0400
+
+ xtestlib: remove duplicate paragraph in legal notice
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit d03495e02bf43e9605671d8f6474c1e9e45261e2
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Fri Sep 16 16:55:48 2011 -0400
+
+ specs: fix author affiliation
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit b5e58980988017265c239a2bad11489a7ab06c23
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Mon Sep 12 16:54:45 2011 -0400
+
+ docs: use the &fullrelvers; entity to set X11 release information
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 743447eaeab62b5e1d5951706cc99d51c0261bbf
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Sun Sep 11 19:49:54 2011 -0400
+
+ docs: remove <productnumber> which is not used by default
+
+ This element is not rendered by default on the title. A template
+ customization is required to display it.
+ X Window System does not have a product number.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit c6be40edba1fe8557ebd0b1cc09b3480bc7d6bb8
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Thu Sep 8 20:00:00 2011 -0400
+
+ docbook.am: embed css styles inside the HTML HEAD element
+
+ Rather than referring to the external xorg.css stylesheet, embed the content
+ of the file in the html output produced. This is accomplished by using
+ version 1.10 of xorg-xhtml.xsl.
+
+ This makes the whole html docs tree much more relocatable.
+ In addition, it eliminates xorg.css as a runtime file which makes
+ xorg-sgml-doctools a build time only package.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit ee829b31b27580afbd6e16f81d9ef3526514be8e
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Wed Sep 7 10:31:04 2011 -0400
+
+ docbook.am: global maintenance update - entities, images and olinking
+
+ Adding support in libX11 for html chunking caused a reorg of docbook.am
+ as well as the xorg-sgml-doctools masterdb for olinking.
+ The parameter img.src.path is added for pdf images.
+ A searchpath to the root builddir is added for local entities, if present.
+
+ The docbook.am makefile hides all the details and is identical for
+ all 22 modules having DocBook documentation. It is included by a thin
+ Makefile.am which requires no docbook knowledge.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit b8c1a91ed12488999dee915953b5bc36019bbf95
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Sun Jun 12 18:39:46 2011 -0400
+
+ Install xml versions of specs even if HAVE_XMLTO is false
+
+ DocBook/XML input source is also a usefull output format that can be viewed
+ with an XML viewer or editor and by some O/S help system.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 9656d08c2c01965aa57f21f29cc2261b9d015b3c
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Sun Jun 5 16:27:37 2011 -0400
+
+ Install target dbs alongside generated documents
+
+ This matches a change in xorg-sgml-docs whereby the masterdb will look for
+ the target dbs into the same location as the generated documents.
+
+ The target dbs are now installed alongside the generated documents.
+ Previously they are installed in $prefix/sgml/X11/dbs alongside masterdb which
+ has the potential of installing outside the package prefix and cause
+ distcheck to fail when user does not have write permission in this package.
+
+ Requires XORG_CHECK_SGML_DOCTOOLS(1.8) which was released 2011-06-11
+
+commit c131572b98342e0e2a599619647dd1835c740ee4
+Author: Matt Dew <marcoz@osource.org>
+Date: Tue May 31 20:03:23 2011 -0600
+
+ Add id attributes to funcsynopsis to allow other docs to olink to them.
+
+ Signed-off-by: Matt Dew <marcoz@osource.org>
+ Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+ Reviewed-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit c82effa402128366bfd3cfb77da82d524ddb878f
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Sun Feb 27 15:06:18 2011 -0500
+
+ Documentation: add Docbook external references support
+
+ When writing technical documentation, it is often necessary to cross
+ reference to other information. When that other information is not in the
+ current document, additional support is needed, namely <olink>.
+
+ A new feature with version 1.7 of xorg-sgml-doctools adds references to
+ other documents within or outside this package.
+
+ This patch adds technical support for this feature but does not change
+ the content of the documentation as seen by the end user.
+
+ Each book or article must generate a database containing the href
+ of sections that can be referred to from another document. This database
+ is installed in DATAROOTDIR/sgml/X11/dbs. There is a requirement that
+ the value of DATAROOTDIR for xorg-sgml-doctools and for the package
+ documentation is the same. This forms a virtual document tree.
+
+ This database is consulted by other documents while they are being generated
+ in order to fulfill the missing information for linking.
+ Refer to the xorg-sgml-doctools for further technical information.
+
+ Co-authored-by: Matt Dew <marcoz@osource.org>
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 755e43b9a05dfce2564cd62cf97364db94a62731
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Wed Feb 2 11:43:45 2011 -0500
+
+ config: comment, minor upgrade, quote and layout configure.ac
+
+ Group statements per section as per Autoconf standard layout
+ Quote statements where appropriate.
+ Autoconf recommends not using dnl instead of # for comments
+
+ Use AC_CONFIG_FILES to replace the deprecated AC_OUTPUT with parameters.
+ Add AC_CONFIG_SRCDIR([Makefile.am])
+
+ This helps automated maintenance and release activities.
+ Details can be found in http://wiki.x.org/wiki/NewModuleGuidelines
+
+commit 97eab9c4e103b6b18f1307d42c4ab15bc80b8db7
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Fri Jan 28 19:41:37 2011 -0500
+
+ config: replace deprecated AM_CONFIG_HEADER with AC_CONFIG_HEADERS
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit a0154ff17ac2f7d08e26e82cc211f61935acf229
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Thu Jan 27 18:50:15 2011 -0500
+
+ config: remove AC_PROG_CC as it overrides AC_PROG_C_C99
+
+ XORG_STRICT_OPTION from XORG_DEFAULT_OPTIONS calls
+ AC_PROG_C_C99. This sets gcc with -std=gnu99.
+ If AC_PROG_CC macro is called afterwards, it resets CC to gcc.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 22ae1c003879ccddb4143669275c5b8071f713a8
+Author: Paulo Zanoni <pzanoni@mandriva.com>
+Date: Thu Dec 16 14:11:43 2010 -0200
+
+ Use docbookx.dtd version 4.3 for all docs
+
+ Signed-off-by: Paulo Zanoni <pzanoni@mandriva.com>
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit e8ac35fac1974b9fd698f74c143c9691af5dd688
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Tue Nov 9 13:04:59 2010 -0500
+
+ config: HTML file generation: use the installed copy of xorg.css
+
+ Currenlty the xorg.css file is copied in each location
+ where a DocBook/XML file resides. This produces about
+ 70 copies in the $(docdir) install tree.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 5c6834bc9e0ab78c78733c59046510a2f48b2d42
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Fri Oct 29 17:38:10 2010 -0700
+
+ libXtst 1.2.0
+
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 109ec12489f050e537d26eed2e60c6d97eb7439f
+Author: Tobias Koch <tobias.koch@nokia.com>
+Date: Wed Sep 29 18:03:30 2010 +0300
+
+ Allow more than 6 axes to be sent.
+
+ From: Tobias Koch <tobias.koch@nokia.com>
+
+ If the number of axes exceeds 6, X server will return BadValue for
+ XTestFakeInput because the number of axes in a single DeviceValuator
+ event is incorrectly set to the total number of axes.
+
+ Signed-off-by: Tobias Koch <tobias.koch@nokia.com>
+ Reviewed-by: Rami Ylimäki <rami.ylimaki@vincit.fi>
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 809ceed85bb577d4bbf80f2d84382375c65b9fbe
+Author: Jesse Adkins <jesserayadkins@gmail.com>
+Date: Tue Sep 28 13:30:04 2010 -0700
+
+ Purge cvs tags.
+
+ Signed-off-by: Jesse Adkins <jesserayadkins@gmail.com>
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 785d8cde2d3beecfb23a9dd9b87bb0d96cf352b8
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Mon Aug 16 11:40:14 2010 -0400
+
+ man: remove unused $(BUILT_SOURCES) variable
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 1dba184f586cc689a79b21b60267c72c2c0172b9
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Mon Aug 16 11:30:23 2010 -0400
+
+ man: remove unused LIB_MAN_DIR_SUFFIX (part of an unrequired broken fix)
+
+ Local fix in CVS for bug 5628 is not required
+ as the problem has been fixed in
+ util-macros d9062e4077ebfd0985baf8418f3d0f111b9ddbba
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 601ea1309d80ba19b4e03207d6fb0f54b2f12730
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Thu Jul 8 15:10:27 2010 -0700
+
+ config: Use additional man page support from util-macros 1.8
+
+ Use MAN_SUBST now supplied in XORG_MANPAGE_SECTIONS
+ The value of MAN_SUBST is the same for all X.Org packages.
+
+ Use AC_PROG_SED now supplied by XORG_DEFAULT_OPTIONS
+ The existing statement can now be removed from the configuration file.
+
+ Use automake provided $(AM_V_GEN) and XORG_DEFAULT_OPTIONS provided $(SED)
+ Enables silent rule and use platform appropriate version of sed.
+
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 672f3ea3431c37ce8f4c33da224287861f64c2a4
+Author: Fernando Carrijo <fcarrijo@yahoo.com.br>
+Date: Thu Jul 1 07:05:16 2010 -0300
+
+ Purge macros NEED_EVENTS and NEED_REPLIES
+
+ Signed-off-by: Fernando Carrijo <fcarrijo@yahoo.com.br>
+ Acked-by: Tiago Vignatti <tiago.vignatti@nokia.com>
+ Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 1676c80db40bffec416da6e3d0002ff9d37093b3
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Sun Jun 27 20:45:38 2010 -0400
+
+ specs: remove trailing spaces in DocBook XML docs
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 96f104f32aef56dd408afbc0d5a073f51e8f0a69
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Sun Jun 27 09:29:26 2010 -0400
+
+ doc: add recordlib converted docbook xml
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit b6a6644e371192be281ff96c59aa39f32ba64a84
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Sat Jun 26 13:36:29 2010 -0400
+
+ doc: replace groff input format with docbook xml format
+
+ Initial version of xtestlib and recordlib docbook xml.
+ recordlib is missing and will be added later
+ Requires util-macros 1.10
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit bbae053ca8bce46639f74f88dc9f687fe53e7c86
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Thu Jun 17 14:45:14 2010 -0400
+
+ specs: translate, format, process, install and distribute.
+
+ Makefile copied from libSM.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit a9e6bb4e4f06b328f03d3d22b6268c4cdd76b702
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Sat Jun 12 09:03:23 2010 -0700
+
+ Sun's copyrights belong to Oracle now
+
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 65daf48de4726cb54c7337563b9d828536916b61
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Sat Jun 12 09:00:56 2010 -0700
+
+ Copy some introductory text from the specs to README
+
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit b2190a83417ae6a4f99ab3acd47ae2c67b5d6693
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Sat Jun 12 08:54:20 2010 -0700
+
+ Move recordlib & testlib specs from xorg-docs module
+
+ Not formatted, translated, processed or installed yet,
+ just moved & added to EXTRA_DIST
+
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit c83fb2aeeb458ead667a1ebe30c5a59b9e786ed3
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Mon Mar 29 16:50:34 2010 -0400
+
+ config: update AC_PREREQ statement to 2.60
+
+ Unrelated to the previous patches, the new value simply reflects
+ the reality that the minimum level for autoconf to configure
+ all x.org modules is 2.60 dated June 2006.
+
+ ftp://ftp.gnu.org/gnu/autoconf/autoconf-2.60.tar.gz
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit f01cb33610654d590339a838f0978386ed8ac5fd
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Mon Mar 29 14:53:49 2010 -0400
+
+ config: remove the pkgconfig pc.in file from EXTRA_DIST
+
+ Automake always includes it in the tarball.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit c4a225f9c96362ca1a2bd98f9c82cb1992d7dd8c
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Thu Mar 11 10:22:59 2010 -0500
+
+ doc: specify 0.0.20 as the minimum version for xmlto
+
+ Older versions do not have fop backend.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit d6b098f463d185e5ed1b45013bd2600c124b7a3a
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Tue Feb 16 10:37:21 2010 -0500
+
+ config: move CWARNFLAGS from configure.ac to Makefile.am
+
+ Compiler warning flags should be explicitly set in the makefile
+ rather than being merged with other packages compiler flags.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit a125ac058be77d81c1806420a7fd1df3b19a6bf4
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Sat Jan 23 10:49:06 2010 -0500
+
+ man: allow installing prebuilt man pages from tarball
+
+ The man pages source may be supplied in the tarball or built
+ from git. The makefile needs to take that into consideration
+ and adjust the targets accordingly.
+
+ Reviewed-by: Dan Nicholson <dbn.lists@gmail.com>
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 1b887152b514c1701e09313dde718fb9e263ff9f
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Mon Jan 18 20:09:55 2010 -0500
+
+ config: replace custom code with reusable macro XORG_WITH_XMLTO
+
+ XORG_WITH_XMLTO provides additional functions like a configure
+ option which allow platform builders to control the usage of
+ the xmlto program.
+
+ This is a requirement from platforms that do not have such doc tool.
+
+ Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit f9ddf6c7bcc3ca2a4745a37d901ab2337b256638
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Thu Jan 14 20:38:59 2010 -0800
+
+ Update Sun license notices to current X.Org standard form
+
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit 5b4cd49321b7f74f6597872977d27e5e1a014f94
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Fri Nov 27 20:56:04 2009 -0500
+
+ Makefile.am: add ChangeLog and INSTALL on MAINTAINERCLEANFILES
+
+ Now that the INSTALL file is generated.
+ Allows running make maintainer-clean.
+
+commit 6757983c1a575a2cc172be70861be70f3e5dc25e
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Wed Oct 28 14:09:10 2009 -0400
+
+ INSTALL, NEWS, README or AUTHORS files are missing/incorrect #24206
+
+ Add missing INSTALL file. Use standard GNU file on building tarball
+ README may have been updated
+ Remove AUTHORS file as it is empty and no content available yet.
+ Remove NEWS file as it is empty and no content available yet.
+
+commit 7855bdbf6df8cb5eca0d44713f33aebc17ef6df8
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Tue Oct 27 15:07:26 2009 -0400
+
+ Deploy the new XORG_DEFAULT_OPTIONS #24242
+
+ This macro aggregate a number of existing macros that sets commmon
+ X.Org components configuration options. It shields the configuration file from
+ future changes.
+
+commit fe3b99e8c996fec849f043ad99e05850f5985b5f
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Mon Oct 26 22:08:43 2009 -0400
+
+ Makefile.am: ChangeLog not required: EXTRA_DIST or *CLEANFILES #24432
+
+ ChangeLog filename is known to Automake and requires no further
+ coding in the makefile.
+
+commit f77d44ecd4ced217745e4f751800152e3fa71c26
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date: Thu Oct 22 12:34:19 2009 -0400
+
+ .gitignore: use common defaults with custom section # 24239
+
+ Using common defaults will reduce errors and maintenance.
+ Only the very small or inexistent custom section need periodic maintenance
+ when the structure of the component changes. Do not edit defaults.
+
+commit c26e9300ce965c394e452b6a02a059b7514994c1
+Author: Jeremy Huddleston <jeremyhu@freedesktop.org>
+Date: Wed Oct 21 12:47:26 2009 -0700
+
+ This is not a GNU project, so declare it foreign.
+
+ On Wed, 2009-10-21 at 13:36 +1000, Peter Hutterer wrote:
+ > On Tue, Oct 20, 2009 at 08:23:55PM -0700, Jeremy Huddleston wrote:
+ > > I noticed an INSTALL file in xlsclients and libXvMC today, and it
+ > > was quite annoying to work around since 'autoreconf -fvi' replaces
+ > > it and git wants to commit it. Should these files even be in git?
+ > > Can I nuke them for the betterment of humanity and since they get
+ > > created by autoreconf anyways?
+ >
+ > See https://bugs.freedesktop.org/show_bug.cgi?id=24206
+
+ As an interim measure, replace AM_INIT_AUTOMAKE([dist-bzip2]) with
+ AM_INIT_AUTOMAKE([foreign dist-bzip2]). This will prevent the generation
+ of the INSTALL file. It is also part of the 24206 solution.
+
+ Signed-off-by: Jeremy Huddleston <jeremyhu@freedesktop.org>
+
+commit ddc11c4ef1bd0e6c970630dea74f54bb2b0ea893
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Mon Oct 5 11:38:38 2009 +1000
+
+ libXtst 1.1.0
+
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit e3d74ecf1a3a7adfeafca8cd02c1da82e95d5eaf
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Mon Oct 5 11:40:53 2009 +1000
+
+ Require libXext 1.0.99.4
+
+ libXext 1.0.99.1 up to including 1.0.99.3 had the XTest.h header which is
+ now in this module.
+
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 7a9b269ed83c106265896373120603b9c06997f3
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Mon Oct 5 10:38:34 2009 +1000
+
+ Require macros 1.3 for XORG_DEFAULT_OPTIONS
+
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 9f727168f561c76c5ae6c3115282ac803172e9f8
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Tue Aug 25 14:09:47 2009 +1000
+
+ Version bump: 1.0.99.2
+
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 527759ae93ceaafca670995ab97545112f89bfbc
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Tue Aug 18 11:12:37 2009 +1000
+
+ Include recordproto.h instead of recordstr.h
+
+commit 849fa907e129575831fbd3fa69249ff843413fd5
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Fri Aug 14 14:15:48 2009 +1000
+
+ Move record headers to here.
+
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 1c928d9c138c90512d534e67e96bced247ca3241
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Fri Aug 14 15:00:15 2009 +1000
+
+ XRecord: avoid use of uninitialised variables.
+
+ Both variables are initialized inside an if condition but later checked for
+ NULL.
+
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit c0404c6db9a8eacc07d140093982b910e54e3f97
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Wed Jul 22 20:34:51 2009 +1000
+
+ Version bump: 1.0.99.1
+
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 3f4b895a29b1b48336621e6dcc80831a5910bed9
+Author: Magnus Kessler <Magnus.Kessler@gmx.net>
+Date: Wed Jul 22 09:29:16 2009 +0100
+
+ Rename xtest.h to xtestconst.h to avoid a collision with XTest.h on case-insensitive filesystems
+
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit ab9ad139b1f20866405ddcc44d25b7b141cd7bce
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Mon Jul 20 13:26:45 2009 +1000
+
+ Move XTest.h header from xextproto/libXext to here.
+
+ XTest.h was in xextproto until xextproto-7.1 and did a short but whoefully
+ misguided visit to libXext during the cleanup of the xextproto headers.
+
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit a119baf3c5aa4f035040e0b991e99e6b382b9670
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Thu Jul 16 09:41:33 2009 +1000
+
+ Include xtestproto.h, not xteststr.h
+
+ Require xextproto 7.0.99.1.
+
+ Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 378db00ee91a11629666fc1c5e5a5e13c65ffefc
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Mon Feb 2 20:34:37 2009 -0800
+
+ Add README with pointers to mailing list, bugzilla & git repos
+
+ Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit 3237cc5b45a41ffe93ebde10b1090a7f2db6f88e
+Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
+Date: Fri Jan 30 20:41:31 2009 -0200
+
+ Janitor: ansification, make distcheck, compiler warnings.
+
+ Manual page generation, and xmlto handling, shamelessly cut&paste'd
+ from libXi/man/Makefile.am, so that make distcheck will work.
+
+commit 48544103324d1816139dfafe5873a11c88ee05b6
+Author: Peter Hutterer <peter.hutterer@redhat.com>
+Date: Fri Aug 8 10:18:19 2008 +0930
+
+ Require xi.pc for XInput.h include.
+
+ XInput.h is now part of libXi. But just in case we have an older version of
+ libXi floating around, pull in inputproto too.
+
+commit 5b4ba84a422d168c01b335c4fc4046a7316463e0
+Author: Ian Romanick <idr@us.ibm.com>
+Date: Wed May 21 12:38:00 2008 -0700
+
+ Add .PHONY build target to fix parallel builds
+
+commit 56bc832134b4f6884999797f0f0c1b846602088d
+Author: Peter Hutterer <peter@cs.unisa.edu.au>
+Date: Mon May 19 17:38:08 2008 +0930
+
+ Rename parameters to clarify QueryExtension call.
+
+ These parameters are not treated as input. Rename them to make the inner
+ workings slightly more obvious.
+
+ X.Org Bug 14511 <http://bugs.freedesktop.org/show_bug.cgi?id=14511>
+
+commit f3971bca54ff6018758642303108eec975d80cd5
+Author: James Cloos <cloos@jhcloos.com>
+Date: Thu Dec 6 15:51:20 2007 -0500
+
+ Add missing PHONY line for automatic ChangeLog generation
+
+commit 8db9ffdf7a16162cd81da2bf1e914ecf3981d0ee
+Author: Egbert Eich <eich@freedesktop.org>
+Date: Tue Oct 16 14:27:57 2007 +0200
+
+ Wrong place. Reverting srcdir patch.
+
+commit 7684e7da5648fb8664c145a5f4d79d8e2d085808
+Author: Egbert Eich <eich@freedesktop.org>
+Date: Mon Oct 15 11:44:53 2007 +0200
+
+ Fix man page build when srcdir is specified.
+
+commit 4a5ac6a63c22bdfac9a873803f3a0fa3d6e20a5b
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Fri Aug 17 14:57:22 2007 -0700
+
+ Version bump: 1.0.3
+
+commit fe206f87078c90afaa5eba42a4bbe1c0ea300e9b
+Author: zoka <zoran@microtrol.com.au>
+Date: Mon Jul 2 20:34:52 2007 -0700
+
+ libXtst man pages generation fails if srcdir != builddir
+
+commit a8738715dd5b74f0dec904c83b732ef6471be0db
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Wed Jun 6 18:57:12 2007 -0700
+
+ Version bump: 1.0.2
+
+commit 8bbc3b75318c67f6089d50f68d53d092390c8233
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Wed Jun 6 18:41:36 2007 -0700
+
+ Replace static ChangeLog with dist-hook to generate from git
+
+commit 6aaa875dffbcc5dd2206644cfa73fdfd8ffe280f
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Wed Jun 6 18:13:32 2007 -0700
+
+ Convert man page to docbook/xml (thanks to doclifter)
+
+commit d9514f97f54b47630b645ef44a5d40262a10d33a
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Wed Jun 6 16:39:01 2007 -0700
+
+ Add man pages for XTest*() functions
+
+ Converted xorg-docs/Xext/xtestlib.ms to man page formatting
+
+commit 68a28875bc7a2cd760f035508997dfd88b3b6cc8
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Wed Jun 6 14:43:59 2007 -0700
+
+ Fill in COPYING file with real copyright/licenses
+
+commit 931675017dd28ccca8353abeff3055f0c47bc3b2
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Wed Jun 6 14:36:43 2007 -0700
+
+ Coverity #578/579: Don't leak memory if one malloc fails but other succeeds
+
+ (Unlikely to happen, since the smaller malloc was first, but still possible.)
+
+commit dab4830b8db0d3cf5db5e96b2b870e94a48330bc
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Wed Jun 6 14:23:17 2007 -0700
+
+ ANSIfy static function declarations (clears some lint warnings)
+
+commit 57a201a15637cfea6c15a4d0ed8b629c9cd49495
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Wed Jun 6 14:11:04 2007 -0700
+
+ Add hooks to check code with sparse/lint
+
+commit 5e791a1465aba3b8be89b4cf2d9f90dee18e8e96
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Wed Jun 6 14:10:44 2007 -0700
+
+ Add *~ to .gitignore to skip emacs/patch droppings
+
+commit 68ca8cd2ba9877ee2e3695783f3a8445ab366ea8
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date: Thu Jul 13 14:59:09 2006 -0700
+
+ renamed: .cvsignore -> .gitignore
+
+commit 1f76457e307db2cec4c7f1e4b66dab597271fc86
+Author: Kevin E Martin <kem@kem.org>
+Date: Wed Dec 21 02:30:06 2005 +0000
+
+ Update package version for X11R7 release.
+
+commit 0f5c2436708a0d399f8fc348902518a9117728ac
+Author: Adam Jackson <ajax@nwnk.net>
+Date: Mon Dec 19 16:28:27 2005 +0000
+
+ Stub COPYING files
+
+commit b5670af70e2e29f67639e85106817740c83ccc8d
+Author: Kevin E Martin <kem@kem.org>
+Date: Thu Dec 15 00:24:35 2005 +0000
+
+ Update package version number for final X11R7 release candidate.
+
+commit c68f6e145fac21f3fc6fe7d09b5e8639538d54e1
+Author: Kevin E Martin <kem@kem.org>
+Date: Sat Dec 3 05:49:45 2005 +0000
+
+ Update package version number for X11R7 RC3 release.
+
+commit 1d76bb2d8bb23d91a64c23923fc819af0badb57b
+Author: Kevin E Martin <kem@kem.org>
+Date: Sat Nov 19 07:15:43 2005 +0000
+
+ Update pkgconfig files to separate library build-time dependencies from
+ application build-time dependencies, and update package deps to work
+ with separate build roots.
+
+commit 3e0b2a05fcfb60561402b46318bd152b466509f9
+Author: Kevin E Martin <kem@kem.org>
+Date: Wed Nov 9 21:19:13 2005 +0000
+
+ Update package version number for X11R7 RC2 release.
+
+commit c753f306d0bda3dc3009ad273e9cd3548ea13bb8
+Author: Kevin E Martin <kem@kem.org>
+Date: Tue Nov 1 15:11:52 2005 +0000
+
+ Update pkgcheck dependencies to work with separate build roots.
+
+commit 36c47a88481794b25118870a6caf93d2b2ca9344
+Author: Kevin E Martin <kem@kem.org>
+Date: Wed Oct 19 02:48:12 2005 +0000
+
+ Update package version number for RC1 release.
+
+commit 6578854789201d229f20ae560d4b7051e9402c84
+Author: Adam Jackson <ajax@nwnk.net>
+Date: Wed Aug 3 03:28:02 2005 +0000
+
+ Do PKG_CHECK_MODULES on a unique token instead of on "DEP", so builds with
+ a global configure cache don't get confused.
+
+commit aa10e9ef0425286da35fb3312dd6df31066c627a
+Author: Kevin E Martin <kem@kem.org>
+Date: Fri Jul 29 21:22:53 2005 +0000
+
+ Various changes preparing packages for RC0:
+ - Verify and update package version numbers as needed
+ - Implement versioning scheme
+ - Change bug address to point to bugzilla bug entry form
+ - Disable loadable i18n in libX11 by default (use --enable-loadable-i18n to
+ reenable it)
+ - Fix makedepend to use pkgconfig and pass distcheck
+ - Update build script to build macros first
+ - Update modular Xorg version
+
+commit a72494febb5b14a5ad860f1048ff11bdd83bbe53
+Author: Daniel Stone <daniel@fooishbar.org>
+Date: Sat Jul 16 07:39:26 2005 +0000
+
+ Set soversion to 6.1.0 with -version-number.
+
+commit 9001f6684617761cf258e71259f98f85c02f33d1
+Author: Adam Jackson <ajax@nwnk.net>
+Date: Thu Jul 14 15:07:42 2005 +0000
+
+ more trailing whitespace
+
+commit 3568421ddbec548cff7b49eb339d5bafaab2cbd3
+Author: Keith Packard <keithp@keithp.com>
+Date: Sat Jul 9 06:50:41 2005 +0000
+
+ Add .cvsignore files Switch _la_CFLAGS for AM_CFLAGS to clean up directory
+
+commit 1f8c48e0574892a0b3fe359fb65523d7d1dcc236
+Author: Kevin E Martin <kem@kem.org>
+Date: Sat Jul 2 06:35:03 2005 +0000
+
+ Add appropriate lib*_CFLAGS to Makefile.am's -- fixes build problems
+
+commit 250934b516532e24e48a9aa93dd389493acc4f53
+Author: Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de>
+Date: Tue Jun 21 15:41:36 2005 +0000
+
+ lib/XScrnSaver/configure.ac
+ lib/XScrnSaver/src/Makefile.am
+ lib/Xfontcache/configure.ac
+ lib/Xfontcache/src/Makefile.am
+ lib/Xinerama/configure.ac
+ lib/Xinerama/src/Makefile.am
+ lib/Xtst/configure.ac
+ lib/Xv/configure.ac
+ lib/XvMC/configure.ac
+ lib/dmx/configure.ac Add missing xext.pc and xextproto.pc Add DEP_CFLAGS to
+ src/Makefile.am
+
+commit dbedf673f50e0baf6d5af60f60dbd16368071ed4
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date: Mon Jun 13 19:44:25 2005 +0000
+
+ - Add Xtst to symlink.sh
+ - Add Xtst build system
+
+commit e2cdce7dab4c62bdfcff33ee9270f6a7703352ef
+Author: Egbert Eich <eich@suse.de>
+Date: Mon May 24 19:06:58 2004 +0000
+
+ Fix build glitches when building modules independently using Imake.
+
+commit 3bb9e7d92569600697ec398e9cff01e50101ff22
+Author: Egbert Eich <eich@suse.de>
+Date: Fri Apr 23 18:43:55 2004 +0000
+
+ Merging XORG-CURRENT into trunk
+
+commit 91ddef6b5dec497a7501fc7a9416cfc6454824f3
+Author: Egbert Eich <eich@suse.de>
+Date: Sun Mar 14 08:32:27 2004 +0000
+
+ Importing vendor version xf86-4_4_99_1 on Sun Mar 14 00:26:39 PST 2004
+
+commit efc2b386671de52b5454a336dab4afa3aeabd340
+Author: Egbert Eich <eich@suse.de>
+Date: Wed Mar 3 12:11:32 2004 +0000
+
+ Importing vendor version xf86-4_4_0 on Wed Mar 3 04:09:24 PST 2004
+
+commit b7c0ec40d3045f024bb74292189f72cdf7a1cd14
+Author: Egbert Eich <eich@suse.de>
+Date: Thu Feb 26 13:35:34 2004 +0000
+
+ readding XFree86's cvs IDs
+
+commit 2f5a9d8afe48466be084cea784ac73e932655f6e
+Author: Egbert Eich <eich@suse.de>
+Date: Thu Feb 26 09:22:48 2004 +0000
+
+ Importing vendor version xf86-4_3_99_903 on Wed Feb 26 01:21:00 PST 2004
+
+commit 7aea93fb6b188b32b0be32f064997aabe8d7bdda
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date: Tue Nov 25 19:28:16 2003 +0000
+
+ XFree86 4.3.99.16 Bring the tree up to date for the Cygwin folks
+
+commit 88eb8a804d05b72091309323ad2df962a1ed7b8d
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date: Fri Nov 14 16:48:49 2003 +0000
+
+ XFree86 4.3.0.1
+
+commit 65a2b6d50473730673749ad2facc248ea41af00a
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date: Fri Nov 14 15:54:39 2003 +0000
+
+ R6.6 is the Xorg base-line
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..8b82ade
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,291 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008 Free Software Foundation, Inc.
+
+ This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+ Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+ 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 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.
+
+ Running `configure' might take a while. 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.
+
+ 6. Often, you can also type `make uninstall' to remove the installed
+ files again.
+
+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=c99 CFLAGS=-g 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 can use 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 `..'.
+
+ With a non-GNU `make', it is safer 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.
+
+ On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor. Like
+this:
+
+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CPP="gcc -E" CXXCPP="g++ -E"
+
+ This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+ By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' 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.
+
+Particular systems
+==================
+
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+ ./configure CC="cc -Ae"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file. The option `-nodtk' can be used as
+a workaround. If GNU CC is not installed, it is therefore recommended
+to try
+
+ ./configure CC="cc"
+
+and if that doesn't work, try
+
+ ./configure CC="cc -nodtk"
+
+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 option `--target=TYPE' 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
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+ Print a summary of the options unique to this package's
+ `configure', and exit. The `short' variant lists options used
+ only in the top level, while the `recursive' variant lists options
+ also present in any nested packages.
+
+`--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.
+
+`--prefix=DIR'
+ Use DIR as the installation prefix. *Note Installation Names::
+ for more details, including other options available for fine-tuning
+ the installation locations.
+
+`--no-create'
+`-n'
+ Run the configure checks, but stop before creating any output
+ files.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..da9d32f
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,42 @@
+#
+# Copyright 2005 Red Hat, Inc.
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of Red Hat not be used in
+# advertising or publicity pertaining to distribution of the software without
+# specific, written prior permission. Red Hat makes no
+# representations about the suitability of this software for any purpose. It
+# is provided "as is" without express or implied warranty.
+#
+# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+# EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+SUBDIRS = src man specs
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = xtst.pc
+
+MAINTAINERCLEANFILES = ChangeLog INSTALL
+
+.PHONY: ChangeLog INSTALL
+
+INSTALL:
+ $(INSTALL_CMD)
+
+ChangeLog:
+ $(CHANGELOG_CMD)
+
+dist-hook: ChangeLog INSTALL
+
+if LINT
+lint:
+ (cd src && $(MAKE) $(MFLAGS) lint)
+endif LINT
diff --git a/README b/README
new file mode 100644
index 0000000..c83d9fe
--- /dev/null
+++ b/README
@@ -0,0 +1,33 @@
+libXtst provides the Xlib-based client API for the XTEST & RECORD extensions.
+
+The XTEST extension is a minimal set of client and server extensions
+required to completely test the X11 server with no user intervention.
+This extension is not intended to support general journaling and
+playback of user actions.
+
+The RECORD extension supports the recording and reporting of all
+core X protocol and arbitrary X extension protocol.
+
+All questions regarding this software should be directed at the
+Xorg mailing list:
+
+ http://lists.freedesktop.org/mailman/listinfo/xorg
+
+Please submit bug reports to the Xorg bugzilla:
+
+ https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
+
+The master development code repository can be found at:
+
+ git://anongit.freedesktop.org/git/xorg/lib/libXtst
+
+ http://cgit.freedesktop.org/xorg/lib/libXtst
+
+For patch submission instructions, see:
+
+ http://www.x.org/wiki/Development/Documentation/SubmittingPatches
+
+For more information on the git code manager, see:
+
+ http://wiki.x.org/wiki/GitPage
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..1f2927f
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,66 @@
+
+# Copyright 2005 Red Hat, Inc.
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of Red Hat not be used in
+# advertising or publicity pertaining to distribution of the software without
+# specific, written prior permission. Red Hat makes no
+# representations about the suitability of this software for any purpose. It
+# is provided "as is" without express or implied warranty.
+#
+# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+# EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+
+# Initialize Autoconf
+AC_PREREQ([2.60])
+AC_INIT([libXtst], [1.2.1],
+ [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXtst])
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_HEADERS([config.h])
+
+# Initialize Automake
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AM_MAINTAINER_MODE
+
+# Initialize libtool
+AC_PROG_LIBTOOL
+
+# Require xorg-macros minimum of 1.12 for DocBook external references
+m4_ifndef([XORG_MACROS_VERSION],
+ [m4_fatal([must install xorg-macros 1.12 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.12)
+XORG_DEFAULT_OPTIONS
+XORG_ENABLE_SPECS
+XORG_WITH_XMLTO(0.0.22)
+XORG_WITH_FOP
+XORG_WITH_XSLTPROC
+XORG_CHECK_SGML_DOCTOOLS(1.8)
+
+# Obtain compiler/linker options for depedencies
+PKG_CHECK_MODULES(XTST, x11 [xext >= 1.0.99.4] xi [recordproto >= 1.13.99.1] [xextproto >= 7.0.99.3] inputproto)
+
+# Determine if the source for man pages is available
+# It may already be present (tarball) or can be generated using xmlto
+AM_CONDITIONAL([INSTALL_MANPAGES],
+ [test -f "$srcdir/man/XTestQueryExtension.man" || test "x$have_xmlto" = xyes])
+
+# Allow checking code with lint, sparse, etc.
+XORG_WITH_LINT
+XORG_LINT_LIBRARY([Xtst])
+LINT_FLAGS="${LINT_FLAGS} ${XTST_CFLAGS}"
+
+AC_CONFIG_FILES([Makefile
+ man/Makefile
+ src/Makefile
+ specs/Makefile
+ xtst.pc])
+AC_OUTPUT
diff --git a/docbook.am b/docbook.am
new file mode 100644
index 0000000..bba4d54
--- /dev/null
+++ b/docbook.am
@@ -0,0 +1,105 @@
+#
+# Generate output formats for a single DocBook/XML with/without chapters
+#
+# Variables set by the calling Makefile:
+# shelfdir: the location where the docs/specs are installed. Typically $(docdir)
+# docbook: the main DocBook/XML file, no chapters, appendix or image files
+# chapters: all files pulled in by an XInclude statement and images.
+#
+
+#
+# This makefile is intended for Users Documentation and Functional Specifications.
+# Do not use for Developer Documentation which is not installed and does not require olink.
+# Refer to http://www.x.org/releases/X11R7.6/doc/xorg-docs/ReleaseNotes.html#id2584393
+# for an explanation on documents classification.
+#
+
+# DocBook/XML generated output formats to be installed
+shelf_DATA =
+
+# DocBook/XML file with chapters, appendix and images it includes
+dist_shelf_DATA = $(docbook) $(chapters)
+
+if HAVE_XMLTO
+if HAVE_STYLESHEETS
+
+XMLTO_SEARCHPATH_FLAGS = \
+ --searchpath "$(XORG_SGML_PATH)/X11" \
+ --searchpath "$(abs_top_builddir)"
+XMLTO_HTML_OLINK_FLAGS = \
+ --stringparam target.database.document=$(XORG_SGML_PATH)/X11/dbs/masterdb.html.xml \
+ --stringparam current.docid="$(<:.xml=)"
+XMLTO_HTML_STYLESHEET_FLAGS = -x $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl
+XMLTO_HTML_FLAGS = \
+ $(XMLTO_SEARCHPATH_FLAGS) \
+ $(XMLTO_HTML_STYLESHEET_FLAGS) \
+ $(XMLTO_HTML_OLINK_FLAGS)
+
+shelf_DATA += $(docbook:.xml=.html)
+%.html: %.xml $(chapters)
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) xhtml-nochunks $<
+
+if HAVE_XMLTO_TEXT
+
+shelf_DATA += $(docbook:.xml=.txt)
+%.txt: %.xml $(chapters)
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) txt $<
+endif HAVE_XMLTO_TEXT
+
+if HAVE_FOP
+XMLTO_FO_IMAGEPATH_FLAGS = --stringparam img.src.path=$(abs_builddir)/
+XMLTO_PDF_OLINK_FLAGS = \
+ --stringparam target.database.document=$(XORG_SGML_PATH)/X11/dbs/masterdb.pdf.xml \
+ --stringparam current.docid="$(<:.xml=)"
+XMLTO_FO_STYLESHEET_FLAGS = -x $(STYLESHEET_SRCDIR)/xorg-fo.xsl
+
+XMLTO_FO_FLAGS = \
+ $(XMLTO_SEARCHPATH_FLAGS) \
+ $(XMLTO_FO_STYLESHEET_FLAGS) \
+ $(XMLTO_FO_IMAGEPATH_FLAGS) \
+ $(XMLTO_PDF_OLINK_FLAGS)
+
+shelf_DATA += $(docbook:.xml=.pdf)
+%.pdf: %.xml $(chapters)
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop pdf $<
+
+shelf_DATA += $(docbook:.xml=.ps)
+%.ps: %.xml $(chapters)
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop ps $<
+endif HAVE_FOP
+
+# Generate documents cross-reference target databases
+if HAVE_XSLTPROC
+
+XSLT_SEARCHPATH_FLAGS = \
+ --path "$(XORG_SGML_PATH)/X11" \
+ --path "$(abs_top_builddir)"
+XSLT_OLINK_FLAGS = \
+ --stringparam targets.filename "$@" \
+ --stringparam collect.xref.targets "only" \
+ --stringparam olink.base.uri "$(@:.db=)"
+
+XSLT_HTML_FLAGS = \
+ $(XSLT_SEARCHPATH_FLAGS) \
+ $(XSLT_OLINK_FLAGS) \
+ --nonet --xinclude \
+ $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl
+XSLT_PDF_FLAGS = \
+ $(XSLT_SEARCHPATH_FLAGS) \
+ $(XSLT_OLINK_FLAGS) \
+ --nonet --xinclude \
+ $(STYLESHEET_SRCDIR)/xorg-fo.xsl
+
+shelf_DATA += $(docbook:.xml=.html.db)
+%.html.db: %.xml $(chapters)
+ $(AM_V_GEN)$(XSLTPROC) $(XSLT_HTML_FLAGS) $<
+
+shelf_DATA += $(docbook:.xml=.pdf.db)
+%.pdf.db: %.xml $(chapters)
+ $(AM_V_GEN)$(XSLTPROC) $(XSLT_PDF_FLAGS) $<
+
+endif HAVE_XSLTPROC
+endif HAVE_STYLESHEETS
+endif HAVE_XMLTO
+
+CLEANFILES = $(shelf_DATA)
diff --git a/include/X11/extensions/XTest.h b/include/X11/extensions/XTest.h
new file mode 100644
index 0000000..f973aeb
--- /dev/null
+++ b/include/X11/extensions/XTest.h
@@ -0,0 +1,144 @@
+/*
+
+Copyright 1992, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+#ifndef _XTEST_H_
+#define _XTEST_H_
+
+#include <X11/Xfuncproto.h>
+#include <X11/extensions/xtestconst.h>
+#include <X11/extensions/XInput.h>
+
+_XFUNCPROTOBEGIN
+
+Bool XTestQueryExtension(
+ Display* /* dpy */,
+ int* /* event_basep */,
+ int* /* error_basep */,
+ int* /* majorp */,
+ int* /* minorp */
+);
+
+Bool XTestCompareCursorWithWindow(
+ Display* /* dpy */,
+ Window /* window */,
+ Cursor /* cursor */
+);
+
+Bool XTestCompareCurrentCursorWithWindow(
+ Display* /* dpy */,
+ Window /* window */
+);
+
+extern int XTestFakeKeyEvent(
+ Display* /* dpy */,
+ unsigned int /* keycode */,
+ Bool /* is_press */,
+ unsigned long /* delay */
+);
+
+extern int XTestFakeButtonEvent(
+ Display* /* dpy */,
+ unsigned int /* button */,
+ Bool /* is_press */,
+ unsigned long /* delay */
+);
+
+extern int XTestFakeMotionEvent(
+ Display* /* dpy */,
+ int /* screen */,
+ int /* x */,
+ int /* y */,
+ unsigned long /* delay */
+);
+
+extern int XTestFakeRelativeMotionEvent(
+ Display* /* dpy */,
+ int /* x */,
+ int /* y */,
+ unsigned long /* delay */
+);
+
+extern int XTestFakeDeviceKeyEvent(
+ Display* /* dpy */,
+ XDevice* /* dev */,
+ unsigned int /* keycode */,
+ Bool /* is_press */,
+ int* /* axes */,
+ int /* n_axes */,
+ unsigned long /* delay */
+);
+
+extern int XTestFakeDeviceButtonEvent(
+ Display* /* dpy */,
+ XDevice* /* dev */,
+ unsigned int /* button */,
+ Bool /* is_press */,
+ int* /* axes */,
+ int /* n_axes */,
+ unsigned long /* delay */
+);
+
+extern int XTestFakeProximityEvent(
+ Display* /* dpy */,
+ XDevice* /* dev */,
+ Bool /* in_prox */,
+ int* /* axes */,
+ int /* n_axes */,
+ unsigned long /* delay */
+);
+
+extern int XTestFakeDeviceMotionEvent(
+ Display* /* dpy */,
+ XDevice* /* dev */,
+ Bool /* is_relative */,
+ int /* first_axis */,
+ int* /* axes */,
+ int /* n_axes */,
+ unsigned long /* delay */
+);
+
+extern int XTestGrabControl(
+ Display* /* dpy */,
+ Bool /* impervious */
+);
+
+void XTestSetGContextOfGC(
+ GC /* gc */,
+ GContext /* gid */
+);
+
+void XTestSetVisualIDOfVisual(
+ Visual* /* visual */,
+ VisualID /* visualid */
+);
+
+Status XTestDiscard(
+ Display* /* dpy */
+);
+
+_XFUNCPROTOEND
+
+#endif
diff --git a/include/X11/extensions/record.h b/include/X11/extensions/record.h
new file mode 100644
index 0000000..e82b06c
--- /dev/null
+++ b/include/X11/extensions/record.h
@@ -0,0 +1,183 @@
+/***************************************************************************
+ * Copyright 1995 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMs ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************/
+
+#ifndef _RECORD_H_
+#define _RECORD_H_
+
+#include <X11/extensions/recordconst.h>
+
+typedef unsigned long XRecordClientSpec;
+typedef unsigned long XRecordContext;
+
+typedef struct
+{
+ unsigned char first;
+ unsigned char last;
+} XRecordRange8;
+
+typedef struct
+{
+ unsigned short first;
+ unsigned short last;
+} XRecordRange16;
+
+typedef struct
+{
+ XRecordRange8 ext_major;
+ XRecordRange16 ext_minor;
+} XRecordExtRange;
+
+typedef struct
+{
+ XRecordRange8 core_requests; /* core X requests */
+ XRecordRange8 core_replies; /* core X replies */
+ XRecordExtRange ext_requests; /* extension requests */
+ XRecordExtRange ext_replies; /* extension replies */
+ XRecordRange8 delivered_events; /* delivered core and ext events */
+ XRecordRange8 device_events; /* all core and ext device events */
+ XRecordRange8 errors; /* core X and ext errors */
+ Bool client_started; /* connection setup reply */
+ Bool client_died; /* notice of client disconnect */
+} XRecordRange;
+
+typedef struct
+{
+ XRecordClientSpec client;
+ unsigned long nranges;
+ XRecordRange **ranges;
+} XRecordClientInfo;
+
+typedef struct
+{
+ Bool enabled;
+ int datum_flags;
+ unsigned long nclients;
+ XRecordClientInfo **client_info;
+} XRecordState;
+
+typedef struct
+{
+ XID id_base;
+ Time server_time;
+ unsigned long client_seq;
+ int category;
+ Bool client_swapped;
+ unsigned char *data;
+ unsigned long data_len; /* in 4-byte units */
+} XRecordInterceptData;
+
+_XFUNCPROTOBEGIN
+
+/*********************************************************
+ *
+ * Prototypes
+ *
+ */
+
+XID XRecordIdBaseMask(
+ Display *dpy
+);
+
+extern Status XRecordQueryVersion(
+ Display* /* dpy */,
+ int* /* cmajor_return */,
+ int* /* cminor_return */
+);
+
+extern XRecordContext XRecordCreateContext(
+ Display* /* dpy */,
+ int /* datum_flags */,
+ XRecordClientSpec* /* clients */,
+ int /* nclients */,
+ XRecordRange** /* ranges */,
+ int /* nranges */
+);
+
+extern XRecordRange *XRecordAllocRange(
+ void
+);
+
+extern Status XRecordRegisterClients(
+ Display* /* dpy */,
+ XRecordContext /* context */,
+ int /* datum_flags */,
+ XRecordClientSpec* /* clients */,
+ int /* nclients */,
+ XRecordRange** /* ranges */,
+ int /* nranges */
+);
+
+extern Status XRecordUnregisterClients(
+ Display* /* dpy */,
+ XRecordContext /* context */,
+ XRecordClientSpec* /* clients */,
+ int /* nclients */
+);
+
+extern Status XRecordGetContext(
+ Display* /* dpy */,
+ XRecordContext /* context */,
+ XRecordState** /* state_return */
+);
+
+extern void XRecordFreeState(
+XRecordState* /* state */
+);
+
+typedef void (*XRecordInterceptProc) (
+ XPointer /* closure */,
+ XRecordInterceptData* /* recorded_data */
+);
+
+extern Status XRecordEnableContext(
+ Display* /* dpy */,
+ XRecordContext /* context */,
+ XRecordInterceptProc /* callback */,
+ XPointer /* closure */
+);
+
+extern Status XRecordEnableContextAsync(
+ Display* /* dpy */,
+ XRecordContext /* context */,
+ XRecordInterceptProc /* callback */,
+ XPointer /* closure */
+);
+
+extern void XRecordProcessReplies(
+ Display* /* dpy */
+);
+
+extern void XRecordFreeData(
+XRecordInterceptData* /* data */
+);
+
+extern Status XRecordDisableContext(
+ Display* /* dpy */,
+ XRecordContext /* context */
+);
+
+extern Status XRecordFreeContext(
+ Display* /* dpy */,
+ XRecordContext /* context */
+);
+
+_XFUNCPROTOEND
+
+#endif
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644
index 0000000..2597d07
--- /dev/null
+++ b/man/Makefile.am
@@ -0,0 +1,78 @@
+#
+# Copyright (c) 2007, Oracle and/or its affiliates. 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 (including the next
+# paragraph) 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 OR COPYRIGHT HOLDERS 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.
+#
+
+libmandir = $(LIB_MAN_DIR)
+
+libman_xml = XTest.xml
+
+libman_PRE = \
+ XTestQueryExtension.man \
+ XTestCompareCursorWithWindow.man \
+ XTestCompareCurrentCursorWithWindow.man \
+ XTestFakeKeyEvent.man \
+ XTestFakeButtonEvent.man \
+ XTestFakeMotionEvent.man \
+ XTestFakeRelativeMotionEvent.man \
+ XTestGrabControl.man \
+ XTestSetGContextOfGC.man \
+ XTestSetVisualIDOfVisual.man \
+ XTestDiscard.man
+
+EXTRA_DIST = $(libman_PRE) $(libman_xml) x.stamp
+
+CLEANFILES = $(libman_DATA)
+
+MAINTAINERCLEANFILES = $(libman_PRE)
+
+if INSTALL_MANPAGES
+libman_DATA = $(libman_PRE:man=@LIB_MAN_SUFFIX@)
+endif
+
+# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
+SUFFIXES = .$(LIB_MAN_SUFFIX) .man
+
+.man.$(LIB_MAN_SUFFIX):
+ $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@
+
+# This is ugly, but handling of tools with multiple outputs in make is a
+# huge PITA. The commands below are taken from the automake manual:
+# http://www.gnu.org/software/automake/manual/automake.html#Multiple-Outputs
+if HAVE_XMLTO
+x.stamp: $(libman_xml)
+ @rm -f x.tmp
+ @touch x.tmp
+ $(XMLTO) man $^
+ @for man in $(libman_PRE); do \
+ out=`echo $$man | sed 's/\.man/.__libmansuffix__/'`; \
+ echo mv -f $$out $$man; \
+ mv -f $$out $$man || exit 1; \
+ done
+ @mv -f x.tmp $@
+$(libman_PRE): x.stamp
+ @if test -f $@; then :; else \
+ rm -f $<; \
+ $(MAKE) $(AM_MAKEFLAGS) $<; \
+ fi
+CLEANFILES += x.tmp
+MAINTAINERCLEANFILES += x.stamp
+endif # HAVE_XMLTO
diff --git a/man/XTest.xml b/man/XTest.xml
new file mode 100644
index 0000000..9d21ef7
--- /dev/null
+++ b/man/XTest.xml
@@ -0,0 +1,413 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<!-- lifted from troff+man by doclifter -->
+<refentry id='XTest.man'>
+<!--
+Copyright &copy; 1992 by UniSoft Group Ltd.
+Permission to use, copy, modify, and distribute this documentation for
+any purpose and without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+UniSoft makes no representations about the suitability for any purpose of
+the information in this document. This documentation is provided "as is"
+without express or implied warranty.
+
+Copyright &copy; 1992, 1994 X Consortium
+
+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 X CONSORTIUM 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 name of the X Consortium 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
+X Consortium.
+ -->
+
+<!-- edited for DP edits and code consistency w/ core protocol/xlib 4/2/96 -->
+<!-- Converted from xorg-docs/specs/Xext/xtestlib.ms 6/6/07 -->
+ <refentryinfo>
+ <productname>__vendorversion__</productname>
+ <pubdate>6 June 2007</pubdate>
+ <author><firstname>Kieron</firstname><surname>Drake</surname>
+ <affiliation><orgname>UniSoft Ltd.</orgname></affiliation>
+ </author>
+ </refentryinfo>
+<refmeta>
+<refentrytitle>XTest</refentrytitle>
+<manvolnum>__libmansuffix__</manvolnum>
+<refmiscinfo class='source'>__xorgversion__</refmiscinfo>
+<refmiscinfo class='manual'>XTST FUNCTIONS</refmiscinfo>
+</refmeta>
+<refnamediv id='name'>
+<refname>XTestQueryExtension</refname>
+<refname>XTestCompareCursorWithWindow</refname>
+<refname>XTestCompareCurrentCursorWithWindow</refname>
+<refname>XTestFakeKeyEvent</refname>
+<refname>XTestFakeButtonEvent</refname>
+<refname>XTestFakeMotionEvent</refname>
+<refname>XTestFakeRelativeMotionEvent</refname>
+<refname>XTestGrabControl</refname>
+<refname>XTestSetGContextOfGC</refname>
+<refname>XTestSetVisualIDOfVisual</refname>
+<refname>XTestDiscard</refname>
+<refpurpose>XTest extension functions</refpurpose>
+</refnamediv>
+<!-- body begins here -->
+<refsynopsisdiv id='synopsis'>
+<funcsynopsis>
+<funcsynopsisinfo>
+cc [ flag ... ] file ... -lXtst [ library ... ]
+</funcsynopsisinfo>
+<funcsynopsisinfo>
+#include &lt;X11/extensions/XTest.h&gt;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef><function>Bool</function> XTestQueryExtension</funcdef>
+<paramdef><parameter>display</parameter></paramdef>
+<paramdef><parameter>event_base_return</parameter></paramdef>
+<paramdef><parameter>error_base_return</parameter></paramdef>
+<paramdef><parameter>major_version_return</parameter></paramdef>
+<paramdef><parameter>minor_version_return</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ Display *display;
+ int *event_base_return;
+ int *error_base_return;
+ int *major_version_return;
+ int *minor_version_return;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef><function>Bool</function> XTestCompareCursorWithWindow</funcdef>
+<paramdef><parameter>display</parameter></paramdef>
+<paramdef><parameter>window</parameter></paramdef>
+<paramdef><parameter>cursor</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ Display *display;
+ Window window;
+ Cursor cursor;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef><function>Bool</function> XTestCompareCurrentCursorWithWindow</funcdef>
+<paramdef><parameter>display</parameter></paramdef>
+<paramdef><parameter>window</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ Display *display;
+ Window window;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef>int <function>XTestFakeKeyEvent</function></funcdef>
+<paramdef><parameter>display</parameter></paramdef>
+<paramdef><parameter>keycode</parameter></paramdef>
+<paramdef><parameter>is_press</parameter></paramdef>
+<paramdef><parameter>delay</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ Display *display;
+ unsigned int keycode;
+ Bool is_press;
+ unsigned long delay;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef>int <function>XTestFakeButtonEvent</function></funcdef>
+<paramdef><parameter>display</parameter></paramdef>
+<paramdef><parameter>button</parameter></paramdef>
+<paramdef><parameter>is_press</parameter></paramdef>
+<paramdef><parameter>delay</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ Display *display;
+ unsigned int button;
+ Bool is_press;
+ unsigned long delay;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef>int <function>XTestFakeMotionEvent</function></funcdef>
+<paramdef><parameter>display</parameter></paramdef>
+<paramdef><parameter>screen_number</parameter></paramdef>
+<paramdef><parameter>x</parameter></paramdef>
+<paramdef><parameter>y</parameter></paramdef>
+<paramdef><parameter>delay</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ Display *display;
+ int screen_number;
+ int x, y;
+ unsigned long delay;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef>int <function>XTestFakeRelativeMotionEvent</function></funcdef>
+<paramdef><parameter>display</parameter></paramdef>
+<paramdef><parameter>screen_number</parameter></paramdef>
+<paramdef><parameter>x</parameter></paramdef>
+<paramdef><parameter>y</parameter></paramdef>
+<paramdef><parameter>delay</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ Display *display;
+ int screen_number;
+ int x, y;
+ unsigned long delay;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef>int <function>XTestGrabControl</function></funcdef>
+<paramdef><parameter>display</parameter></paramdef>
+<paramdef><parameter>impervious</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ Display *display;
+ Bool impervious;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef>void <function>XTestSetGContextOfGC</function></funcdef>
+<paramdef><parameter>gc</parameter></paramdef>
+<paramdef><parameter>gid</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ GC gc;
+ GContext gid;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef>void <function>XTestSetVisualIDOfVisual</function></funcdef>
+<paramdef><parameter>visual</parameter></paramdef>
+<paramdef><parameter>visualid</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ Visual *visual;
+ VisualID visualid;
+</funcsynopsisinfo>
+<funcprototype>
+<funcdef><function>Status</function> XTestDiscard</funcdef>
+<paramdef><parameter>display</parameter></paramdef>
+</funcprototype>
+<funcsynopsisinfo>
+ Display *display;
+</funcsynopsisinfo>
+</funcsynopsis>
+</refsynopsisdiv>
+
+
+<refsect1 id='description'><title>DESCRIPTION</title>
+<para>This extension is a minimal set of client and server extensions
+required to completely test the X11 server with no user intervention.
+This extension is not intended to support general journaling and
+playback of user actions.</para>
+
+<para>The functions provided by this extension fall into two groups:</para>
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='B'>Client Operations</emphasis></term>
+ <listitem>
+<para>These routines manipulate otherwise hidden client-side behavior. The
+actual implementation will depend on the details of the actual language
+binding and what degree of request buffering, GContext caching, and so on, is
+provided. In the C binding, routines are provided
+to access the internals of two opaque data structures
+&mdash; <structname>GC</structname>s
+and
+<structname>Visual</structname>s &mdash;
+and to discard any requests pending within the
+output buffer of a connection. The exact details can be expected to differ for
+other language bindings.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>Server Requests</emphasis></term>
+ <listitem>
+<para>The first of these requests is similar to that provided in most
+extensions: it allows a client to specify a major and minor version
+number to the server and for the server to respond with major and minor
+versions of its own. The remaining two requests allow the following:</para>
+ <itemizedlist>
+ <listitem>
+<para>Access to an otherwise <emphasis>write-only</emphasis> server resource:
+the cursor associated with a given window</para>
+ </listitem>
+ <listitem>
+<para>Perhaps most importantly, limited synthesis of input device events,
+almost as if a cooperative user had moved the pointing device
+or pressed a key or button.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>All XTEST extension functions and procedures, and all manifest
+constants and macros, will start with the string <emphasis>XTest</emphasis>.
+All operations are classified as
+server/client (Server) or client-only (Client).</para>
+
+<para><function>XTestQueryExtension</function>
+returns
+<returnvalue>True</returnvalue>
+if the specified display supports the XTEST extension, else
+<returnvalue>False</returnvalue>.
+If the extension is supported, *event_base would be set to the event number for
+the first event for this extension and
+*error_base would be set to the error number for the first error for
+this extension. As no errors or events are defined for this version of the extension,
+the values returned here are not defined (nor useful).
+If the extension is supported, *major_version and *minor_version are set to
+the major and minor version numbers of the extension supported by the
+display. Otherwise, none of the arguments are set.</para>
+
+
+<para>If the extension is supported,
+<function>XTestCompareCursorWithWindow</function>
+performs a comparison of the cursor
+whose ID is specified by cursor (which may be
+<emphasis remap='B'>None</emphasis>)
+with the cursor of the window specified by window returning
+<returnvalue>True</returnvalue>
+if they are the same and
+<returnvalue>False</returnvalue>
+otherwise.
+If the extension is not supported, then the request is ignored and
+zero is returned.</para>
+
+
+<para>If the extension is supported,
+<function>XTestCompareCurrentCursorWithWindow</function>
+performs a comparison of the current cursor
+with the cursor of the specified window returning
+<returnvalue>True</returnvalue>
+if they are the same and
+<returnvalue>False</returnvalue>
+otherwise.
+If the extension is not supported, then the request is ignored and
+zero is returned.</para>
+
+
+<para>If the extension is supported,
+<function>XTestFakeKeyEvent</function>
+requests the server to simulate either a
+<emphasis remap='B'>KeyPress</emphasis>
+(if is_press is
+<returnvalue>True</returnvalue>)
+or a
+<emphasis remap='B'>KeyRelease</emphasis>
+(if is_press is
+<returnvalue>False</returnvalue>)
+of the key with the specified keycode;
+otherwise, the request is ignored.</para>
+
+<para>If the extension is supported,
+the simulated event will not be processed until delay milliseconds
+after the request is received (if delay is
+<emphasis remap='B'>CurrentTime</emphasis>,
+then this is interpreted as no delay at all). No other requests from
+this client will be processed until this delay, if any, has expired
+and subsequent processing of the simulated event has been completed.</para>
+
+
+<para>If the extension is supported,
+<function>XTestFakeButtonEvent</function>
+requests the server to simulate either
+a
+<emphasis remap='B'>ButtonPress</emphasis>
+(if is_press is
+<returnvalue>True</returnvalue>)
+or a
+<emphasis remap='B'>ButtonRelease</emphasis>
+(if is_press is
+<returnvalue>False</returnvalue>)
+of the logical button numbered by the specified button;
+otherwise, the request is ignored.</para>
+
+<para>If the extension is supported,
+the simulated event will not be processed until delay milliseconds
+after the request is received (if delay is
+<emphasis remap='B'>CurrentTime</emphasis>,
+then this is interpreted as no delay at all). No other requests from
+this client will be processed until this delay, if any, has expired
+and subsequent processing of the simulated event has been completed.</para>
+
+
+<para>If the extension is supported,
+<function>XTestFakeMotionEvent</function>
+requests the server to simulate
+a movement of the pointer to the specified position (x, y) on the
+root window of screen_number;
+otherwise, the request is ignored. If screen_number is -1, the
+current screen (that the pointer is on) is used.</para>
+
+<para>If the extension is supported,
+the simulated event will not be processed until delay milliseconds
+after the request is received (if delay is
+<emphasis remap='B'>CurrentTime</emphasis>,
+then this is interpreted as no delay at all). No other requests from
+this client will be processed until this delay, if any, has expired
+and subsequent processing of the simulated event has been completed.</para>
+
+
+<para>If the extension is supported,
+<function>XTestFakeRelativeMotionEvent</function>
+requests the server to simulate
+a movement of the pointer by the specified offsets (x, y) relative
+to the current pointer position on screen_number;
+otherwise, the request is ignored. If screen_number is -1, the
+current screen (that the pointer is on) is used.</para>
+
+<para>If the extension is supported,
+the simulated event will not be processed until delay milliseconds
+after the request is received (if delay is
+<emphasis remap='B'>CurrentTime</emphasis>,
+then this is interpreted as no delay at all). No other requests from
+this client will be processed until this delay, if any, has expired
+and subsequent processing of the simulated event has been completed.</para>
+
+
+
+<para>If impervious is
+<returnvalue>True</returnvalue>,
+then the executing client becomes impervious to server grabs.
+If impervious is
+<returnvalue>False</returnvalue>,
+then the executing client returns to the normal state of being
+susceptible to server grabs.</para>
+
+
+<para><function>XTestSetGContextOfGC</function>
+sets the GContext within the opaque datatype referenced by gc to
+be that specified by gid.</para>
+
+
+<para><function>XTestSetVisualIDOfVisual</function>
+sets the VisualID within the opaque datatype referenced by visual to
+be that specified by visualid.</para>
+
+
+<para><function>XTestDiscard</function>
+discards any requests within the output buffer for the specified display.
+It returns
+<returnvalue>True</returnvalue>
+if any requests were discarded; otherwise, it returns
+<returnvalue>False</returnvalue>.</para>
+
+</refsect1>
+
+<refsect1 id='return_values'><title>RETURN VALUES</title>
+<para>All routines that have return type Status will return nonzero for
+success and zero for failure. Even if the XTEST extension is
+supported, the server may withdraw such facilities arbitrarily; in which case
+they will subsequently return zero.</para>
+</refsect1>
+</refentry>
+
diff --git a/man/XTestCompareCurrentCursorWithWindow.man b/man/XTestCompareCurrentCursorWithWindow.man
new file mode 100644
index 0000000..4373039
--- /dev/null
+++ b/man/XTestCompareCurrentCursorWithWindow.man
@@ -0,0 +1 @@
+.so XTestQueryExtension.__libmansuffix__
diff --git a/man/XTestCompareCursorWithWindow.man b/man/XTestCompareCursorWithWindow.man
new file mode 100644
index 0000000..4373039
--- /dev/null
+++ b/man/XTestCompareCursorWithWindow.man
@@ -0,0 +1 @@
+.so XTestQueryExtension.__libmansuffix__
diff --git a/man/XTestDiscard.man b/man/XTestDiscard.man
new file mode 100644
index 0000000..4373039
--- /dev/null
+++ b/man/XTestDiscard.man
@@ -0,0 +1 @@
+.so XTestQueryExtension.__libmansuffix__
diff --git a/man/XTestFakeButtonEvent.man b/man/XTestFakeButtonEvent.man
new file mode 100644
index 0000000..4373039
--- /dev/null
+++ b/man/XTestFakeButtonEvent.man
@@ -0,0 +1 @@
+.so XTestQueryExtension.__libmansuffix__
diff --git a/man/XTestFakeKeyEvent.man b/man/XTestFakeKeyEvent.man
new file mode 100644
index 0000000..4373039
--- /dev/null
+++ b/man/XTestFakeKeyEvent.man
@@ -0,0 +1 @@
+.so XTestQueryExtension.__libmansuffix__
diff --git a/man/XTestFakeMotionEvent.man b/man/XTestFakeMotionEvent.man
new file mode 100644
index 0000000..4373039
--- /dev/null
+++ b/man/XTestFakeMotionEvent.man
@@ -0,0 +1 @@
+.so XTestQueryExtension.__libmansuffix__
diff --git a/man/XTestFakeRelativeMotionEvent.man b/man/XTestFakeRelativeMotionEvent.man
new file mode 100644
index 0000000..4373039
--- /dev/null
+++ b/man/XTestFakeRelativeMotionEvent.man
@@ -0,0 +1 @@
+.so XTestQueryExtension.__libmansuffix__
diff --git a/man/XTestGrabControl.man b/man/XTestGrabControl.man
new file mode 100644
index 0000000..4373039
--- /dev/null
+++ b/man/XTestGrabControl.man
@@ -0,0 +1 @@
+.so XTestQueryExtension.__libmansuffix__
diff --git a/man/XTestQueryExtension.man b/man/XTestQueryExtension.man
new file mode 100644
index 0000000..41da9f3
--- /dev/null
+++ b/man/XTestQueryExtension.man
@@ -0,0 +1,288 @@
+'\" t
+.\" Title: XTest
+.\" Author: Kieron Drake
+.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
+.\" Date: <pubdate>6 June 2007</pubdate>
+.\" Manual: XTST FUNCTIONS
+.\" Source: __xorgversion__
+.\" Language: English
+.\"
+.TH "XTEST" "__libmansuffix__" "<pubdate>6 June 2007</pubdate>" "__xorgversion__" "XTST FUNCTIONS"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+XTestQueryExtension, XTestCompareCursorWithWindow, XTestCompareCurrentCursorWithWindow, XTestFakeKeyEvent, XTestFakeButtonEvent, XTestFakeMotionEvent, XTestFakeRelativeMotionEvent, XTestGrabControl, XTestSetGContextOfGC, XTestSetVisualIDOfVisual, XTestDiscard \- XTest extension functions
+.SH "SYNOPSIS"
+.sp
+.ft B
+.nf
+cc [ flag \&.\&.\&. ] file \&.\&.\&. \-lXtst [ library \&.\&.\&. ]
+.fi
+.ft
+.sp
+.ft B
+.nf
+#include <X11/extensions/XTest\&.h>
+.fi
+.ft
+.HP \w'Bool\ XTestQueryExtension('u
+.BI "Bool XTestQueryExtension(" "display" ", " "event_base_return" ", " "error_base_return" ", " "major_version_return" ", " "minor_version_return" ");"
+.sp
+.ft B
+.nf
+ Display *display;
+ int *event_base_return;
+ int *error_base_return;
+ int *major_version_return;
+ int *minor_version_return;
+.fi
+.ft
+.HP \w'Bool\ XTestCompareCursorWithWindow('u
+.BI "Bool XTestCompareCursorWithWindow(" "display" ", " "window" ", " "cursor" ");"
+.sp
+.ft B
+.nf
+ Display *display;
+ Window window;
+ Cursor cursor;
+.fi
+.ft
+.HP \w'Bool\ XTestCompareCurrentCursorWithWindow('u
+.BI "Bool XTestCompareCurrentCursorWithWindow(" "display" ", " "window" ");"
+.sp
+.ft B
+.nf
+ Display *display;
+ Window window;
+.fi
+.ft
+.HP \w'int\ XTestFakeKeyEvent('u
+.BI "int XTestFakeKeyEvent(" "display" ", " "keycode" ", " "is_press" ", " "delay" ");"
+.sp
+.ft B
+.nf
+ Display *display;
+ unsigned int keycode;
+ Bool is_press;
+ unsigned long delay;
+.fi
+.ft
+.HP \w'int\ XTestFakeButtonEvent('u
+.BI "int XTestFakeButtonEvent(" "display" ", " "button" ", " "is_press" ", " "delay" ");"
+.sp
+.ft B
+.nf
+ Display *display;
+ unsigned int button;
+ Bool is_press;
+ unsigned long delay;
+.fi
+.ft
+.HP \w'int\ XTestFakeMotionEvent('u
+.BI "int XTestFakeMotionEvent(" "display" ", " "screen_number" ", " "x" ", " "y" ", " "delay" ");"
+.sp
+.ft B
+.nf
+ Display *display;
+ int screen_number;
+ int x, y;
+ unsigned long delay;
+.fi
+.ft
+.HP \w'int\ XTestFakeRelativeMotionEvent('u
+.BI "int XTestFakeRelativeMotionEvent(" "display" ", " "screen_number" ", " "x" ", " "y" ", " "delay" ");"
+.sp
+.ft B
+.nf
+ Display *display;
+ int screen_number;
+ int x, y;
+ unsigned long delay;
+.fi
+.ft
+.HP \w'int\ XTestGrabControl('u
+.BI "int XTestGrabControl(" "display" ", " "impervious" ");"
+.sp
+.ft B
+.nf
+ Display *display;
+ Bool impervious;
+.fi
+.ft
+.HP \w'void\ XTestSetGContextOfGC('u
+.BI "void XTestSetGContextOfGC(" "gc" ", " "gid" ");"
+.sp
+.ft B
+.nf
+ GC gc;
+ GContext gid;
+.fi
+.ft
+.HP \w'void\ XTestSetVisualIDOfVisual('u
+.BI "void XTestSetVisualIDOfVisual(" "visual" ", " "visualid" ");"
+.sp
+.ft B
+.nf
+ Visual *visual;
+ VisualID visualid;
+.fi
+.ft
+.HP \w'Status\ XTestDiscard('u
+.BI "Status XTestDiscard(" "display" ");"
+.sp
+.ft B
+.nf
+ Display *display;
+.fi
+.ft
+.SH "DESCRIPTION"
+.PP
+This extension is a minimal set of client and server extensions required to completely test the X11 server with no user intervention\&. This extension is not intended to support general journaling and playback of user actions\&.
+.PP
+The functions provided by this extension fall into two groups:
+.PP
+\fBClient Operations\fR
+.RS 4
+These routines manipulate otherwise hidden client\-side behavior\&. The actual implementation will depend on the details of the actual language binding and what degree of request buffering, GContext caching, and so on, is provided\&. In the C binding, routines are provided to access the internals of two opaque data structures \(em
+GCs and
+Visuals \(em and to discard any requests pending within the output buffer of a connection\&. The exact details can be expected to differ for other language bindings\&.
+.RE
+.PP
+\fBServer Requests\fR
+.RS 4
+The first of these requests is similar to that provided in most extensions: it allows a client to specify a major and minor version number to the server and for the server to respond with major and minor versions of its own\&. The remaining two requests allow the following:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Access to an otherwise
+\fIwrite\-only\fR
+server resource: the cursor associated with a given window
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Perhaps most importantly, limited synthesis of input device events, almost as if a cooperative user had moved the pointing device or pressed a key or button\&.
+.RE
+.RE
+.PP
+All XTEST extension functions and procedures, and all manifest constants and macros, will start with the string
+\fIXTest\fR\&. All operations are classified as server/client (Server) or client\-only (Client)\&.
+.PP
+\fBXTestQueryExtension\fR
+returns
+True
+if the specified display supports the XTEST extension, else
+False\&. If the extension is supported, *event_base would be set to the event number for the first event for this extension and *error_base would be set to the error number for the first error for this extension\&. As no errors or events are defined for this version of the extension, the values returned here are not defined (nor useful)\&. If the extension is supported, *major_version and *minor_version are set to the major and minor version numbers of the extension supported by the display\&. Otherwise, none of the arguments are set\&.
+.PP
+If the extension is supported,
+\fBXTestCompareCursorWithWindow\fR
+performs a comparison of the cursor whose ID is specified by cursor (which may be
+\fBNone\fR) with the cursor of the window specified by window returning
+True
+if they are the same and
+False
+otherwise\&. If the extension is not supported, then the request is ignored and zero is returned\&.
+.PP
+If the extension is supported,
+\fBXTestCompareCurrentCursorWithWindow\fR
+performs a comparison of the current cursor with the cursor of the specified window returning
+True
+if they are the same and
+False
+otherwise\&. If the extension is not supported, then the request is ignored and zero is returned\&.
+.PP
+If the extension is supported,
+\fBXTestFakeKeyEvent\fR
+requests the server to simulate either a
+\fBKeyPress\fR
+(if is_press is
+True) or a
+\fBKeyRelease\fR
+(if is_press is
+False) of the key with the specified keycode; otherwise, the request is ignored\&.
+.PP
+If the extension is supported, the simulated event will not be processed until delay milliseconds after the request is received (if delay is
+\fBCurrentTime\fR, then this is interpreted as no delay at all)\&. No other requests from this client will be processed until this delay, if any, has expired and subsequent processing of the simulated event has been completed\&.
+.PP
+If the extension is supported,
+\fBXTestFakeButtonEvent\fR
+requests the server to simulate either a
+\fBButtonPress\fR
+(if is_press is
+True) or a
+\fBButtonRelease\fR
+(if is_press is
+False) of the logical button numbered by the specified button; otherwise, the request is ignored\&.
+.PP
+If the extension is supported, the simulated event will not be processed until delay milliseconds after the request is received (if delay is
+\fBCurrentTime\fR, then this is interpreted as no delay at all)\&. No other requests from this client will be processed until this delay, if any, has expired and subsequent processing of the simulated event has been completed\&.
+.PP
+If the extension is supported,
+\fBXTestFakeMotionEvent\fR
+requests the server to simulate a movement of the pointer to the specified position (x, y) on the root window of screen_number; otherwise, the request is ignored\&. If screen_number is \-1, the current screen (that the pointer is on) is used\&.
+.PP
+If the extension is supported, the simulated event will not be processed until delay milliseconds after the request is received (if delay is
+\fBCurrentTime\fR, then this is interpreted as no delay at all)\&. No other requests from this client will be processed until this delay, if any, has expired and subsequent processing of the simulated event has been completed\&.
+.PP
+If the extension is supported,
+\fBXTestFakeRelativeMotionEvent\fR
+requests the server to simulate a movement of the pointer by the specified offsets (x, y) relative to the current pointer position on screen_number; otherwise, the request is ignored\&. If screen_number is \-1, the current screen (that the pointer is on) is used\&.
+.PP
+If the extension is supported, the simulated event will not be processed until delay milliseconds after the request is received (if delay is
+\fBCurrentTime\fR, then this is interpreted as no delay at all)\&. No other requests from this client will be processed until this delay, if any, has expired and subsequent processing of the simulated event has been completed\&.
+.PP
+If impervious is
+True, then the executing client becomes impervious to server grabs\&. If impervious is
+False, then the executing client returns to the normal state of being susceptible to server grabs\&.
+.PP
+\fBXTestSetGContextOfGC\fR
+sets the GContext within the opaque datatype referenced by gc to be that specified by gid\&.
+.PP
+\fBXTestSetVisualIDOfVisual\fR
+sets the VisualID within the opaque datatype referenced by visual to be that specified by visualid\&.
+.PP
+\fBXTestDiscard\fR
+discards any requests within the output buffer for the specified display\&. It returns
+True
+if any requests were discarded; otherwise, it returns
+False\&.
+.SH "RETURN VALUES"
+.PP
+All routines that have return type Status will return nonzero for success and zero for failure\&. Even if the XTEST extension is supported, the server may withdraw such facilities arbitrarily; in which case they will subsequently return zero\&.
+.SH "AUTHOR"
+.PP
+\fBKieron Drake\fR
+.br
+UniSoft Ltd\&.
+.RS 4
+Author.
+.RE
diff --git a/man/XTestSetGContextOfGC.man b/man/XTestSetGContextOfGC.man
new file mode 100644
index 0000000..4373039
--- /dev/null
+++ b/man/XTestSetGContextOfGC.man
@@ -0,0 +1 @@
+.so XTestQueryExtension.__libmansuffix__
diff --git a/man/XTestSetVisualIDOfVisual.man b/man/XTestSetVisualIDOfVisual.man
new file mode 100644
index 0000000..4373039
--- /dev/null
+++ b/man/XTestSetVisualIDOfVisual.man
@@ -0,0 +1 @@
+.so XTestQueryExtension.__libmansuffix__
diff --git a/man/x.stamp b/man/x.stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/man/x.stamp
diff --git a/packaging/libXtst.spec b/packaging/libXtst.spec
new file mode 100644
index 0000000..a2e7641
--- /dev/null
+++ b/packaging/libXtst.spec
@@ -0,0 +1,83 @@
+Summary: X.Org X11 libXtst runtime library
+Name: libXtst
+Version: 1.2.0
+Release: 3
+License: MIT
+Group: System Environment/Libraries
+URL: http://www.x.org
+
+Source0: %{name}-%{version}.tar.gz
+
+BuildRequires: pkgconfig(xorg-macros)
+BuildRequires: pkgconfig(xproto)
+BuildRequires: pkgconfig(xextproto)
+BuildRequires: pkgconfig(randrproto)
+BuildRequires: pkgconfig(inputproto)
+BuildRequires: pkgconfig(recordproto)
+BuildRequires: pkgconfig(xextproto)
+BuildRequires: libX11-devel
+BuildRequires: libXext-devel
+BuildRequires: libXi-devel
+
+%description
+X.Org X11 libXtst runtime library
+
+%package devel
+Summary: X.Org X11 libXtst development package
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+Requires: libXi-devel
+Provides: libxtst-devel
+
+%description devel
+X.Org X11 libXtst development package
+
+%prep
+%setup -q
+
+# Disable static library creation by default.
+%define with_static 0
+
+%build
+
+%reconfigure --disable-static \
+ LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed"
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p %{buildroot}/usr/share/license
+cp -af COPYING %{buildroot}/usr/share/license/%{name}
+make install DESTDIR=$RPM_BUILD_ROOT
+
+# We intentionally don't ship *.la files
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
+
+rm -rf $RPM_BUILD_ROOT%{_docdir}
+
+%remove_docs
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post -p /sbin/ldconfig
+%postun -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+/usr/share/license/%{name}
+%doc COPYING ChangeLog
+%{_libdir}/libXtst.so.6
+%{_libdir}/libXtst.so.6.1.0
+
+%files devel
+%defattr(-,root,root,-)
+#%doc specs/*.txt
+%{_includedir}/X11/extensions/XTest.h
+%{_includedir}/X11/extensions/record.h
+%if %{with_static}
+%{_libdir}/libXtst.a
+%endif
+%{_libdir}/libXtst.so
+%{_libdir}/pkgconfig/xtst.pc
+#%{_mandir}/man3/XTest*.3*
diff --git a/specs/Makefile.am b/specs/Makefile.am
new file mode 100644
index 0000000..f35ef69
--- /dev/null
+++ b/specs/Makefile.am
@@ -0,0 +1,13 @@
+
+if ENABLE_SPECS
+
+# Main DocBook/XML files (DOCTYPE book)
+docbook = xtestlib.xml recordlib.xml
+
+# The location where the DocBook/XML files and their generated formats are installed
+shelfdir = $(docdir)
+
+# Generate DocBook/XML output formats with or without stylesheets
+include $(top_srcdir)/docbook.am
+
+endif ENABLE_SPECS
diff --git a/specs/recordlib.xml b/specs/recordlib.xml
new file mode 100644
index 0000000..08d3eb2
--- /dev/null
+++ b/specs/recordlib.xml
@@ -0,0 +1,1509 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+
+<!-- lifted from troff+ms+XMan by doclifter -->
+<book id="recordlib">
+
+<bookinfo>
+ <title>X Record Extension Library</title>
+ <subtitle>X Consortium Standard</subtitle>
+ <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo>
+ <releaseinfo>Version 1.13</releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>Martha</firstname><surname>Zimet</surname>
+ <affiliation><orgname>Network Computing Devices, Inc.</orgname></affiliation>
+ </author>
+ <editor>
+ <firstname>Stephen</firstname><surname>Gildea</surname>
+ <affiliation><orgname>X Consortium</orgname></affiliation>
+ </editor>
+ </authorgroup>
+ <copyright><year>1994</year><holder>Network Computing Devices, Inc.</holder></copyright>
+
+<legalnotice>
+<para>
+Permission to use, copy, modify, distribute, and sell this
+documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice and this permission
+notice appear in all copies. Network Computing Devices, Inc.
+makes no representations about the suitability for any purpose
+of the information in this document. This documentation is
+provided "as is" without express or implied warranty.
+</para>
+</legalnotice>
+
+<legalnotice>
+<para role="multiLicensing">Copyright © 1995 X Consortium</para>
+<para>
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files
+(the &ldquo;Software&rdquo;), 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:
+</para>
+<para>THE SOFTWARE IS PROVIDED &ldquo;AS IS&rdquo;, 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 X CONSORTIUM 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.
+</para>
+<para>
+Except as contained in this notice, the name of the X Consortium 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
+X Consortium.
+</para>
+<para>X Window System is a trademark of The Open Group.</para>
+</legalnotice>
+</bookinfo>
+
+<chapter id='Record_Extension_Overview'>
+<title>Record Extension Overview</title>
+<para>
+The purpose of this extension is to support the recording and reporting of
+all core X protocol and arbitrary X extension protocol. This first section
+gives an overview of the Record extension. The following sections describe
+how to use the Record extension library.
+</para>
+
+<sect1 id='Synchronous_Playback'>
+<title>Synchronous Playback</title>
+<para>
+Environment information is generally provided to an X-based playback
+mechanism, which might use the XTest extension to synthesize input
+events. This synchronization information defines the X state prior to
+event synthesis (for example, location of the cursor, window locations
+and sizes, installed colormap, window manager running, and so on) and
+the consequences that occur after the playback mechanism synthesizes
+the event. If the user moves the mouse into the icon window and presses
+and releases a mouse button, the device events
+<function>MotionNotify</function>, <function>ButtonPress</function>,
+and <function>ButtonRelease</function> are generated by the X server.
+Because X follows an
+event-driven model, there are consequences that follow from the user
+actions, or device events, that are in the form of X protocol. As a result
+of the previous user actions, the client could generate requests such as
+<function>ImageText8</function> and <function>PolyLine</function> to the
+X server, or the X server could send non-device events such as
+<function>Expose</function> and <function>MapNotify</function> to the
+client window. Both the
+requests and non-device events that result from user actions are known
+as consequences, which can be used as a synchronization, or control point,
+during playback. That is, the playback mechanism does not generate a specific
+synthesized event until its matching synchronization condition occurs
+(for example, the window is mapped or unmapped, the cursor changes, a text
+string displays, and so on)
+</para>
+<para>
+Because it cannot be predicted what synchronization information is required
+during playback, the Record extension makes no assumptions about the intended
+use of the recorded data. Facilities exist to record any core X protocol or
+X extension protocol. Therefore, Record does not enforce a specific
+synchronization methodology.
+</para>
+</sect1>
+
+<sect1 id='Design_Approach'>
+<title>Design Approach</title>
+<para>
+The design approach of the extension is to record core X protocol and
+arbitrary X extension protocol entirely within the X server itself. When
+the extension has been requested to record specific protocol by one or more
+recording clients, the protocol data is formatted and returned to the
+recording clients. The extension provides a mechanism for capturing all
+events, including input device events that do not go to any clients.
+</para>
+</sect1>
+
+<sect1 id='Record_Clients'>
+<title>Record Clients</title>
+<para>
+The recommended communication model for a Record application is to open two
+connections to the server—one connection for recording control and one
+connection for reading recorded protocol data.
+</para>
+<para>
+Information about recording (for example, what clients to record, what
+protocol to record for each client, and so on) is stored in resources
+called record contexts (type <function>XRecordContext</function>). Most
+Record extension functions take a record context as an argument. Although
+in theory it is possible to share record contexts between applications,
+it is expected that applications will use their own context when performing
+recording operations.
+</para>
+<para>
+A client that wishes to record X protocol does so through the library
+functions defined in
+<xref linkend='Library_Extension_Requests' xrefstyle='select: title'/>
+A typical sequence of requests that a client would make is as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+<xref linkend='XRecordQueryVersion' xrefstyle='select: title'/>
+ </para>
+ <para>
+query the extension protocol version.
+ </para>
+</listitem>
+<listitem>
+ <para>
+<xref linkend='XRecordCreateContext' xrefstyle='select: title'/>
+ </para>
+ <para>
+request that the server create a record context for access by this client,
+and express interest in clients and protocol to be recorded. This request
+returns an <function>XRecord-Context</function>, which is an XID that is
+used by most other extension requests to identify the specified context.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<xref linkend='XRecordEnableContext' xrefstyle='select: title'/>
+ </para>
+ <para>
+begin the recording and reporting of protocol data.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<xref linkend='XRecordDisableContext' xrefstyle='select: title'/>
+ </para>
+ <para>
+end the recording and reporting of protocol data.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<xref linkend='XRecordFreeContext' xrefstyle='select: title'/>
+ </para>
+ <para>
+free the record context.
+ </para>
+ </listitem>
+</itemizedlist>
+
+<para>
+The header for this library is
+&lt;<function>X11/extensions/record.h</function>&gt;. All identifiers defined
+in the interface are supplied by this header and are prefixed with "XRecord".
+The <function>Xtst</function> library contains the
+<function>XRecord</function> functions.
+</para>
+
+</sect1>
+</chapter>
+
+<chapter id='Common_Arguments'>
+<title>Common Arguments</title>
+<para>
+The Record extension functions <xref linkend='XRecordCreateContext' xrefstyle='select: title'/>
+ and <xref linkend='XRecordRegisterClients' xrefstyle='select: title'/> allow applications to
+specify the following:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Individual clients or sets of clients to record
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Ranges of core X protocol and X extension protocol to record for each client
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+Protocol in the ranges specified by the recording client will be recorded
+by the server. The device_events protocol type can be specified by a
+recording client although it may not be sent to a recorded client. The
+device_events type differs from delivered_events, which also can be
+specified by a recording client; delivered_events are actually delivered to
+one or more clients. These event types are discussed in
+<xref linkend='Protocol_Ranges' xrefstyle='select: title'/>
+</para>
+
+
+<para>
+The Record extension functions <xref linkend='XRecordCreateContext' xrefstyle='select: title'/>
+ and <xref linkend='XRecordRegisterClients' xrefstyle='select: title'/> have the common arguments
+datum_flags, clients, and ranges, which specify whether server time
+and/or client sequence number should precede protocol elements, the
+clients or client set to record, and the protocol ranges to record,
+respectively. These are discussed in the following sections.
+</para>
+
+<sect1 id='Datum_Flags'>
+<title>Datum Flags</title>
+<para>
+The datum_flags argument is a set of flags OR’ed together to specify options
+for the record context. Specify zero to disable all the options.
+</para>
+
+<para>
+The <function>XRecordFromServerTime</function> flag specifies that
+<function>XRecordInterceptData</function> structures with a category of
+<function>XRecordFromServer</function> will have a server_time field specific to each
+protocol element.
+</para>
+
+<para>
+The <function>XRecordFromClientTime</function> flag specifies that
+<function>XRecordInterceptData</function> structures with a category of
+<function>XRecordFromClient</function> will have a server_time field specific
+to each protocol element.
+</para>
+
+<para>
+The <function>XRecordFromClientSequence</function> flag specifies that
+<function>XRecordInterceptData</function> structures with a category of
+<function>XRecordFromClient</function> or
+<function>XRecordClientDied</function> will have a valid client_seq field.
+</para>
+</sect1>
+
+<sect1 id='Selecting_Clients'>
+<title>Selecting Clients</title>
+
+<para>
+The clients argument is a pointer to an array of
+<function>XRecordClientSpec</function>.
+<function>XRecordClientSpec</function> is an integral type that holds a
+resource ID, a client resource ID base, or one of the client set constants
+defined below.
+</para>
+<para>
+Duplicate elements in the array are ignored by the functions, and if any
+element in the array is not valid, a
+<function>BadMatch</function>
+error results. A resource ID references the client that created that
+resource. The client set may be one of the following constants:
+<function>XRecordCurrentClients</function>,
+<function>XRecordFutureClients</function>, or
+<function>XRecordAllClients</function>.
+</para>
+<para>
+If the element in the array identifies a particular client, protocol
+specified by the ranges argument will be recorded by the server. The
+recorded protocol data will not be returned to the recording client until
+the record context has been enabled. This is described in
+<xref linkend='Data_Transfer' xrefstyle='select: title'/>
+</para>
+<para>
+If the element is <function>XRecordCurrentClients</function>, the protocol
+ranges specified by the ranges argument, except for device_events, are
+associated with each current client connection. If the element is
+<function>XRecordFutureClients</function>, the
+protocol ranges specified by the ranges argument are associated with each new
+client connection. If the element is
+<function>XRecordAllClients</function>,
+the protocol ranges specified by the ranges argument are associated with
+each current client connection and with each new client connection.
+When the context is enabled, the data connection is unregistered if it
+was registered. If the context is enabled,
+<function>XRecordCurrentClients</function> and
+<function>XRecordAllClients</function>
+silently exclude the recording data connection. It is an error to explicitly
+register the data connection.
+</para>
+</sect1>
+<sect1 id='Protocol_Ranges'>
+<title>Protocol Ranges</title>
+
+<para>
+The functions <xref linkend='XRecordCreateContext' xrefstyle='select: title'/> and
+<xref linkend='XRecordRegisterClients' xrefstyle='select: title'/> have another common argument,
+ranges, which is an array of pointers to <function>XRecordRange</function>
+structures. Each structure contains ranges of numeric values for each of
+the protocol types that can be specified and recorded individually by the
+Record extension. An <function>XRecordRange</function> structure must be
+allocated by the Record library using the
+<function>XRecordAllocRange</function> function.
+</para>
+<para>
+The <function>XRecordRange</function> typedef is a structure with the
+following members:
+</para>
+
+<literallayout remap='Ds'>
+XRecordRange:
+ XRecordRange8 core_requests /* core X requests */
+ XRecordRange8 core_replies /* core X replies */
+ XRecordExtRange ext_requests /* extension requests */
+ XRecordExtRange ext_replies /* extension replies */
+ XRecordRange8 delivered_events /* delivered core and ext events */
+ XRecordRange8 device_events /* all core and ext device events */
+ XRecordRange8 errors /* core X and X ext errors */
+ Bool client_started /* connection setup reply from server */
+ Bool client_died /* notification of client disconnect */
+</literallayout>
+
+<para>
+The types used in
+<function>XRecordRange</function>
+members are defined as follows. The
+<function>XRecordRange8</function>
+typedef is a structure with the following members:
+</para>
+
+<literallayout remap='Ds'>
+XRecordRange8:
+ unsigned char first
+ unsigned char last
+</literallayout>
+
+<para>
+The
+<function>XRecordRange16</function>
+typedef is a structure with the following members:
+</para>
+
+<literallayout remap='Ds'>
+XRecordRange16:
+ unsigned short first
+ unsigned short last
+</literallayout>
+
+<para>
+The
+<function>XRecordExtRange</function>
+typedef is a structure with the following members:
+</para>
+
+<literallayout remap='Ds'>
+XRecordExtRange:
+ XRecordRange8 ext_major
+ XRecordRange16 ext_minor
+</literallayout>
+
+<para>
+If any of the values specified in
+<function>XRecordRange</function>
+is invalid, a
+<function>BadValue</function>
+error results.
+</para>
+
+<para>
+The core_requests member specifies the range of core X protocol
+requests to record. Core X protocol requests with a major opcode
+that is between first and last, inclusive, will be
+recorded. A
+<function>BadValue</function>
+error results if the value of first is greater than the value of last.
+If the values of both first and last are zero, no core
+X protocol requests will be recorded.
+</para>
+
+<para>
+The core_replies member specifies the range of replies resulting
+from core X protocol requests to record. Replies that result from
+core X protocol requests with a major opcode between first
+and last, inclusive, will be recorded. A
+<function>BadValue</function>
+error results if the value of first is greater than the value of last.
+If the values of both first and last are zero, no core X protocol
+replies will be recorded.
+</para>
+
+<para>
+The ext_requests member specifies the range of X extension
+requests to record. X extension requests with a major opcode
+between ext_major.first and ext_major.last, and with a
+minor opcode
+between ext_minor.first and ext_minor.last, inclusive, will be
+recorded. A
+<function>BadValue</function>
+error results
+if the value of ext_major.first is greater than the value of
+ext_major.last or if the value of ext_minor.first is
+greater than the value of ext_minor.last. If the values of both
+ext_major.first
+and ext_major.last are zero,
+no X extension requests will be recorded.
+</para>
+
+<para>
+The ext_replies member specifies the range of replies resulting
+from X extension requests to record. Replies that result from an X
+extension request with a major opcode between
+ext_major.first and
+ext_major.last, and a minor opcode that is between
+ext_minor.first and ext_minor.last will be recorded. A
+<function>BadValue</function>
+error results
+if the value of ext_major.first is greater than the value of
+ext_major.last or if the value of ext_minor.first is greater than
+the value of ext_minor.last. If the values of both
+ext_major.first and ext_major.last are zero, no X extension
+replies will be recorded.
+</para>
+
+<para>
+The delivered_events member specifies the range of both core
+X events and X extension events to record. These events are
+delivered to at least one client. Core X events and X extension events
+with a code value between first and last inclusive will be recorded. A
+<function>BadValue</function>
+error results if the value of first is greater than the value of last.
+If the values of first and last are zero, no events will be recorded.
+</para>
+
+<para>
+The device_events member specifies the range of both core X device
+events and X extension device events to record. These events may or
+may not be delivered to a client. Core X device events and X extension
+device events with a code value between first and last inclusive that
+are not delivered to any clients will be recorded. A
+<function>BadValue</function>
+error results if the value of first is greater than the value of last. A
+<function>BadValue</function>
+error results if first is less than two or last is less than two, except
+that if first and last are zero, no events will be recorded.
+</para>
+
+<para>
+The errors member specifies the range of both core X errors and X
+extension errors to record. Core X errors and X extension errors with
+a code value between first and last inclusive will be
+recorded. A
+<function>BadValue</function>
+error results if the value of first is greater than the value of last.
+If the values of first and last are zero, no errors will be recorded.
+</para>
+
+<para>
+A value of
+<function>True</function>
+for the client_started member specifies the
+connection setup reply from the server to new clients. If
+<function>False</function>
+the connection setup reply is not specified by this
+<function>XRecordRange</function>
+</para>
+
+<para>
+A value of
+<function>True</function>
+for the client_died member specifies
+notification when a client disconnects. If
+<function>False</function>
+notification when a client disconnects is not specified by this
+<function>XRecordRange</function>
+</para>
+</sect1>
+</chapter>
+
+<chapter id='Library_Extension_Requests'>
+<title>Library Extension Requests</title>
+
+<para>
+Recording operations are accessed by programs through the use of
+new protocol requests. The following functions are provided as extensions
+to Xlib. An Xlib error results if
+an extension request is made to an X server that does not support the
+Record extension. Note that any of the extension protocol requests may generate
+<function>BadAlloc</function>
+or
+<function>BadLength</function>
+errors.
+</para>
+
+<sect1 id='Query_Extension_Version'>
+<title>Query Extension Version</title>
+
+<para>
+An application uses the
+<xref linkend='XRecordQueryVersion' xrefstyle='select: title'/>
+function to determine
+the version of the Record extension protocol supported by an X server.
+</para>
+
+<funcsynopsis id='XRecordQueryVersion'>
+<funcprototype>
+ <funcdef>Status <function>XRecordQueryVersion</function></funcdef>
+ <paramdef>Display <parameter> *display</parameter></paramdef>
+ <paramdef>int <parameter> cmajor_return</parameter></paramdef>
+ <paramdef>int <parameter> cminor_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Returns the connection to the X server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>cmajor_return</emphasis></term>
+ <listitem><para>Returns the extension protocol major version in use.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>cminor_return</emphasis></term>
+ <listitem><para>Returns the extension protocol minor version in use.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The
+<xref linkend='XRecordQueryVersion' xrefstyle='select: title'/>
+function returns the major and minor protocol version numbers supported by
+the server.
+<xref linkend='XRecordQueryVersion' xrefstyle='select: title'/>
+returns nonzero (success) only if the returned version numbers are
+common to both the library and the server; otherwise, it returns zero.
+</para>
+</sect1>
+
+<sect1 id='Create_and_Modify_Context'>
+<title>Create and Modify Context</title>
+
+<para>
+An application uses the
+<xref linkend='XRecordCreateContext' xrefstyle='select: title'/>
+function to create a record context. At the time the record context is
+created by the recording client, the clients to be recorded and the
+protocol to record for each client may be specified.
+</para>
+
+<funcsynopsis id='XRecordCreateContext'>
+<funcprototype>
+ <funcdef>XRecordContext <function>XRecordCreateContext</function></funcdef>
+ <paramdef>Display <parameter> *display</parameter></paramdef>
+ <paramdef>int <parameter> datum_flags</parameter></paramdef>
+ <paramdef>XRecordClientSpec <parameter> *clients</parameter></paramdef>
+ <paramdef>int <parameter> nclients</parameter></paramdef>
+ <paramdef>XRecordRange <parameter> *ranges</parameter></paramdef>
+ <paramdef>int <parameter> nranges</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Returns the connection to the X server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>datum_flags</emphasis></term>
+ <listitem><para>Specifies whether detailed time or sequence info should be sent.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>clients</emphasis></term>
+ <listitem><para>Specifies the clients to record.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>nclients</emphasis></term>
+ <listitem><para>Specifies the number of clients.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>ranges</emphasis></term>
+ <listitem><para>Specifies the protocol ranges to record.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>nranges</emphasis></term>
+ <listitem><para>Specifies the number of protocol ranges.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The
+<xref linkend='XRecordCreateContext' xrefstyle='select: title'/>
+function creates a record context and returns an
+<function>XRecordContext</function>
+which is then used in the other Record library calls. This request is
+typically executed by the recording client over its control connection to
+the X server. The datum_flags specifies whether server time and/or client
+sequence number should precede protocol elements recorded by context (
+<xref linkend='Datum_Flags' xrefstyle='select: title'/>
+). When a clients element identifies a particular client, the client is added
+to the context and the protocol to record for that client is set to the
+union of all ranges. When a clients element is
+<function>XRecordCurrentClients</function>
+<function>XRecordFutureClients</function>
+or
+<function>XRecordAllClients</function>
+the actions described in
+<xref linkend='Selecting_Clients' xrefstyle='select: title'/>
+are performed.
+</para>
+
+<para>
+<xref linkend='XRecordCreateContext' xrefstyle='select: title'/>
+returns zero if the request failed.
+<xref linkend='XRecordCreateContext' xrefstyle='select: title'/>
+can generate
+<function>BadIDChoice</function>
+<function>BadMatch</function>
+and
+<function>BadValue</function>
+errors.
+</para>
+
+<para>The ranges argument is an
+<function>XRecordRange</function>
+array, that is, an array
+of pointers. The structures the elements point to shall be allocated
+by calling
+<function>XRecordAllocRange</function></para>
+
+<literallayout remap='FD'>
+XRecordRange *
+XRecordAllocRange(void)
+</literallayout> <!-- remap='FN' -->
+
+<para>
+The
+<function>XRecordAllocRange</function>
+function
+allocates and returns an
+<function>XRecordRange</function>
+structure.
+The structure is initialized to specify no protocol.
+The function returns NULL if the structure allocation fails.
+The application can free the structure by calling
+<olink targetdoc='libX11' targetptr='XFree'><function>XFree</function></olink>
+</para>
+
+<sect2 id='Additions'>
+<title>Additions</title>
+
+<para>
+An application uses the
+<xref linkend='XRecordRegisterClients' xrefstyle='select: title'/>
+function to modify a previously created
+record context, by adding clients or modifying the recorded protocol,
+typically over its control connection to the X server.
+</para>
+
+<funcsynopsis id='XRecordRegisterClients'>
+<funcprototype>
+ <funcdef>Status <function>XRecordRegisterClients</function></funcdef>
+ <paramdef>Display <parameter> *display</parameter></paramdef>
+ <paramdef>XRecordContext <parameter> context</parameter></paramdef>
+ <paramdef>int <parameter> datum_flags</parameter></paramdef>
+ <paramdef>XRecordClientSpec <parameter> *clients</parameter></paramdef>
+ <paramdef>int <parameter> nclients</parameter></paramdef>
+ <paramdef>XRecordRange <parameter> *ranges</parameter></paramdef>
+ <paramdef>int <parameter> nranges</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Returns the connection to the X server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>context</emphasis></term>
+ <listitem><para>Specifies the record context to modify.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>datum_flags</emphasis></term>
+ <listitem><para>Specifies whether detailed time or sequence info should be sent.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>clients</emphasis></term>
+ <listitem><para>Specifies the clients to record.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>nclients</emphasis></term>
+ <listitem><para>Specifies the number of clients.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>ranges</emphasis></term>
+ <listitem><para>Specifies the protocol ranges to record.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>nranges</emphasis></term>
+ <listitem><para>Specifies the number of protocol ranges.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The datum_flags specifies whether server time and/or client sequence number
+should precede protocol elements for all clients recorded by context (See
+<xref linkend='Datum_Flags' xrefstyle='select: title'/>
+). When a clients element identifies a particular client and the client is
+not yet targeted for recording in the given context, the client is added
+to the set of clients to record, and the protocol to record for that client
+is set to the union of all ranges. When the client is
+already targeted for recording, the protocol to record for that client
+is set to the union of all ranges. When the element is
+<function>XRecordCurrentClients</function>
+<function>XRecordFutureClients</function>
+or
+<function>XRecordAllClients</function>
+the actions described in
+<xref linkend='Selecting_Clients' xrefstyle='select: title'/>
+are performed.
+</para>
+
+<para>
+<xref linkend='XRecordRegisterClients' xrefstyle='select: title'/>
+returns zero if the request failed; otherwise, it
+returns nonzero.
+</para>
+
+<para>
+<xref linkend='XRecordRegisterClients' xrefstyle='select: title'/>
+can generate
+<function>XRecordBadContext</function>
+<function>BadMatch</function>
+and
+<function>BadValue</function>
+errors.
+</para>
+</sect2>
+
+<sect2 id='Deletions'>
+<title>Deletions</title>
+
+<para>
+An application uses the
+<function>XRecordUnregisterClients</function>
+function to delete clients from a previously created
+record context, typically over its control connection to the X server.
+</para>
+
+<funcsynopsis id='XRecordUnRegisterClients'>
+<funcprototype>
+ <funcdef>Status <function>XRecordUnRegisterClients</function></funcdef>
+ <paramdef>Display <parameter> *display</parameter></paramdef>
+ <paramdef>XRecordContext <parameter> context</parameter></paramdef>
+ <paramdef>XRecordClientSpec <parameter> *clients</parameter></paramdef>
+ <paramdef>int <parameter> nclients</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Returns the connection to the X server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>context</emphasis></term>
+ <listitem><para>Specifies the record context to modify.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>clients</emphasis></term>
+ <listitem><para>Specifies the clients to stop recording.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>nclients</emphasis></term>
+ <listitem><para>Specifies the number of clients.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+When an element in clients identifies a particular client, and the
+specified client is already targeted for recording in the given
+context, the client and the set of protocol to record for that
+client are deleted from the context. If the specified client is not
+targeted for recording, then no action is performed.
+</para>
+
+<para>
+When the element is
+<function>XRecordCurrentClients</function>
+all clients currently targeted for recording in context and their
+corresponding sets of protocol to record are deleted from context.
+</para>
+
+<para>
+When the item is
+<function>XRecordFutureClients</function>
+any future client connections will not automatically be targeted for
+recording in context.
+</para>
+
+<para>
+When the element is
+<function>XRecordAllClients</function>
+all clients currently targeted for recording in context and their
+corresponding sets of protocol to record are deleted from context.
+Any future client connections will not automatically be targeted
+for recording in context.
+</para>
+
+<para>
+<function>XRecordUnregisterClients</function>
+returns zero if the request failed; otherwise, it returns nonzero.
+</para>
+
+<para>
+<function>XRecordUnregisterClients</function>
+can generate
+<function>XRecordBadContext</function>
+<function>BadMatch</function>
+and
+<function>BadValue</function>
+errors.</para>
+</sect2>
+</sect1>
+
+<sect1 id='Query_Context_State'>
+<title>Query Context State</title>
+
+<para>
+An application uses the
+<xref linkend='XRecordGetContext' xrefstyle='select: title'/>
+function to query the current state of a record context, typically over
+its control connection to the X server.
+</para>
+
+<funcsynopsis id='XRecordGetContext'>
+<funcprototype>
+ <funcdef>Status <function>XRecordGetContext</function></funcdef>
+ <paramdef>Display <parameter> *display</parameter></paramdef>
+ <paramdef>XRecordContext <parameter> context</parameter></paramdef>
+ <paramdef>XRecordState <parameter> **state_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Specifies the connection to the X server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>context</emphasis></term>
+ <listitem><para>Specifies the record context to query.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>state_return</emphasis></term>
+ <listitem><para>Specifies the address of a variable into which
+the function stores a pointer to the current state of the record context.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The
+<function>XRecordState</function>
+typedef returned by
+<xref linkend='XRecordGetContext' xrefstyle='select: title'/>
+is a structure with the following members:
+</para>
+
+<literallayout remap='Ds'>
+XRecordState:
+ Bool enabled
+ int datum_flags
+ unsigned long nclients
+ XRecordClientInfo **client_info
+</literallayout>
+
+<para>
+The enabled member is set to the state of data transfer and is
+<function>True</function>
+when the recording client has asked that recorded data be sent;
+otherwise it is
+<function>False</function>
+The datum_flags member is set to the value of these flags for this context.
+The nclients member is set to the number of
+<function>XRecordClientInfo</function>
+structures returned. The client_info member is an array of pointers to
+<function>XRecordClientInfo</function>
+structures that contain the protocol to record for each targeted client. The
+<function>XRecordClientInfo</function>
+typedef is a structure with the following members:
+</para>
+
+<literallayout remap='Ds'>
+XRecordClientInfo:
+ XRecordClientSpec client
+ unsigned long nranges
+ XRecordRange **ranges
+</literallayout>
+
+<para>
+The client member either identifies a client targeted for recording
+or is set to
+<function>XRecordFutureClients</function>
+to describe how future clients will be automatically targeted for recording.
+The nranges member is set to the number of protocol
+ranges to be recorded for the specified client. The ranges member
+is an array of pointers to
+<function>XRecordRange</function>
+structures, which specify the protocol ranges to record.
+</para>
+
+<para>
+<xref linkend='XRecordGetContext' xrefstyle='select: title'/>
+returns zero if the request failed; otherwise, it returns nonzero.
+The context argument must specify a valid
+<function>XRecordContext</function>
+or a
+<function>XRecordBadContext</function>
+error results.
+</para>
+
+<para>
+Recording clients should use the
+<xref linkend='XRecordFreeState' xrefstyle='select: title'/>
+function to free the state data returned by
+<xref linkend='XRecordGetContext' xrefstyle='select: title'/>
+</para>
+
+<funcsynopsis id='XRecordFreeState'>
+<funcprototype>
+ <funcdef>void <function>XRecordFreeState</function></funcdef>
+ <paramdef>XRecordState <parameter> *state</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>state</emphasis></term>
+ <listitem><para>Specifies the structure that is to be freed.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<xref linkend='XRecordFreeState' xrefstyle='select: title'/>
+frees the data pointed to by state. If the argument does not match an
+<function>XRecordState</function>
+pointer returned from a successful call to
+<xref linkend='XRecordGetContext' xrefstyle='select: title'/>
+or if
+<xref linkend='XRecordFreeState' xrefstyle='select: title'/>
+has already been called with it, the behavior is undefined.
+</para>
+</sect1>
+
+<sect1 id='Data_Transfer'>
+<title>Data Transfer</title>
+
+<para>
+An application uses the
+<xref linkend='XRecordEnableContext' xrefstyle='select: title'/>
+and
+<xref linkend='XRecordDisableContext' xrefstyle='select: title'/>
+functions to change the state of data transfer
+between the X server and the recording client. These functions allow
+the application to start recording and reporting of protocol data
+and to stop recording and reporting of protocol data, respectively.
+</para>
+
+<sect2 id='Enable_Context'>
+<title>Enable Context</title>
+
+<para>
+To direct the X server to record and report protocol, a program uses
+<xref linkend='XRecordEnableContext' xrefstyle='select: title'/>
+typically over its data connection to the X
+server. The reporting of recorded protocol back to the recording client
+is handled by the following data structures and procedure definitions.
+Each recorded protocol element is reported to the recording client through an
+<function>XRecordInterceptData</function>
+typedef, a structure with the following members:
+</para>
+
+<literallayout remap='Ds'>
+XRecordInterceptData:
+ XID id_base
+ Time server_time
+ unsigned long client_seq
+ int category
+ Bool client_swapped
+ unsigned char *data
+ unsigned long data_len
+</literallayout>
+
+<para>
+The id_base member is set to the resource identifier base sent to the
+client in the connection setup reply and therefore identifies the client
+being recorded, except when the recorded protocol data is a device
+event that may have not been delivered to a client. In this case,
+id_base is set to zero. The server_time member
+is set to the time of the server when the protocol was recorded.
+It is the time that was attached to this protocol element in the reply,
+if so specified by datum_flags,
+or else the time from the header of the reply that contained
+this protocol element.
+The client_seq member is the sequence number of the recorded
+client's most recent request processed by the server at the time this
+protocol element was recorded, if this information were included in the
+recorded data; otherwise client_seq is 0.
+The category member is set to one of the following values:
+<function>XRecordStartOfData</function>
+<function>XRecordFromServer</function>
+<function>XRecordFromClient</function>
+<function>XRecordClientStarted</function>
+<function>XRecordClientDied</function>
+or
+<function>XRecordEndOfData</function>
+<function>XRecordStartOfData</function>
+is immediately sent as the first reply to confirm that the context is enabled.
+<function>XRecordFromClient</function>
+indicates the protocol
+data is from the recorded client to the server (requests).
+<function>XRecordFromServer</function>
+indicates the protocol data is from the server to the recorded client
+(replies, errors, events, or device events).
+<function>XRecordClientStarted</function>
+indicates that the protocol data is the connection setup reply from the server.
+<function>XRecordClientDied</function>
+indicates that the recorded client has closed its connection
+to the X server; there is no protocol data.
+<function>XRecordEndOfData</function>
+indicates that the context has been disabled and that
+this is the last datum. It does not correspond to any protocol or
+state change in a recorded client. There is no protocol data.
+</para>
+
+<para>
+The client_swapped member is set to
+<function>True</function>
+if the byte order of the client being recorded is swapped relative to
+the recording client; otherwise, it is set to
+<function>False</function>
+All recorded protocol data is returned in the byte order of the recorded
+client. Therefore, recording clients are responsible for all byte swapping,
+if required. Device events are in the byte order of the recording client.
+For replies of category
+<function>XRecordStartOfData</function>
+and
+<function>XRecordEndOfData</function>
+client_swapped is set according
+to the byte order of the server relative to the recording client.
+</para>
+
+<para>
+The data member contains the actual recorded protocol data.
+When category is set to
+<function>XRecordStartOfData</function>
+<function>XRecordClientDied</function>
+or
+<function>XRecordEndOfData</function>
+no protocol data are contained in data.
+</para>
+
+
+<!-- copied exactly from the protocol document -->
+<para>
+For the core X events
+<function>KeyPress</function>
+<function>KeyRelease</function>
+<function>ButtonPress</function>
+and
+<function>ButtonRelease</function>,
+the fields of a device event that contain
+valid information are time and detail. For the core X event
+<function>MotionNotify</function>
+the fields of a device event that contain valid information are time, root,
+root-x and root-y.
+The time field refers to the time the event was generated by the device.
+</para>
+
+<para>For the extension input device events
+<function>DeviceKeyPress</function>
+<function>DeviceKeyRelease</function>
+<function>DeviceButtonPress</function>
+and
+<function>DeviceButtonRelease</function>
+the fields of a device event that contain valid information are
+device, time, and detail. For
+<function>DeviceMotionNotify</function>
+the valid device event fields are device and time.
+For the extension input device events
+<function>ProximityIn</function>
+and
+<function>ProximityOut</function>
+the fields of a device event that contain valid
+information are device and time. For the extension input device event
+<function>DeviceValuator</function>
+the fields of a device event that contain valid information are
+device, num_valuators, first_valuator, and valuators.
+The time field refers to the time the event was generated by the device.
+</para>
+
+
+<para>
+The data_len member is set to the length of the actual recorded protocol
+data in 4-byte units.
+</para>
+
+<para>
+When the context has been enabled, protocol data the recording client has
+previously expressed interest in is recorded and returned to the
+recording client via multiple replies. Because the X server batches
+the recorded data, more than one protocol element may be contained
+in the same reply packet. When a reply is received, a procedure of type
+<function>XRecordInterceptProc</function>
+is called for each protocol element in the reply.
+</para>
+
+<funcsynopsis id='XRecordInterceptProc'>
+<funcprototype>
+ <funcdef>typedef void <function>(*XRecordInterceptProc)</function></funcdef>
+ <paramdef>XPointer<parameter> closure</parameter></paramdef>
+ <paramdef>XRecordInterceptData<parameter> *recorded_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>closure</emphasis></term>
+ <listitem><para>Pointer that was passed in when the context was enabled.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>recorded_data</emphasis></term>
+ <listitem><para>A protocol element recorded by the server extension.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+This callback may use the control display connection (or any display
+connection other than the data connection).
+</para>
+
+<para>
+Recording clients should use the
+<xref linkend='XRecordFreeData' xrefstyle='select: title'/>
+function to free the
+<function>XRecordInterceptData</function>
+structure.
+</para>
+
+<funcsynopsis id='XRecordEnableContext'>
+<funcprototype>
+ <funcdef>Status <function>XRecordEnableContext</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XRecordContext<parameter> context</parameter></paramdef>
+ <paramdef>XRecordInterceptProc<parameter> callback</parameter></paramdef>
+ <paramdef>XPointer<parameter> closure</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Specifies the connection to the X server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>context</emphasis></term>
+ <listitem><para>Specifies the record context to enable.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>callback</emphasis></term>
+ <listitem><para>Specifies the function to be called for each protocol element received.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>closure</emphasis></term>
+ <listitem><para>Specifies data passed to callback.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+
+<para>
+<xref linkend='XRecordEnableContext' xrefstyle='select: title'/>
+enables data transfer between the recording client and
+the X server. All core and extension protocol received from or sent to
+targeted clients that the recording client has expressed
+interest in will be recorded and reported to the recording client.
+</para>
+
+<para>
+<xref linkend='XRecordEnableContext' xrefstyle='select: title'/>
+returns zero if the request failed; otherwise, it
+returns nonzero. The context argument must specify a valid
+<function>XRecordContext</function>
+or a
+<function>XRecordBadContext</function>
+error results. The error
+<function>BadMatch</function>
+results when data transfer is already enabled on the given context.
+</para>
+</sect2>
+
+<sect2 id='Enable_Context_Asynchronously'>
+<title>Enable Context Asynchronously</title>
+
+<para>Because
+<xref linkend='XRecordEnableContext' xrefstyle='select: title'/>
+does not return until
+<xref linkend='XRecordDisableContext' xrefstyle='select: title'/>
+is executed on the control connection, a nonblocking interface in
+addition to
+<xref linkend='XRecordEnableContext' xrefstyle='select: title'/>
+is provided. This interface also
+enables data transfer; however, it does not block.
+</para>
+
+<para>
+This interface is defined as follows:
+</para>
+
+<funcsynopsis id='XRecordEnableContextAsync'>
+<funcprototype>
+ <funcdef>Status <function>XRecordEnableContextAsync</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XRecordContext<parameter> context</parameter></paramdef>
+ <paramdef>XRecordInterceptProc<parameter> callback</parameter></paramdef>
+ <paramdef>XPointer<parameter> closure</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Specifies the connection to the X server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>context</emphasis></term>
+ <listitem><para>Specifies the record context to enable.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>callback</emphasis></term>
+ <listitem><para>Specifies the function to be called for each protocol element received.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>closure</emphasis></term>
+ <listitem><para>Specifies data passed to callback.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<xref linkend='XRecordEnableContextAsync' xrefstyle='select: title'/>
+enables data transfer between the recording
+client and the X server just as
+<xref linkend='XRecordEnableContext' xrefstyle='select: title'/>
+does. Unlike
+<xref linkend='XRecordEnableContext' xrefstyle='select: title'/>
+it does not wait for the context to be disabled
+before returning;
+<xref linkend='XRecordEnableContextAsync' xrefstyle='select: title'/>
+returns as soon as the
+<function>XRecordStartOfData</function>
+reply has been received and processed.
+</para>
+
+<para>
+<xref linkend='XRecordEnableContextAsync' xrefstyle='select: title'/>
+returns zero if it could not allocate the
+necessary memory and nonzero if it sent the request successfully to
+the server. The context argument must specify a valid
+<function>XRecordContext</function>
+or a
+<function>XRecordBadContext</function>
+error results. The error
+<function>BadMatch</function>
+results when data transfer is already enabled.
+</para>
+
+<para>
+Each time it reads data from the server connection, Xlib will check
+for incoming replies and call <emphasis remap='I'>callback</emphasis>
+as necessary. The application may direct Xlib explicitly to check
+for Record data with the
+<xref linkend='XRecordProcessReplies' xrefstyle='select: title'/>
+function.
+</para>
+
+<funcsynopsis id='XRecordProcessReplies'>
+<funcprototype>
+ <funcdef>void <function>XRecordProcessReplies</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Specifies the connection to the X server.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<xref linkend='XRecordProcessReplies' xrefstyle='select: title'/>
+will check for any replies that have not yet
+been processed by the application. The asynchronous callback will be called
+as appropriate.
+<xref linkend='XRecordProcessReplies' xrefstyle='select: title'/>
+returns when all immediately
+available replies have been processed. It does not block.
+</para>
+
+<para>To free the data passed to the
+<function>XRecordInterceptProc</function>
+callback, use
+<xref linkend='XRecordFreeData' xrefstyle='select: title'/></para>
+
+<funcsynopsis id='XRecordFreeData'>
+<funcprototype>
+ <funcdef>void <function>XRecordFreeData</function></funcdef>
+ <paramdef>XRecordInterceptData<parameter> *data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>data</emphasis></term>
+ <listitem><para>Specifies the structure that is to be freed.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+
+<para>
+<xref linkend='XRecordFreeData' xrefstyle='select: title'/>
+frees the data pointed to by data. If the argument does not match an
+<function>XRecordInterceptData</function>
+pointer earlier passed to an
+<function>XRecordInterceptProc</function>
+callback or if
+<xref linkend='XRecordFreeData' xrefstyle='select: title'/>
+has already been called with it, the behavior is undefined.
+</para>
+</sect2>
+
+<sect2 id='Disable_Context'>
+<title>Disable Context</title>
+
+<para>
+To direct the X server to halt the reporting of recorded protocol, the
+program executes
+<xref linkend='XRecordDisableContext' xrefstyle='select: title'/>
+typically over its control connection to the X server.
+</para>
+
+<funcsynopsis id='XRecordDisableContext'>
+<funcprototype>
+ <funcdef>Status <function>XRecordDisableContext</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XRecordContext<parameter> context</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Specifies the connection to the X server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>context</emphasis></term>
+ <listitem><para>Specifies the record context to disable.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+
+<para>
+The
+<xref linkend='XRecordDisableContext' xrefstyle='select: title'/>
+function disables context, stopping all recording over its data connection.
+Any complete protocol elements for context that were buffered in the
+server will be sent to the recording client rather than being discarded.
+If a program attempts to disable an
+<function>XRecordContext</function>
+that has not been enabled, no action will take place.
+</para>
+
+<para>
+<xref linkend='XRecordDisableContext' xrefstyle='select: title'/>
+returns zero if the request failed; otherwise, it
+returns nonzero. The context argument must specify a valid
+<function>XRecordContext</function>
+or an
+<function>XRecordBadContext</function>
+error results.
+</para>
+</sect2>
+</sect1>
+
+<sect1 id='ID_Base_Mask'>
+<title>ID Base Mask</title>
+
+<para>
+To determine the mask the server uses for the client ID base, use
+<xref linkend='XRecordIdBaseMask' xrefstyle='select: title'/></para>
+
+<funcsynopsis id='XRecordIdBaseMask'>
+<funcprototype>
+ <funcdef>XID <function>XRecordIdBaseMask</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Specifies the connection to the X server.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The
+<xref linkend='XRecordIdBaseMask' xrefstyle='select: title'/>
+function returns the resource ID mask passed to the client by the
+server at connection setup.
+</para>
+
+</sect1>
+
+<sect1 id='Free_Context'>
+<title>Free Context</title>
+
+<para>
+Before terminating, the program should request that the server
+free the record context. This is done with the
+<xref linkend='XRecordFreeContext' xrefstyle='select: title'/>
+function, typically over the record client's control connection
+to the X server.
+</para>
+
+<funcsynopsis id='XRecordFreeContext'>
+<funcprototype>
+ <funcdef>Status <function>XRecordFreeContext</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XRecordContext<parameter> context</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem><para>Specifies the connection to the X server.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='I'>context</emphasis></term>
+ <listitem><para>Specifies the record context to free.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The
+<xref linkend='XRecordFreeContext' xrefstyle='select: title'/>
+function frees the given context for the
+requesting client. Freeing a record context releases the clients
+targeted for recording and their respective protocol ranges to
+record. If protocol data is being reported to the recording client,
+generally over the data connection to the X server, the reporting
+ceases as if
+<xref linkend='XRecordDisableContext' xrefstyle='select: title'/>
+had been called on the given context. When a program terminates
+without freeing its record context, the X server will automatically
+free that context on behalf of the client.
+</para>
+
+<para>
+<xref linkend='XRecordFreeContext' xrefstyle='select: title'/>
+returns zero if the request failed; otherwise,it
+returns nonzero. The context argument must specify a valid
+<function>XRecordContext</function>
+or a
+<function>XRecordBadContext</function>
+error results.
+</para>
+
+</sect1>
+</chapter>
+</book>
diff --git a/specs/xtestlib.xml b/specs/xtestlib.xml
new file mode 100644
index 0000000..463149a
--- /dev/null
+++ b/specs/xtestlib.xml
@@ -0,0 +1,458 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+
+<!-- lifted from troff+ms+XMan by doclifter -->
+<book id="xtestlib">
+
+<bookinfo>
+ <title>XTEST Extension Library</title>
+ <subtitle>X Consortium Standard</subtitle>
+ <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo>
+ <releaseinfo>Version 2.2</releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>Kieron</firstname><surname>Drake</surname>
+ <affiliation><orgname>UniSoft Ltd.</orgname></affiliation>
+ </author>
+ </authorgroup>
+ <copyright><year>1992</year><holder>UniSoft Group Ltd.</holder></copyright>
+
+<legalnotice>
+<para>
+Permission to use, copy, modify, and distribute this documentation for
+any purpose and without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies. UniSoft
+makes no representations about the suitability for any purpose of the
+information in this document. This documentation is provided
+&ldquo;as is&rdquo; without express or implied warranty.
+</para>
+</legalnotice>
+
+<legalnotice>
+<para role="multiLicensing">Copyright © 1992,1994 X Consortium</para>
+<para>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files
+(the &ldquo;Software&rdquo;), 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:
+</para>
+<para>
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+</para>
+<para>
+THE SOFTWARE IS PROVIDED &ldquo;AS IS&rdquo;, 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 X CONSORTIUM 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.
+</para>
+<para>
+Except as contained in this notice, the name of the X Consortium 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 X Consortium.
+</para>
+<para>X Window System is a trademark of The Open Group.</para>
+</legalnotice>
+</bookinfo>
+
+<chapter id='Overview'>
+<title>Overview</title>
+
+<para>
+This extension is a minimal set of client and server extensions
+required to completely test the X11 server with no user intervention.
+</para>
+
+<para>
+This extension is not intended to support general journaling and
+playback of user actions. This is a difficult area [XTrap, 89] as it attempts
+to synchronize synthetic user interactions with their effects; it is at the
+higher level of dialogue recording/playback rather than at the strictly lexical
+level. We are interested only in the latter, simpler, case. A more detailed
+discussion and justification of the extension functionality is given in
+[Drake, 91].
+</para>
+
+<para>
+We are aiming only to provide a minimum set of facilities that
+solve immediate testing and validation problems. The testing extension
+itself needs testing, where possible, and so should be as simple as possible.
+</para>
+
+<para>We have also tried to:</para>
+<itemizedlist mark='bullet'>
+ <listitem>
+ <para>
+Confine the extension to an appropriate high level
+within the server to minimize portability problems. In practice this
+means that the extension should be at the DIX level or use the
+DIX/DDX interface, or both. This has effects, in particular, on the
+level at which "input synthesis" can occur.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Minimize the changes required in the rest of the server.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Minimize performance penalties on normal server operation.
+ </para>
+ </listitem>
+</itemizedlist>
+</chapter>
+
+<chapter id='Description'>
+<title>Description</title>
+
+<para>The functions provided by this extension fall into two groups:</para>
+
+<itemizedlist>
+ <listitem>
+ <para>Client Operations</para>
+ <para>
+These routines manipulate otherwise hidden client-side behavior.
+The actual implementation will depend on the details of the actual language
+binding and what degree of request buffering, GContext caching, and so on, is
+provided. In the C binding, defined in section 7, routines are provided
+to access the internals of two opaque data structures -
+<symbol role='Pn'>GC</symbol>s
+and
+<function>Visual</function>s - and to discard any requests pending within the
+output buffer of a connection. The exact details can be expected to differ for
+other language bindings.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Server Requests</para>
+ <para>
+The first of these requests is similar to that provided in most
+extensions: it allows a client to specify a major and minor version
+number to the server and for the server to respond with major and minor
+versions of its own. The remaining two requests allow the following:
+ </para>
+ </listitem>
+ <listitem>
+ <itemizedlist>
+ <listitem>
+ <para>
+Access to an otherwise "write-only" server resource: the
+cursor associated with a given window
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Perhaps most importantly, limited synthesis of input
+device events, almost as if a cooperative user had moved the pointing device
+or pressed a key or button.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+</itemizedlist>
+</chapter>
+
+<chapter id='C_Language_Binding'>
+<title>C Language Binding</title>
+
+<para>
+The C functions either provide direct access to the protocol and add no
+additional semantics to those defined in section 5 or they correspond
+directly to the abstract descriptions of client operations in section 4.
+</para>
+
+<para>
+All XTEST extension functions and procedures, and all manifest constants
+and macros, will start with the string "XTest". All operations are
+classified as server/client (Server) or client-only (Client).
+All routines that have return type Status will return nonzero for
+"success" and zero for "failure." Even if the XTEST extension is
+supported, the server may withdraw such facilities arbitrarily; in which case
+they will subsequently return zero.
+</para>
+
+<para>
+The include file for this extension is
+&lt;<symbol role='Pn'>X11/extensions/XTest.h</symbol>&gt;.
+</para>
+
+<funcsynopsis id='XTestQueryExtension'>
+<funcprototype>
+<funcdef>Bool<function> XTestQueryExtension</function></funcdef>
+<paramdef>Display<parameter> *display</parameter></paramdef>
+<paramdef>int<parameter> *event_base</parameter></paramdef>
+<paramdef>int<parameter> *error_base</parameter></paramdef>
+<paramdef>int<parameter> *major_version</parameter></paramdef>
+<paramdef>int<parameter> *minor_version</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>
+<xref linkend='XTestQueryExtension' xrefstyle='select: title'/>
+returns
+<function>True</function>
+if the specified display supports the XTEST extension, else
+<function>False</function>
+If the extension is supported, *event_base would be set to the event number
+for the first event for this extension and *error_base would be set to the
+error number for the first error for this extension. As no errors or
+events are defined for this version of the extension, the values returned
+here are not defined (nor useful). If the extension is supported,
+*major_version and *minor_version are set to the major and minor version
+numbers of the extension supported by the display. Otherwise, none of
+the arguments are set.
+</para>
+
+<funcsynopsis id='XTestCompareCursorWithWindow'>
+<funcprototype>
+<funcdef>Bool<function> XTestCompareCursorWithWindow</function></funcdef>
+<paramdef>Display<parameter> *display</parameter></paramdef>
+<paramdef>Window<parameter> *window</parameter></paramdef>
+<paramdef>Cursor<parameter> cursor</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>If the extension is supported,
+<xref linkend='XTestCompareCursorWithWindow' xrefstyle='select: title'/>
+performs a comparison of the cursor whose ID is specified by cursor (which
+may be
+<function>None</function>
+with the cursor of the window specified by window returning
+<function>True</function>
+if they are the same and
+<function>False</function>
+otherwise. If the extension is not supported, then the request is ignored and
+zero is returned.
+</para>
+
+<funcsynopsis id='XTestCompareCurrentCursorWithWindow'>
+<funcprototype>
+<funcdef>Bool<function>XTestCompareCurrentCursorWithWindow</function></funcdef>
+<paramdef>Display<parameter> *display</parameter></paramdef>
+<paramdef>Window<parameter> window</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>If the extension is supported,
+<xref linkend='XTestCompareCurrentCursorWithWindow' xrefstyle='select: title'/>
+performs a comparison of the current cursor with the cursor of the specified
+window returning
+<function>True</function>
+if they are the same and
+<function>False</function>
+otherwise. If the extension is not supported, then the request is ignored and
+zero is returned.
+</para>
+
+<funcsynopsis id='XTestFakeKeyEvent'>
+<funcprototype>
+<funcdef><function>XTestFakeKeyEvent</function></funcdef>
+<paramdef>Display<parameter> *display</parameter></paramdef>
+<paramdef>unsigned int<parameter> keycode</parameter></paramdef>
+<paramdef>Bool<parameter> is_press</parameter></paramdef>
+<paramdef>unsigned long<parameter> delay</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>If the extension is supported,
+<xref linkend='XTestFakeKeyEvent' xrefstyle='select: title'/>
+requests the server to simulate either a
+<function>KeyPress</function>
+(if is_press is
+<function>True</function>
+or a
+<function>KeyRelease</function>
+(if is_press is
+<function>False</function>
+of the key with the specified keycode; otherwise, the request is ignored.
+</para>
+
+<para>
+If the extension is supported, the simulated event will not be processed
+until delay milliseconds after the request is received (if delay is
+<function>CurrentTime</function>
+then this is interpreted as no delay at all). No other requests from
+this client will be processed until this delay, if any, has expired
+and subsequent processing of the simulated event has been completed.
+</para>
+
+<funcsynopsis id='XTestFakeButtonEvent'>
+<funcprototype>
+<funcdef><function>XTestFakeButtonEvent</function></funcdef>
+<paramdef>Display<parameter> *display</parameter></paramdef>
+<paramdef>unsigned int<parameter> button</parameter></paramdef>
+<paramdef>Bool<parameter> is_press</parameter></paramdef>
+<paramdef>unsigned long<parameter> delay</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>If the extension is supported,
+<xref linkend='XTestFakeButtonEvent' xrefstyle='select: title'/>
+requests the server to simulate either a
+<function>ButtonPress</function>
+(if is_press is
+<function>True</function>
+or a
+<function>ButtonRelease</function>
+(if is_press is
+<function>False</function>
+of the logical button numbered by the specified button; otherwise, the
+request is ignored.
+</para>
+
+<para>If the extension is supported,
+the simulated event will not be processed until delay milliseconds
+after the request is received (if delay is
+<function>CurrentTime</function>
+then this is interpreted as no delay at all). No other requests from
+this client will be processed until this delay, if any, has expired
+and subsequent processing of the simulated event has been completed.
+</para>
+
+<funcsynopsis id='XTestFakeMotionEvent'>
+<funcprototype>
+<funcdef><function>XTestFakeMotionEvent</function></funcdef>
+<paramdef>Display<parameter> *display</parameter></paramdef>
+<paramdef>int<parameter> screen_number</parameter></paramdef>
+<paramdef>int<parameter> x</parameter></paramdef>
+<paramdef>int<parameter> y</parameter></paramdef>
+<paramdef>unsigned long<parameter> delay</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>If the extension is supported,
+<xref linkend='XTestFakeMotionEvent' xrefstyle='select: title'/>
+requests the server to simulate a movement of the pointer to the specified
+position (x, y) on the root window of screen_number; otherwise, the request
+is ignored. If screen_number is -1, the current screen (that the pointer
+is on) is used.
+</para>
+
+<para>
+If the extension is supported, the simulated event will not be processed
+until delay milliseconds after the request is received (if delay is
+<function>CurrentTime</function>
+then this is interpreted as no delay at all). No other requests from
+this client will be processed until this delay, if any, has expired
+and subsequent processing of the simulated event has been completed.
+</para>
+
+<funcsynopsis id='XTestFakeRelativeMotionEvent'>
+<funcprototype>
+<funcdef><function>XTestFakeRelativeMotionEvent</function></funcdef>
+<paramdef>Display<parameter> *display</parameter></paramdef>
+<paramdef>int<parameter> screen_number</parameter></paramdef>
+<paramdef>int<parameter> x</parameter></paramdef>
+<paramdef>int<parameter> y</parameter></paramdef>
+<paramdef>unsigned long<parameter> delay</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>
+If the extension is supported,
+<xref linkend='XTestFakeRelativeMotionEvent' xrefstyle='select: title'/>
+requests the server to simulate a movement of the pointer by the specified
+offsets (x, y) relative to the current pointer position on screen_number;
+otherwise, the request is ignored. If screen_number is -1, the
+current screen (that the pointer is on) is used.
+</para>
+
+<para>
+If the extension is supported, the simulated event will not be processed
+until delay milliseconds after the request is received (if delay is
+<function>CurrentTime</function>
+then this is interpreted as no delay at all). No other requests from
+this client will be processed until this delay, if any, has expired
+and subsequent processing of the simulated event has been completed.
+</para>
+
+<funcsynopsis id='XTestGrabControl'>
+<funcprototype>
+<funcdef><function>XTestGrabControl</function></funcdef>
+<paramdef>Display<parameter> *display</parameter></paramdef>
+<paramdef>Bool<parameter> impervious</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>If impervious is
+<function>True</function>
+then the executing client becomes impervious to server grabs. If impervious is
+<function>False</function>
+then the executing client returns to the normal state of being susceptible
+to server grabs.
+</para>
+
+<funcsynopsis id='XTestSetGContextOfGC'>
+<funcprototype>
+<funcdef>Bool<function> XTestSetGContextOfGC</function></funcdef>
+<paramdef>GC<parameter> gc</parameter></paramdef>
+<paramdef>GContext<parameter> gid</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>
+<xref linkend='XTestSetGContextOfGC' xrefstyle='select: title'/>
+sets the GContext within the opaque datatype referenced by gc to
+be that specified by gid.
+</para>
+
+<funcsynopsis id='XTestSetVisualIDOfVisual'>
+<funcprototype>
+<funcdef><function>XTestSetVisualIDOfVisual</function></funcdef>
+<paramdef>Visual<parameter> *visual</parameter></paramdef>
+<paramdef>VisualID<parameter> visualid</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>
+<xref linkend='XTestSetVisualIDOfVisual' xrefstyle='select: title'/>
+sets the VisualID within the opaque datatype referenced by visual to
+be that specified by visualid.
+</para>
+
+<funcsynopsis id='XTestDiscard'>
+<funcprototype>
+<funcdef>Bool<function> XTestDiscard</function></funcdef>
+<paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>
+<xref linkend='XTestDiscard' xrefstyle='select: title'/>
+discards any requests within the output buffer for the specified display.
+It returns
+<function>True</function>
+if any requests were discarded; otherwise, it returns
+<function>False</function>
+</para>
+</chapter>
+
+<chapter id='References'>
+<title>References</title>
+
+<para>
+Annicchiarico, D., et al., <emphasis remap='I'>XTrap: The XTrap
+Architecture</emphasis>.
+Digital Equipment Corporation, July 1991.
+</para>
+
+<para>
+Drake, K. J., <emphasis remap='I'>Some Proposals for a Minimum X11
+Testing Extension</emphasis>.
+UniSoft Ltd., June 1991.
+</para>
+
+</chapter>
+</book>
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..1091ece
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,27 @@
+lib_LTLIBRARIES = libXtst.la
+
+libXtst_la_SOURCES = \
+ XRecord.c \
+ XTest.c
+
+libXtst_la_LIBADD = @XTST_LIBS@
+
+AM_CFLAGS = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/include/X11/extensions \
+ $(XTST_CFLAGS) \
+ $(CWARNFLAGS)
+
+libXtst_la_LDFLAGS = -version-number 6:1:0 -no-undefined
+
+libXtstincludedir = $(includedir)/X11/extensions
+libXtstinclude_HEADERS = $(top_srcdir)/include/X11/extensions/XTest.h \
+ $(top_srcdir)/include/X11/extensions/record.h
+
+if LINT
+ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS)
+
+lint:
+ $(LINT) $(ALL_LINT_FLAGS) $(libXtst_la_SOURCES) $(XTST_LIBS)
+endif LINT
diff --git a/src/XRecord.c b/src/XRecord.c
new file mode 100644
index 0000000..b65451c
--- /dev/null
+++ b/src/XRecord.c
@@ -0,0 +1,1073 @@
+/*
+XRecord.c - client-side library for RECORD extension
+
+Copyright 1995, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+/***************************************************************************
+ * Copyright 1995 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMs ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************/
+/*
+ * By Stephen Gildea, X Consortium, and Martha Zimet, NCD.
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <X11/extensions/recordproto.h>
+#include <X11/extensions/record.h>
+
+static XExtensionInfo _xrecord_info_data;
+static XExtensionInfo *xrecord_info = &_xrecord_info_data;
+static const char *xrecord_extension_name = RECORD_NAME;
+
+#define XRecordCheckExtension(dpy,i,val) \
+ XextCheckExtension(dpy, i, xrecord_extension_name, val)
+
+/**************************************************************************
+ * *
+ * private utility routines *
+ * *
+ **************************************************************************/
+
+static XExtDisplayInfo *find_display(Display *dpy);
+
+/*
+ * A reply buffer holds a reply from RecordEnableContext.
+ * Pieces of that buffer are passed to the XRecordEnableContext callback.
+ * ref_count is incremented each time we do that.
+ * ref_count is decremented each time XRecordFreeData is called on
+ * the buffer. When ref_count is 0, we can free or reuse the buffer.
+ */
+struct reply_buffer
+{
+ struct reply_buffer *next; /* next in list or NULL */
+ unsigned char *buf; /* pointer to malloc'd buffer */
+ int nbytes; /* size of buf */
+ int ref_count; /* callback uses pending */
+};
+
+
+/*
+ * There's some extra information the implementation finds useful
+ * to attach to an XRecordInterceptData packet to handle memory
+ * management. So we really allocate one of these.
+ */
+struct intercept_queue
+{
+ /* this struct gets passed to the user as an XRecordInterceptData,
+ so the data field must come first so we can cast the address
+ back and forth */
+ XRecordInterceptData data;
+ struct intercept_queue *next; /* next in free list or NULL */
+ struct mem_cache_str *cache; /* contains head of free list */
+};
+
+/*
+ * per-display pointers to cache of malloc'd but unused memory
+ */
+struct mem_cache_str
+{
+ struct intercept_queue *inter_data; /* free structs only */
+ struct reply_buffer *reply_buffers; /* all reply buffers */
+ int inter_data_count; /* total allocated, free and in use */
+ Bool display_closed; /* so we know when to free ourself */
+};
+
+static int close_display(
+ Display *dpy,
+ XExtCodes *codes) /* not used */
+{
+ XExtDisplayInfo *info = find_display (dpy);
+
+ LockDisplay(dpy);
+ if (info && info->data) {
+ struct mem_cache_str *cache = (struct mem_cache_str *)info->data;
+ struct intercept_queue *iq, *iq_next;
+ struct reply_buffer *rbp, **rbp_next_p;
+
+ for (iq=cache->inter_data; iq; iq=iq_next) {
+ iq_next = iq->next;
+ XFree(iq);
+ cache->inter_data_count--;
+ }
+
+ /* this is a little trickier, because some of these
+ might still be in use */
+ for (rbp_next_p = &cache->reply_buffers; *rbp_next_p; ) {
+ rbp = *rbp_next_p;
+ if (rbp->ref_count == 0) {
+ *rbp_next_p = rbp->next;
+ XFree(rbp->buf);
+ XFree(rbp);
+ } else {
+ rbp_next_p = &rbp->next;
+ }
+ }
+
+ if (cache->reply_buffers == NULL && cache->inter_data_count == 0) {
+ /* every thing has been freed, can free ourselves, too */
+ XFree(cache);
+ } else {
+ cache->display_closed = True;
+ cache->inter_data = NULL; /* neatness only; won't be used */
+ }
+ }
+ UnlockDisplay(dpy);
+ return XextRemoveDisplay(xrecord_info, dpy);
+}
+
+static XPointer alloc_mem_cache(void)
+{
+ struct mem_cache_str *cache;
+
+ /* note that an error will go unnoticed */
+ cache = (struct mem_cache_str *) Xmalloc(sizeof(struct mem_cache_str));
+ if (cache) {
+ cache->display_closed = False;
+ cache->inter_data = NULL;
+ cache->inter_data_count = 0;
+ cache->reply_buffers = NULL;
+ }
+ return (XPointer) cache;
+}
+
+static const char *xrecord_error_list[] = {
+ "XRecordBadContext (Not a defined RECORD context)",
+};
+
+static XEXT_GENERATE_ERROR_STRING (error_string, xrecord_extension_name,
+ RecordNumErrors, xrecord_error_list)
+
+static XExtensionHooks xrecord_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ close_display, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ error_string /* error_string */
+};
+
+static XEXT_GENERATE_FIND_DISPLAY (find_display, xrecord_info,
+ xrecord_extension_name, &xrecord_extension_hooks, RecordNumEvents,
+ alloc_mem_cache())
+
+/**************************************************************************
+ * *
+ * private library routines *
+ * *
+ **************************************************************************/
+
+static void
+SendRange(
+ Display *dpy,
+ XRecordRange **range_item,
+ int nranges)
+{
+ int rlen = SIZEOF(xRecordRange);
+ while(nranges--)
+ {
+ xRecordRange xrange;
+
+ xrange.coreRequestsFirst = (*range_item)->core_requests.first;
+ xrange.coreRequestsLast = (*range_item)->core_requests.last;
+ xrange.coreRepliesFirst = (*range_item)->core_replies.first;
+ xrange.coreRepliesLast = (*range_item)->core_replies.last;
+ xrange.extRequestsMajorFirst = (*range_item)->ext_requests.ext_major.first;
+ xrange.extRequestsMajorLast = (*range_item)->ext_requests.ext_major.last;
+ xrange.extRequestsMinorFirst = (*range_item)->ext_requests.ext_minor.first;
+ xrange.extRequestsMinorLast = (*range_item)->ext_requests.ext_minor.last;
+ xrange.extRepliesMajorFirst = (*range_item)->ext_replies.ext_major.first;
+ xrange.extRepliesMajorLast = (*range_item)->ext_replies.ext_major.last;
+ xrange.extRepliesMinorFirst = (*range_item)->ext_replies.ext_minor.first;
+ xrange.extRepliesMinorLast = (*range_item)->ext_replies.ext_minor.last;
+ xrange.deliveredEventsFirst = (*range_item)->delivered_events.first;
+ xrange.deliveredEventsLast = (*range_item)->delivered_events.last;
+ xrange.deviceEventsFirst = (*range_item)->device_events.first;
+ xrange.deviceEventsLast = (*range_item)->device_events.last;
+ xrange.errorsFirst = (*range_item)->errors.first;
+ xrange.errorsLast = (*range_item)->errors.last;
+ xrange.clientStarted = (*range_item)->client_started;
+ xrange.clientDied = (*range_item)->client_died;
+
+ Data(dpy, (char *)&xrange, rlen);
+ range_item++;
+ }
+}
+
+/**************************************************************************
+ * *
+ * public routines *
+ * *
+ **************************************************************************/
+
+XID
+XRecordIdBaseMask(Display *dpy)
+{
+ return 0x1fffffff & ~dpy->resource_mask;
+}
+
+Status
+XRecordQueryVersion(Display *dpy, int *cmajor_return, int *cminor_return)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xRecordQueryVersionReq *req;
+ xRecordQueryVersionReply rep;
+
+ XRecordCheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(RecordQueryVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->recordReqType = X_RecordQueryVersion;
+ req->majorVersion = RECORD_MAJOR_VERSION;
+ req->minorVersion = RECORD_MINOR_VERSION;
+ if (!_XReply(dpy,(xReply *)&rep, 0, True)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ *cmajor_return = rep.majorVersion;
+ *cminor_return = rep.minorVersion;
+ return ((rep.majorVersion == RECORD_MAJOR_VERSION) &&
+ (rep.minorVersion >= RECORD_LOWEST_MINOR_VERSION));
+}
+
+XRecordContext
+XRecordCreateContext(Display *dpy, int datum_flags,
+ XRecordClientSpec *clients, int nclients,
+ XRecordRange **ranges, int nranges)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xRecordCreateContextReq *req;
+ int clen = 4 * nclients;
+
+ XRecordCheckExtension (dpy, info, 0);
+ LockDisplay(dpy);
+ GetReq(RecordCreateContext, req);
+
+ req->reqType = info->codes->major_opcode;
+ req->recordReqType = X_RecordCreateContext;
+ req->context = XAllocID(dpy);
+ req->length += (nclients * 4 +
+ nranges * SIZEOF(xRecordRange)) >> 2;
+ req->elementHeader = datum_flags;
+ req->nClients = nclients;
+ req->nRanges = nranges;
+
+ Data32(dpy, (long *)clients, clen);
+ SendRange(dpy, ranges, nranges);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return req->context;
+}
+
+XRecordRange *
+XRecordAllocRange(void)
+{
+ return (XRecordRange*)Xcalloc(1, sizeof(XRecordRange));
+}
+
+Status
+XRecordRegisterClients(Display *dpy, XRecordContext context, int datum_flags,
+ XRecordClientSpec *clients, int nclients,
+ XRecordRange **ranges, int nranges)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xRecordRegisterClientsReq *req;
+ int clen = 4 * nclients;
+
+ XRecordCheckExtension (dpy, info, 0);
+ LockDisplay(dpy);
+ GetReq(RecordRegisterClients, req);
+
+ req->reqType = info->codes->major_opcode;
+ req->recordReqType = X_RecordRegisterClients;
+ req->context = context;
+ req->length += (nclients * 4 +
+ nranges * SIZEOF(xRecordRange)) >> 2;
+ req->elementHeader = datum_flags;
+ req->nClients = nclients;
+ req->nRanges = nranges;
+
+ Data32(dpy, (long *)clients, clen);
+ SendRange(dpy, ranges, nranges);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+Status
+XRecordUnregisterClients(Display *dpy, XRecordContext context,
+ XRecordClientSpec *clients, int nclients)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xRecordUnregisterClientsReq *req;
+ int clen = 4 * nclients;
+
+ XRecordCheckExtension (dpy, info, 0);
+ LockDisplay(dpy);
+ GetReq(RecordUnregisterClients, req);
+
+ req->reqType = info->codes->major_opcode;
+ req->recordReqType = X_RecordUnregisterClients;
+ req->context = context;
+ req->length += nclients;
+ req->nClients = nclients;
+
+ Data32(dpy, (long *)clients, clen);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+static void
+WireToLibRange(
+ xRecordRange *wire_range,
+ XRecordRange *lib_range)
+{
+ lib_range->core_requests.first = wire_range->coreRequestsFirst;
+ lib_range->core_requests.last = wire_range->coreRequestsLast;
+ lib_range->core_replies.first = wire_range->coreRepliesFirst;
+ lib_range->core_replies.last = wire_range->coreRepliesLast;
+ lib_range->ext_requests.ext_major.first = wire_range->extRequestsMajorFirst;
+ lib_range->ext_requests.ext_major.last = wire_range->extRequestsMajorLast;
+ lib_range->ext_requests.ext_minor.first = wire_range->extRequestsMinorFirst;
+ lib_range->ext_requests.ext_minor.last = wire_range->extRequestsMinorLast;
+ lib_range->ext_replies.ext_major.first = wire_range->extRepliesMajorFirst;
+ lib_range->ext_replies.ext_major.last = wire_range->extRepliesMajorLast;
+ lib_range->ext_replies.ext_minor.first = wire_range->extRepliesMinorFirst;
+ lib_range->ext_replies.ext_minor.last = wire_range->extRepliesMinorLast;
+ lib_range->delivered_events.first = wire_range->deliveredEventsFirst;
+ lib_range->delivered_events.last = wire_range->deliveredEventsLast;
+ lib_range->device_events.first = wire_range->deviceEventsFirst;
+ lib_range->device_events.last = wire_range->deviceEventsLast;
+ lib_range->errors.first = wire_range->errorsFirst;
+ lib_range->errors.last = wire_range->errorsLast;
+ lib_range->client_started = wire_range->clientStarted;
+ lib_range->client_died = wire_range->clientDied;
+}
+
+Status
+XRecordGetContext(Display *dpy, XRecordContext context,
+ XRecordState **state_return)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xRecordGetContextReq *req;
+ xRecordGetContextReply rep;
+ int count, i, rn;
+ xRecordRange xrange;
+ XRecordRange *ranges = NULL;
+ xRecordClientInfo xclient_inf;
+ XRecordClientInfo **client_inf, *client_inf_str = NULL;
+ XRecordState *ret;
+
+ XRecordCheckExtension (dpy, info, 0);
+ LockDisplay(dpy);
+ GetReq(RecordGetContext, req);
+ req->reqType = info->codes->major_opcode;
+ req->recordReqType = X_RecordGetContext;
+ req->context = context;
+ if (!_XReply(dpy,(xReply *)&rep, 0, False)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 0;
+ }
+ count = rep.nClients;
+
+ ret = (XRecordState*)Xmalloc(sizeof(XRecordState));
+ if (!ret) {
+ /* XXX - eat data */
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 0;
+ }
+
+ ret->enabled = rep.enabled;
+ ret->datum_flags = rep.elementHeader;
+ ret->nclients = count;
+
+ if (count)
+ {
+ client_inf = (XRecordClientInfo **) Xcalloc(count, sizeof(XRecordClientInfo*));
+ ret->client_info = client_inf;
+ if (client_inf != NULL) {
+ client_inf_str = (XRecordClientInfo *) Xmalloc(count*sizeof(XRecordClientInfo));
+ }
+ if (!client_inf || !client_inf_str)
+ {
+ for(i = 0; i < count; i++)
+ {
+ _XEatData (dpy, sizeof(xRecordClientInfo));
+ _XEatData (dpy, SIZEOF(xRecordRange)); /* XXX - don't know how many */
+ }
+ UnlockDisplay(dpy);
+ XRecordFreeState(ret);
+ SyncHandle();
+ return 0;
+ }
+ for(i = 0; i < count; i++)
+ {
+ client_inf[i] = &(client_inf_str[i]);
+ _XRead(dpy, (char *)&xclient_inf, (long)sizeof(xRecordClientInfo));
+ client_inf_str[i].client = xclient_inf.clientResource;
+ client_inf_str[i].nranges = xclient_inf.nRanges;
+
+ if (xclient_inf.nRanges)
+ {
+ client_inf_str[i].ranges = (XRecordRange**) Xcalloc(xclient_inf.nRanges, sizeof(XRecordRange*));
+ if (client_inf_str[i].ranges != NULL) {
+ ranges = (XRecordRange*)
+ Xmalloc(xclient_inf.nRanges * sizeof(XRecordRange));
+ }
+ if (!client_inf_str[i].ranges || !ranges) {
+ /* XXX eat data */
+ UnlockDisplay(dpy);
+ XRecordFreeState(ret);
+ SyncHandle();
+ return 0;
+ }
+ for (rn=0; rn<xclient_inf.nRanges; rn++) {
+ client_inf_str[i].ranges[rn] = &(ranges[rn]);
+ _XRead(dpy, (char *)&xrange, (long)sizeof(xRecordRange));
+ WireToLibRange(&xrange, &(ranges[rn]));
+ }
+ } else {
+ client_inf_str[i].ranges = NULL;
+ }
+ }
+ } else {
+ ret->client_info = NULL;
+ }
+
+ *state_return = ret;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+void
+XRecordFreeState(XRecordState *state)
+{
+ int i;
+
+ for(i=0; i<state->nclients; i++) {
+ if (state->client_info[i]->ranges) {
+ if (state->client_info[i]->ranges[0])
+ Xfree(state->client_info[i]->ranges[0]);
+ Xfree(state->client_info[i]->ranges);
+ }
+ }
+ if (state->client_info) {
+ if (state->client_info[0])
+ Xfree(state->client_info[0]);
+ Xfree(state->client_info);
+ }
+ Xfree(state);
+}
+
+static struct reply_buffer *alloc_reply_buffer(
+ XExtDisplayInfo *info,
+ int nbytes)
+{
+ struct mem_cache_str *cache = (struct mem_cache_str *)info->data;
+ struct reply_buffer *rbp;
+ struct reply_buffer *saved_rb = NULL;
+ /*
+ * First look for an allocated buffer that is not in use.
+ * If we have a big enough buffer, use that, otherwise
+ * realloc an existing one.
+ */
+ for (rbp = cache->reply_buffers; rbp; rbp = rbp->next) {
+ if (rbp->ref_count == 0) {
+ if (rbp->nbytes >= nbytes)
+ return rbp;
+ else
+ saved_rb = rbp;
+ }
+ }
+ if (saved_rb) {
+ saved_rb->buf = (unsigned char *)Xrealloc(saved_rb->buf, nbytes);
+ if (!saved_rb->buf) {
+ saved_rb->nbytes = 0;
+ return NULL;
+ }
+ saved_rb->nbytes = nbytes;
+ return saved_rb;
+ }
+
+ /*
+ * nothing available; malloc a new struct
+ */
+ rbp = (struct reply_buffer *)Xmalloc(sizeof(struct reply_buffer));
+ if (!rbp)
+ return NULL;
+ rbp->buf = (unsigned char *)Xmalloc(nbytes);
+ if (!rbp->buf) {
+ Xfree(rbp);
+ return NULL;
+ }
+ rbp->nbytes = nbytes;
+ rbp->ref_count = 0;
+ rbp->next = cache->reply_buffers;
+ cache->reply_buffers = rbp;
+ return rbp;
+}
+
+static XRecordInterceptData *alloc_inter_data(XExtDisplayInfo *info)
+{
+ struct mem_cache_str *cache = (struct mem_cache_str *)info->data;
+ struct intercept_queue *iq;
+
+ /* if there is one on the free list, pop it */
+ if (cache->inter_data) {
+ iq = cache->inter_data;
+ cache->inter_data = iq->next;
+ return &iq->data;
+ }
+ /* allocate a new one */
+ iq = (struct intercept_queue *)Xmalloc(sizeof(struct intercept_queue));
+ if (!iq)
+ return NULL;
+ iq->cache = cache;
+ cache->inter_data_count++;
+ return &iq->data;
+}
+
+void
+XRecordFreeData(XRecordInterceptData *data)
+{
+ /* we can do this cast because that is what we really allocated */
+ struct intercept_queue *iq = (struct intercept_queue *)data;
+ struct reply_buffer *rbp = NULL;
+ struct mem_cache_str *cache = iq->cache;
+
+ /*
+ * figure out what reply_buffer this points at
+ * and decrement its ref_count.
+ */
+ if (data->data) {
+
+ for (rbp = cache->reply_buffers; rbp; rbp = rbp->next) {
+ if (data->data >= rbp->buf
+ && data->data < rbp->buf + rbp->nbytes)
+ {
+ assert(rbp->ref_count > 0);
+ rbp->ref_count--;
+ break;
+ }
+ }
+ /* it's an error if we didn't find something to free */
+ assert(rbp);
+ }
+ /*
+ * If the display is still open, put this back on the free queue.
+ *
+ * Otherwise the display is closed and we won't reuse this, so free it.
+ * See if we can free the reply buffer, too.
+ * If we can, see if this is the last reply buffer and if so
+ * free the list of reply buffers.
+ */
+ if (cache->display_closed == False) {
+ iq->next = cache->inter_data;
+ cache->inter_data = iq;
+ } else {
+ if (rbp && rbp->ref_count == 0) {
+ struct reply_buffer *rbp2, **rbp_next_p;
+
+ /* Have to search the list again to find the prev element.
+ This is not the common case, so don't slow down the code
+ above by doing it then. */
+ for (rbp_next_p = &cache->reply_buffers; *rbp_next_p; ) {
+ rbp2 = *rbp_next_p;
+ if (rbp == rbp2) {
+ *rbp_next_p = rbp2->next;
+ break;
+ } else {
+ rbp_next_p = &rbp2->next;
+ }
+ }
+ XFree(rbp->buf);
+ XFree(rbp);
+ }
+
+ XFree(iq);
+ cache->inter_data_count--;
+
+ if (cache->reply_buffers == NULL && cache->inter_data_count == 0) {
+ XFree(cache); /* all finished */
+ }
+ }
+}
+
+/* the EXTRACT macros are adapted from ICElibint.h */
+
+#ifndef WORD64
+
+#define EXTRACT_CARD16(swap, src, dst) \
+{ \
+ (dst) = *((CARD16 *) (src)); \
+ if (swap) \
+ (dst) = lswaps (dst); \
+}
+
+#define EXTRACT_CARD32(swap, src, dst) \
+{ \
+ (dst) = *((CARD32 *) (src)); \
+ if (swap) \
+ (dst) = lswapl (dst); \
+}
+
+#else /* WORD64 */
+
+#define EXTRACT_CARD16(swap, src, dst) \
+{ \
+ (dst) = *((src) + 0); \
+ (dst) <<= 8; \
+ (dst) |= *((src) + 1); \
+ if (swap) \
+ (dst) = lswaps (dst); \
+}
+
+#define EXTRACT_CARD32(swap, src, dst) \
+{ \
+ (dst) = *((src) + 0); \
+ (dst) <<= 8; \
+ (dst) |= *((src) + 1); \
+ (dst) <<= 8; \
+ (dst) |= *((src) + 2); \
+ (dst) <<= 8; \
+ (dst) |= *((src) + 3); \
+ if (swap) \
+ (dst) = lswapl (dst); \
+}
+
+#endif /* WORD64 */
+
+/* byte swapping macros from xfs/include/misc.h */
+
+/* byte swap a long literal */
+#define lswapl(x) ((((x) & 0xff) << 24) |\
+ (((x) & 0xff00) << 8) |\
+ (((x) & 0xff0000) >> 8) |\
+ (((x) >> 24) & 0xff))
+
+/* byte swap a short literal */
+#define lswaps(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
+
+enum parser_return { Continue, End, Error };
+
+static enum parser_return
+parse_reply_call_callback(
+ Display *dpy,
+ XExtDisplayInfo *info,
+ xRecordEnableContextReply *rep,
+ struct reply_buffer *reply,
+ XRecordInterceptProc callback,
+ XPointer closure)
+{
+ int current_index;
+ int datum_bytes = 0;
+ XRecordInterceptData *data;
+
+ /* call the callback for each protocol element in the reply */
+ current_index = 0;
+ do {
+ data = alloc_inter_data(info);
+ if (!data)
+ return Error;
+
+ data->id_base = rep->idBase;
+ data->category = rep->category;
+ data->client_swapped = rep->clientSwapped;
+ data->server_time = rep->serverTime;
+ data->client_seq = rep->recordedSequenceNumber;
+ /*
+ * compute the size of this protocol element.
+ */
+ switch (rep->category) {
+ case XRecordFromServer:
+ if (rep->elementHeader&XRecordFromServerTime) {
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index,
+ data->server_time);
+ current_index += 4;
+ }
+ switch (reply->buf[current_index]) {
+ case X_Reply: /* reply */
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index+4, datum_bytes);
+ datum_bytes = (datum_bytes+8) << 2;
+ break;
+ default: /* error or event */
+ datum_bytes = 32;
+ }
+ break;
+ case XRecordFromClient:
+ if (rep->elementHeader&XRecordFromClientTime) {
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index,
+ data->server_time);
+ current_index += 4;
+ }
+ if (rep->elementHeader&XRecordFromClientSequence) {
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index,
+ data->client_seq);
+ current_index += 4;
+ }
+ if (reply->buf[current_index+2] == 0
+ && reply->buf[current_index+3] == 0) /* needn't swap 0 */
+ { /* BIG-REQUESTS */
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index+4, datum_bytes);
+ } else {
+ EXTRACT_CARD16(rep->clientSwapped,
+ reply->buf+current_index+2, datum_bytes);
+ }
+ datum_bytes <<= 2;
+ break;
+ case XRecordClientStarted:
+ EXTRACT_CARD16(rep->clientSwapped,
+ reply->buf+current_index+6, datum_bytes);
+ datum_bytes = (datum_bytes+2) << 2;
+ break;
+ case XRecordClientDied:
+ if (rep->elementHeader&XRecordFromClientSequence) {
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index,
+ data->client_seq);
+ current_index += 4;
+ }
+ /* fall through */
+ case XRecordStartOfData:
+ case XRecordEndOfData:
+ datum_bytes = 0;
+ }
+
+ if (datum_bytes > 0) {
+ if (current_index + datum_bytes > rep->length << 2)
+ fprintf(stderr,
+ "XRecord: %lu-byte reply claims %d-byte element (seq %lu)\n",
+ (long)rep->length << 2, current_index + datum_bytes,
+ dpy->last_request_read);
+ /*
+ * This assignment (and indeed the whole buffer sharing
+ * scheme) assumes arbitrary 4-byte boundaries are
+ * addressable.
+ */
+ data->data = reply->buf+current_index;
+ reply->ref_count++;
+ } else {
+ data->data = NULL;
+ }
+ data->data_len = datum_bytes >> 2;
+
+ (*callback)(closure, data);
+
+ current_index += datum_bytes;
+ } while (current_index<rep->length<<2);
+
+ if (rep->category == XRecordEndOfData)
+ return End;
+
+ return Continue;
+}
+
+Status
+XRecordEnableContext(Display *dpy, XRecordContext context,
+ XRecordInterceptProc callback, XPointer closure)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xRecordEnableContextReq *req;
+ xRecordEnableContextReply rep;
+ struct reply_buffer *reply;
+ enum parser_return status;
+
+ XRecordCheckExtension (dpy, info, 0);
+ LockDisplay(dpy);
+ GetReq(RecordEnableContext, req);
+
+ req->reqType = info->codes->major_opcode;
+ req->recordReqType = X_RecordEnableContext;
+ req->context = context;
+
+ while (1)
+ {
+ /* This code should match that in XRecordEnableContextAsync */
+ if (!_XReply (dpy, (xReply *)&rep, 0, xFalse))
+ {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 0;
+ }
+
+ if (rep.length > 0) {
+ reply = alloc_reply_buffer(info, rep.length<<2);
+ if (!reply) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 0;
+ }
+ _XRead (dpy, (char *)reply->buf, rep.length<<2);
+ } else {
+ reply = NULL;
+ }
+
+ status = parse_reply_call_callback(dpy, info, &rep, reply,
+ callback, closure);
+ switch (status) {
+ case Continue:
+ break;
+ case End:
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+ case Error:
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 0;
+ }
+ }
+}
+
+
+typedef struct _record_async_state
+{
+ unsigned long enable_seq;
+ _XAsyncHandler *async;
+ _XAsyncErrorState *error_state;
+ XExtDisplayInfo *info;
+ XRecordInterceptProc callback;
+ XPointer closure;
+} record_async_state;
+
+static Bool
+record_async_handler(
+ register Display *dpy,
+ register xReply *rep,
+ char *buf,
+ int len,
+ XPointer adata)
+{
+ register record_async_state *state = (record_async_state *)adata;
+ struct reply_buffer *reply;
+ enum parser_return status;
+
+ if (dpy->last_request_read != state->enable_seq)
+ {
+ if (dpy->last_request_read > state->enable_seq) {
+ /* it is an error that we are still on the handler list */
+ fprintf(stderr, "XRecord: handler for seq %lu never saw XRecordEndOfData. (seq now %lu)\n",
+ state->enable_seq, dpy->last_request_read);
+ DeqAsyncHandler(dpy, state->async);
+ Xfree(state->async);
+ }
+ return False;
+ }
+ if (rep->generic.type == X_Error)
+ {
+ DeqAsyncHandler(dpy, state->async);
+ Xfree(state->async);
+ return False;
+ }
+
+ if (rep->generic.length > 0) {
+ reply = alloc_reply_buffer(state->info, rep->generic.length<<2);
+
+ if (!reply) {
+ DeqAsyncHandler(dpy, state->async);
+ Xfree(state->async);
+ return False;
+ }
+
+ _XGetAsyncData(dpy, (char *)reply->buf, buf, len,
+ SIZEOF(xRecordEnableContextReply),
+ rep->generic.length << 2, 0);
+ } else {
+ reply = NULL;
+ }
+
+ status = parse_reply_call_callback(dpy, state->info,
+ (xRecordEnableContextReply*) rep,
+ reply, state->callback, state->closure);
+
+ if (status != Continue)
+ {
+ DeqAsyncHandler(dpy, state->async);
+ Xfree(state->async);
+ if (status == Error)
+ return False;
+ }
+
+ return True;
+}
+
+/*
+ * reads the first reply, StartOfData, synchronously,
+ * then returns allowing the app to call XRecordProcessReplies
+ * to get the rest.
+ */
+Status
+XRecordEnableContextAsync(Display *dpy, XRecordContext context,
+ XRecordInterceptProc callback, XPointer closure)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xRecordEnableContextReq *req;
+ xRecordEnableContextReply rep;
+ struct reply_buffer *reply;
+ enum parser_return status;
+ _XAsyncHandler *async;
+ record_async_state *async_state;
+
+ XRecordCheckExtension (dpy, info, 0);
+ async = (_XAsyncHandler *)Xmalloc(sizeof(_XAsyncHandler) +
+ sizeof(record_async_state));
+ if (!async)
+ return 0;
+ async_state = (record_async_state *)(async + 1);
+
+ LockDisplay(dpy);
+ GetReq(RecordEnableContext, req);
+
+ req->reqType = info->codes->major_opcode;
+ req->recordReqType = X_RecordEnableContext;
+ req->context = context;
+
+ /* Get the StartOfData reply. */
+ /* This code should match that in XRecordEnableContext */
+ if (!_XReply (dpy, (xReply *)&rep, 0, xFalse))
+ {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ Xfree(async);
+ return 0;
+ }
+
+ /* this had better be a StartOfData, which has no extra data. */
+ if (rep.length != 0) {
+ fprintf(stderr, "XRecord: malformed StartOfData for sequence %lu\n",
+ dpy->last_request_read);
+ }
+ reply = NULL;
+
+ status = parse_reply_call_callback(dpy, info, &rep, reply,
+ callback, closure);
+ if (status != Continue)
+ {
+ UnlockDisplay(dpy);
+ Xfree(async);
+ return 0;
+ }
+
+ /* hook in the async handler for the rest of the replies */
+ async_state->enable_seq = dpy->request;
+ async_state->async = async;
+ async_state->info = info;
+ async_state->callback = callback;
+ async_state->closure = closure;
+
+ async->next = dpy->async_handlers;
+ async->handler = record_async_handler;
+ async->data = (XPointer)async_state;
+ dpy->async_handlers = async;
+
+ UnlockDisplay(dpy);
+ /* Don't invoke SyncHandle here, since this is an async
+ function. Does this break XSetAfterFunction() ? */
+ return 1;
+}
+
+void
+XRecordProcessReplies(Display *dpy)
+{
+ (void) XPending(dpy);
+}
+
+Status
+XRecordDisableContext(Display *dpy, XRecordContext context)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xRecordDisableContextReq *req;
+
+ XRecordCheckExtension (dpy, info, 0);
+ LockDisplay(dpy);
+ GetReq(RecordDisableContext, req);
+ req->reqType = info->codes->major_opcode;
+ req->recordReqType = X_RecordDisableContext;
+ req->context = context;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+Status
+XRecordFreeContext(Display *dpy, XRecordContext context)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xRecordFreeContextReq *req;
+
+ XRecordCheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(RecordFreeContext, req);
+ req->reqType = info->codes->major_opcode;
+ req->recordReqType = X_RecordFreeContext;
+ req->context = context;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
diff --git a/src/XTest.c b/src/XTest.c
new file mode 100644
index 0000000..3e4bb17
--- /dev/null
+++ b/src/XTest.c
@@ -0,0 +1,445 @@
+/*
+Copyright 1990, 1991 by UniSoft Group Limited
+*/
+
+/*
+
+Copyright 1992, 1993, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+#include <X11/Xlibint.h>
+#include <X11/extensions/XTest.h>
+#include <X11/extensions/xtestproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <X11/extensions/XInput.h>
+#include <X11/extensions/XIproto.h>
+
+static XExtensionInfo _xtest_info_data;
+static XExtensionInfo *xtest_info = &_xtest_info_data;
+static const char *xtest_extension_name = XTestExtensionName;
+
+#define XTestCheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, xtest_extension_name, val)
+
+#define XTestICheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, xtest_extension_name, val); \
+ if (!i->data) return val
+
+/*****************************************************************************
+ * *
+ * private utility routines *
+ * *
+ *****************************************************************************/
+
+static int close_display(Display *dpy, XExtCodes *codes);
+static /* const */ XExtensionHooks xtest_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ close_display, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ NULL /* error_string */
+};
+
+static XPointer
+get_xinput_base(Display *dpy)
+{
+ int major_opcode, first_event, first_error;
+ first_event = 0;
+
+ XQueryExtension(dpy, INAME, &major_opcode, &first_event, &first_error);
+ return (XPointer)(long)first_event;
+}
+
+static XEXT_GENERATE_FIND_DISPLAY (find_display, xtest_info,
+ xtest_extension_name,
+ &xtest_extension_hooks, XTestNumberEvents,
+ get_xinput_base(dpy))
+
+static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xtest_info)
+
+/*****************************************************************************
+ * *
+ * public routines *
+ * *
+ *****************************************************************************/
+
+Bool
+XTestQueryExtension (Display *dpy,
+ int *event_base_return, int *error_base_return,
+ int *major_return, int *minor_return)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestGetVersionReq *req;
+ xXTestGetVersionReply rep;
+
+ if (XextHasExtension(info)) {
+ LockDisplay(dpy);
+ GetReq(XTestGetVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestGetVersion;
+ req->majorVersion = XTestMajorVersion;
+ req->minorVersion = XTestMinorVersion;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ *event_base_return = info->codes->first_event;
+ *error_base_return = info->codes->first_error;
+ *major_return = rep.majorVersion;
+ *minor_return = rep.minorVersion;
+ return True;
+ } else {
+ return False;
+ }
+}
+
+Bool
+XTestCompareCursorWithWindow(Display *dpy, Window window, Cursor cursor)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestCompareCursorReq *req;
+ xXTestCompareCursorReply rep;
+
+ XTestCheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XTestCompareCursor, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestCompareCursor;
+ req->window = window;
+ req->cursor = cursor;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return rep.same;
+}
+
+Bool
+XTestCompareCurrentCursorWithWindow(Display *dpy, Window window)
+{
+ return XTestCompareCursorWithWindow(dpy, window, XTestCurrentCursor);
+}
+
+int
+XTestFakeKeyEvent(Display *dpy, unsigned int keycode,
+ Bool is_press, unsigned long delay)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestFakeInputReq *req;
+
+ XTestCheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XTestFakeInput, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestFakeInput;
+ req->type = is_press ? KeyPress : KeyRelease;
+ req->detail = keycode;
+ req->time = delay;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+int
+XTestFakeButtonEvent(Display *dpy, unsigned int button,
+ Bool is_press, unsigned long delay)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestFakeInputReq *req;
+
+ XTestCheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XTestFakeInput, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestFakeInput;
+ req->type = is_press ? ButtonPress : ButtonRelease;
+ req->detail = button;
+ req->time = delay;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+int
+XTestFakeMotionEvent(Display *dpy, int screen, int x, int y, unsigned long delay)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestFakeInputReq *req;
+
+ XTestCheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XTestFakeInput, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestFakeInput;
+ req->type = MotionNotify;
+ req->detail = False;
+ if (screen == -1)
+ req->root = None;
+ else
+ req->root = RootWindow(dpy, screen);
+ req->rootX = x;
+ req->rootY = y;
+ req->time = delay;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+int
+XTestFakeRelativeMotionEvent(Display *dpy, int dx, int dy, unsigned long delay)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestFakeInputReq *req;
+
+ XTestCheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XTestFakeInput, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestFakeInput;
+ req->type = MotionNotify;
+ req->detail = True;
+ req->root = None;
+ req->rootX = dx;
+ req->rootY = dy;
+ req->time = delay;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+static void
+send_axes(
+ Display *dpy,
+ XExtDisplayInfo *info,
+ xXTestFakeInputReq *req,
+ XDevice *dev,
+ int first_axis,
+ int *axes,
+ int n_axes)
+{
+ deviceValuator ev;
+ int n;
+
+ req->deviceid |= MORE_EVENTS;
+ req->length += ((n_axes + 5) / 6) * (SIZEOF(xEvent) >> 2);
+ ev.type = XI_DeviceValuator + (long)info->data;
+ ev.deviceid = dev->device_id;
+ ev.first_valuator = first_axis;
+ while (n_axes > 0) {
+ n = n_axes > 6 ? 6 : n_axes;
+ ev.num_valuators = n;
+ switch (n) {
+ case 6:
+ ev.valuator5 = *(axes+5);
+ case 5:
+ ev.valuator4 = *(axes+4);
+ case 4:
+ ev.valuator3 = *(axes+3);
+ case 3:
+ ev.valuator2 = *(axes+2);
+ case 2:
+ ev.valuator1 = *(axes+1);
+ case 1:
+ ev.valuator0 = *axes;
+ }
+ Data(dpy, (char *)&ev, SIZEOF(xEvent));
+ axes += n;
+ n_axes -= n;
+ ev.first_valuator += n;
+ }
+}
+
+int
+XTestFakeDeviceKeyEvent(Display *dpy, XDevice *dev,
+ unsigned int keycode, Bool is_press,
+ int *axes, int n_axes, unsigned long delay)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestFakeInputReq *req;
+
+ XTestICheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XTestFakeInput, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestFakeInput;
+ req->type = is_press ? XI_DeviceKeyPress : XI_DeviceKeyRelease;
+ req->type += (int)(long)info->data;
+ req->detail = keycode;
+ req->time = delay;
+ req->deviceid = dev->device_id;
+ if (n_axes)
+ send_axes(dpy, info, req, dev, 0, axes, n_axes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+int
+XTestFakeDeviceButtonEvent(Display *dpy, XDevice *dev,
+ unsigned int button, Bool is_press,
+ int *axes, int n_axes, unsigned long delay)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestFakeInputReq *req;
+
+ XTestICheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XTestFakeInput, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestFakeInput;
+ req->type = is_press ? XI_DeviceButtonPress : XI_DeviceButtonRelease;
+ req->type += (int)(long)info->data;
+ req->detail = button;
+ req->time = delay;
+ req->deviceid = dev->device_id;
+ if (n_axes)
+ send_axes(dpy, info, req, dev, 0, axes, n_axes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+int
+XTestFakeProximityEvent(Display *dpy, XDevice *dev, Bool in_prox,
+ int *axes, int n_axes, unsigned long delay)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestFakeInputReq *req;
+
+ XTestICheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XTestFakeInput, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestFakeInput;
+ req->type = in_prox ? XI_ProximityIn : XI_ProximityOut;
+ req->type += (int)(long)info->data;
+ req->time = delay;
+ req->deviceid = dev->device_id;
+ if (n_axes)
+ send_axes(dpy, info, req, dev, 0, axes, n_axes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+int
+XTestFakeDeviceMotionEvent(Display *dpy, XDevice *dev,
+ Bool is_relative, int first_axis,
+ int *axes, int n_axes, unsigned long delay)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestFakeInputReq *req;
+
+ XTestICheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XTestFakeInput, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestFakeInput;
+ req->type = XI_DeviceMotionNotify + (int)(long)info->data;
+ req->detail = is_relative;
+ req->time = delay;
+ req->deviceid = dev->device_id;
+ send_axes(dpy, info, req, dev, first_axis, axes, n_axes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+int
+XTestGrabControl(Display *dpy, Bool impervious)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ register xXTestGrabControlReq *req;
+
+ XTestCheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XTestGrabControl, req);
+ req->reqType = info->codes->major_opcode;
+ req->xtReqType = X_XTestGrabControl;
+ req->impervious = impervious;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 1;
+}
+
+void
+XTestSetGContextOfGC(GC gc, GContext gid)
+{
+ gc->gid = gid;
+}
+
+void
+XTestSetVisualIDOfVisual(Visual *visual, VisualID visualid)
+{
+ visual->visualid = visualid;
+}
+
+static xReq _dummy_request = {
+ 0, 0, 0
+};
+
+Status
+XTestDiscard(Display *dpy)
+{
+ Bool something;
+ register char *ptr;
+
+ LockDisplay(dpy);
+ if ((something = (dpy->bufptr != dpy->buffer))) {
+ for (ptr = dpy->buffer;
+ ptr < dpy->bufptr;
+ ptr += (((xReq *)ptr)->length << 2))
+ dpy->request--;
+ dpy->bufptr = dpy->buffer;
+ dpy->last_req = (char *)&_dummy_request;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return something;
+}
diff --git a/xtst.pc.in b/xtst.pc.in
new file mode 100644
index 0000000..8702044
--- /dev/null
+++ b/xtst.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Xtst
+Description: The Xtst Library
+Version: @PACKAGE_VERSION@
+Requires: recordproto
+Requires.private: x11 xext
+Cflags: -I${includedir}
+Libs: -L${libdir} -lXtst