upload tizen2.0 source 2.0alpha master 2.0_alpha submit/master/20120920.151145
authorBoram Park <boram1288.park@samsung.com>
Tue, 21 Aug 2012 09:03:49 +0000 (18:03 +0900)
committerBoram Park <boram1288.park@samsung.com>
Tue, 21 Aug 2012 09:03:49 +0000 (18:03 +0900)
14 files changed:
ChangeLog [changed mode: 0755->0644]
INSTALL [new file with mode: 0644]
Makefile.am [changed mode: 0755->0644]
XI2.h
XI2proto.h
XI2proto.txt [deleted file]
XIproto.txt [deleted file]
autogen.sh [changed mode: 0644->0755]
configure.ac [changed mode: 0755->0644]
packaging/xorg-x11-proto-input.spec [new file with mode: 0644]
packaging/xorg-x11-proto-inputproto.spec [deleted file]
specs/Makefile.am [new file with mode: 0644]
specs/XI2proto.txt [new file with mode: 0644]
specs/XIproto.txt [new file with mode: 0644]

old mode 100755 (executable)
new mode 100644 (file)
index f79c065..de735ff
--- a/ChangeLog
+++ b/ChangeLog
+commit e752e92dbdcf01b1cd46a3853f582ff765d19e90
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 12:58:18 2012 +1000
+
+    inputproto 2.2
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit b02b0b42e266560bd48f7e8f38c8338417394fd0
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Feb 29 15:08:01 2012 +1000
+
+    specs: XI 2.2 release date is March 2012
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 950a7a0b2e733d9713a88612b669603b0c155329
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Feb 29 14:55:26 2012 +1000
+
+    specs: Remove work in progress warning
+    
+    We're close enough to a release now.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 3ac053f2c7ef8d07b4a6dcb64d8ca47edad15716
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 10:31:26 2012 +1000
+
+    specs: remove "since" from TouchOwnershipEvent
+    
+    It's already in a section "Events introduced in version 2.2"
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit b42e4d24a26fb8467ed54183480c9dacd66fc804
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 10:28:46 2012 +1000
+
+    specs: remove TouchOwnership mention from DeviceEvent
+    
+    TouchOwnership is described separately below.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit a09ca92ce31ede86b883cb74fb1767f8ed687ca5
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 10:26:04 2012 +1000
+
+    specs: whitespace fix to avoid wrong asciidoc formatting
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit b1458f6fa9952365f4ad86dc87b385d467318fb1
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 10:25:03 2012 +1000
+
+    specs: fix link to touch ownership section
+    
+    Introduced in 535a4377ddb4c2680d54b4cbbb273134bb5f58a3
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit b321ea46fbb251970c2d655b73209750f24c0b8e
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 10:21:12 2012 +1000
+
+    specs: GrabtypeTouchBegin was added in XI 2.2
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 3773e33579f0b5bd6de9f01481b8608fa3101a2b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 10:19:42 2012 +1000
+
+    specs: formatting fix, move AcceptTouch and RejectTouch onto their own line
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 4de6f26a705062343f5b93dd9827a736c721e265
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 10:08:33 2012 +1000
+
+    specs: replace † with ²
+    
+    † looks too much like a letter and we can't use * and ** because asciidoc
+    interprets it as lists.
+    
+    Use numbers instead, and replace all current * with ¹.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 000a20296a3c52f4232aa466d29faa2e424ca626
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 10:07:21 2012 +1000
+
+    specs: XITouchClass doesn't have properties
+    
+    Leftover from an earlier version.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 0d7bfc10bffa29de1b7217d6399e8f0d5b24c579
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 09:55:21 2012 +1000
+
+    specs: Formatting fix
+    
+    asciidoc requires caption to be on one line but this one here is too long.
+    Split it up instead.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 883143e3454c7fe44b12b11fc12ff3ec2267ecd1
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 2 09:32:18 2012 +1000
+
+    specs: some wording fixes
+    
+    Button press events are insufficient even on scroll wheels, so don't say
+    they are good enough.
+    
+    Remove duplicate claim of event emulation
+    
+    Don't claim we send touch events "without delay"
+    
+    Touch screens hardly ever "physically move" an object.
+    
+    Hyphenate "implementation-dependent"
+    
+    Remove unnecessary "however"
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 9a2e10213c996010124a3d58e71140f41202416c
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Feb 29 14:56:37 2012 +1000
+
+    specs: fix typos 'hierachy' → 'hierarchy'
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 5e18f74e24a17d6a1f18339600a00f5591dc6a82
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Feb 8 03:17:28 2012 +1000
+
+    Unbreak protocol ABI for XIAllowEvents - inputproto 2.1.99.6
+    
+    XIAllowEvents was extended with touchid and grab_window in
+    2ea2f99f4fe1dcd3b8e539ca41c482fc40a0533d. This extended the size of
+    the request from 12 to 20 but also broke the ABI. Older server
+    match the request size exactly, so compiling libXi 1.5 against
+    inputproto 2.2 and then running it against a pre-XI 2.2 server causes a
+    BadLength for any XIAllowEvent request.
+    
+    Add a new request for the new data.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Keith Packard <keithp@keithp.com>
+
+commit 217afacda01b082f39fb6816e62ec20e4791857f
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Thu Jan 26 13:56:38 2012 +1000
+
+    specs: explain touch behaviour for dependent devices
+    
+    Dependent devices don't send touch events until the interaction is a true
+    touch interaction (i.e. doesn't just serve to move the pointer). Once that
+    happens, all touchpoints send touch events exclusively. Pointer movement
+    restarts once we're down to one touch that controls the pointer again.
+    
+    For clients listening to touch events in addition to pointer events, this
+    also means that a two-finger tap looks identical to holding one finger down
+    and tapping with a second-finger. Both actions will result in short
+    TouchBegin/TouchEnd sequences for both fingers.
+    
+    The above is the default behaviour we expect from touchpads, the protocol is
+    more generically worded to leave more room for drivers to decide when a
+    touch only controls the pointer and when it doesn't.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit fc9372868bb772f38a6b17299ef26e3dc9c2ff87
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Thu Jan 26 13:36:24 2012 +1000
+
+    specs: move touch support details to "Touch device support" section
+    
+    Keep the changelog small.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 92f769675b0e39c51280db9690db4b3d80637069
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Thu Jan 26 13:33:40 2012 +1000
+
+    specs: remove superfluous "Changes introduced by ..."
+    
+    The line right above says the same thing.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 556ea96060071ab807ece4f77304208e15f25f9b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Thu Jan 26 13:32:33 2012 +1000
+
+    specs: move touch mode explanations to where it belongs
+    
+    Rather than have two different explanations to the touch modes, remove it
+    from the "Changes in version 2.2" section and merge the content into the
+    text.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 535a4377ddb4c2680d54b4cbbb273134bb5f58a3
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Jan 25 17:03:15 2012 -0500
+
+    specs: replace hard coded number in some "See section" references
+    
+    The glossary does not accept <<links>> however.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit f3d2feead483f6637ef8ff004afad55b5bbf2c62
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Jan 25 17:03:13 2012 -0500
+
+    specs: fix Appendix A title
+    
+    This section starts a new numbered sequence.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 9ff28b092f91ea1d7ff58f54a9404347f517361b
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Jan 25 17:03:12 2012 -0500
+
+    specs: remove older manually typed in section number
+    
+    These would come out in html as 5.2, 6.3 and 6.4.3.4
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 508a360f6530e75d94cd2999e56cb329b315ce5d
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Jan 25 17:03:14 2012 -0500
+
+    specs: use subsections to group use cases description
+    
+    It makes an entry in the appendix for quick navigation.
+    It looks more readable with subtitles.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 08ba2d4e1094fb196d1b7a7b3a3b27a81cb9834c
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Jan 25 17:03:11 2012 -0500
+
+    specs: Edit titles for section 3 and 4
+    
+    In the htlm version, the section number appeared to be 3.2.1 and
+    4.2.2 because of the generated section number.
+    
+    A section title should not begin with a number.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 1306ccf9f262c0c699bec093ffdc4b6695601599
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Jan 6 13:35:25 2012 +1000
+
+    inputproto 2.1.99.5
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 997ae0343730c66d581fd147741cbe27fbe55af2
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Tue Jan 3 09:26:22 2012 +1000
+
+    Set a flag on the pointer-emulating touch event
+    
+    Toolkits need to know which touch event emulated a pointer event and which
+    ones do not. To quote Carlos Garnacho:
+    
+        GTK+ does client-side windows by default (GdkWindows without a backing X
+        window), for this to work the toplevel window in the client needs to
+        select for more events that it wouldn't normally select for in order to
+        cater for the event masks in such child "windows". This means that
+        ideally GTK+ should set the touch events mask in the toplevel, and then
+        find out whether the "window" would receive pointer or touch events for
+        the sequence emulating the pointer, and perform the emulation itself.
+    
+    Reported-by: Carlos Garnacho <carlosg@gnome.org>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 5ee845c1bf457159a034111c3d0df584aa600cd6
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Tue Jan 3 09:24:38 2012 +1000
+
+    specs: purge leftover TouchAccepted note
+    
+    This flag does not exist anymore.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit e65ba758c2d4147c3873c63c262db36ec23bba63
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Tue Jan 3 09:23:23 2012 +1000
+
+    specs: only pointer events have a PointerEmulated flag
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 9611be0a5bc7f4d583d49d51a0e98d3b9b75fc7a
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Dec 23 18:03:09 2011 +1000
+
+    specs: Clarify rejection for touch events on current owner
+    
+    The current owner never gets a TouchUpdate(PendingEnd), that event is
+    superfluous for the owner. The owner receives a TouchEnd when the touch
+    physically ends. If the touch is still active, the owner receives a
+    TouchEnd after rejecting the touch.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit b9f1b26f076cdba373e8b7a0b73384b35e8d799c
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Dec 21 15:30:22 2011 +1000
+
+    inputproto 2.1.99.4
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit b4da32ed2856fef3e8135f03c9194f9dd0287f66
+Merge: 8640944 c508e93
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Dec 21 15:28:44 2011 +1000
+
+    Merge branch 'multitouch-devel'
+    
+    Conflicts:
+       configure.ac
+       specs/XI2proto.txt
+
+commit c508e9360414f9724cc875a4731a5fd8a3969d2b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Dec 21 15:27:47 2011 +1000
+
+    specs: add XI 2.1 release to history section
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 5c9a6569e5182a4c4c6ec052bcd76a9ca3b8f645
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Dec 21 15:24:44 2011 +1000
+
+    Remove --enable-unstable-protocol configure option
+    
+    Protocol is reasonably stable and about to be merged onto the master
+    branch. People should be used to stuff on master being a tad unstable, don't
+    require any specific configure flags.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit aef700dbac09d3c8a576387be47e5693460f1393
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Dec 21 15:23:23 2011 +1000
+
+    specs: remove parts of the "Work in progress" warning
+    
+    The protocol is stable enough now that a simple warning should be enough.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 9a9746b95f3585bba9730105769e9c74520f6bc4
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Tue Dec 20 08:23:55 2011 +1000
+
+    Reinstate libXi's version defines
+    
+    Realistically, we can't remove these from the protocol without breaking
+    older libraries.
+    
+    Introduced in a02566ca7fd37d279b957037e1251a3b3419866d
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit ee0bc61ee3fd775127f8cd222d83314f66255f2b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Tue Dec 20 08:22:52 2011 +1000
+
+    Drop wrong comment for sourceid in TouchOwnershipEvents
+    
+    Copy/paste error from DeviceChangedEvent
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 8640944f4ff193027ce0f21622918b88da910e72
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Dec 16 11:06:13 2011 +1000
+
+    inputproto 2.1
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit b701750ee99e1e227ad8baa994b6fd3398949a3a
+Author: Cyril Brulebois <kibi@debian.org>
+Date:   Thu Dec 15 17:07:54 2011 +0100
+
+    specs: Fix tiny typo.
+    
+    Signed-off-by: Cyril Brulebois <kibi@debian.org>
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 8687f155d8072763c2c7d52cb48eb5f46bfaf705
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Dec 14 08:56:59 2011 +1000
+
+    specs: clarify button state in touch events
+    
+    Emulated pointer events will have button 1 logically down, but touch events
+    only represent the actual button state, irrespective of the touches.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit b1d71fe4cd3871a78e442159443c141193e79a7f
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Dec 14 08:56:09 2011 +1000
+
+    specs: drop leftover from active_touches removal
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 02eadf00f07abb9b0f19a05728b70e42eac08adb
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Dec 13 10:35:18 2011 -0800
+
+    inputproto 2.1.99.3
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 84c049b6603e370afcd267ce4c53a566f842fd69
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Mon Dec 12 10:50:58 2011 -0800
+
+    State that future touch IDs are indeterminate
+    
+    This just makes it absolutely clear that clients should not make any
+    assumptions about future touch ID values.
+    
+    I also added "strictly monotonically" increasing to the definition of
+    touch IDs. It's a more precise definition of the protocol.
+    
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 7d20c9bf38d3d47adc7fb1a70faa370dda1a390c
+Author: Chase Douglas <cndougla@cndougla.(none)>
+Date:   Fri Dec 9 13:32:35 2011 -0800
+
+    Touch IDs must be globally unique
+    
+    XIAllowEvents with a master device and a touch ID must uniquely identify
+    a touch sequence. If touch IDs were unique per slave device, multiple
+    slave devices could have valid sequences with the same touch ID, and the
+    sequences may both be grabbed through the same master device grab.
+    
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit c4703fd9d97c962d5c599a7f826a9a11fc91ee70
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Mon Dec 12 10:26:20 2011 +1000
+
+    Remove XI2.1 and XI2.2 warnings and errors
+    
+    This is too much of a pain, anyone who includes XI headers needs to define
+    this. And that affects input and output drivers as well as legacy clients
+    that don't even need the new stuff.
+    
+    Removing the need for defines would be enough but then the warnings clog up
+    the output and hide real warnings. Just ditch them and laugh at those that
+    use an experimental branch and expect it to work.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 019a252a59c1d076b07a0162cb3ee6af42ceea14
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Dec 2 15:03:46 2011 +1000
+
+    specs: typo fix
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit a9fcea66eb18fab330f3b27b3daedef2b5c9210a
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Nov 11 14:33:34 2011 +1000
+
+    specs: smooth scrolling was added in 2.1, say so
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit c9c4e13e8a3eb90b45c5ef65f729089b7f742e6a
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Nov 11 14:22:08 2011 +1000
+
+    inputproto 2.1.99.2
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 279524b089c7b42871ee072cfc03a1fad7421b7b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Tue Nov 8 15:36:02 2011 +1000
+
+    specs: scroll events have no specific event type, state so.
+    
+    This wasn't clear enough in the current spec.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 9f2b1a33063b139756e08951affe802e8af39a76
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Tue Nov 8 15:29:24 2011 +1000
+
+    specs: We're up to version 2.1 now, say so
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit b289b1c039e36a9440c238ff09dfa3eb67e141e4
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Thu Oct 20 15:55:54 2011 +1000
+
+    XI2: Use touchid, not touch_id in XIAllowEvents
+    
+    Be consistent with other usages of touchid.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 86ce2d05e86852d52f5b135ad03288e4cb16d5df
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Thu Nov 3 09:30:20 2011 +1000
+
+    XI2: swap (Raw)TouchUpdate and (Raw)TouchEnd
+    
+    Not having the event codes in the order begin/update/end does my head in
+    when debugging. It also means there's no symmetry between raw and normal
+    touch events as the ownership event is wedged in between.
+    Rearrange event codes to be Begin/Update/End for both, with the
+    OwnershipEvent being in between.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 463ffaabab506ad6ddb3b55c5781ae91fcccfd04
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Sep 23 08:41:18 2011 +1000
+
+    specs: clarify that Preferred scroll valuators are per scroll direction
+    
+    Reported-by: Daniel Stone <daniel@fooishbar.org>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit cec7567863c3d363b6b75c707540cfe524f849ba
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Wed Sep 14 22:09:28 2011 -0500
+
+    Revert addition of active_touches to device events
+    
+    I can't remember why it's there, and I don't see how it may be useful.
+    If a client really wants to know how many touches are on the device,
+    they can listen to raw events and count the number of active touches.
+    
+    (Real reason: extending events is hard :)
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 22c06a5ddb1d3be2743a79b78eff3844f457dc5e
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Wed Sep 14 20:15:49 2011 -0500
+
+    Fix Xi 2.x version comment in XI2.h
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 88410aa51d03dbb5599e979998137ba6558ff677
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Sep 13 16:59:54 2011 -0500
+
+    inputproto 2.1.99.1 (first snapshot of 2.2)
+    
+    Note that this is built on top of 2.0.99.1, which is a development
+    snapshot of 2.1.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit fa16231f0e5244cdcf77e262647525716f507bdd
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Wed Sep 14 10:10:14 2011 -0500
+
+    Allow grabbing clients to accept or reject touches any time
+    
+    This is potentially both a performance and client complexity
+    improvement. An example is a gesture recognizer using touch grabs on
+    each window with a subscription. If events on a child window are known
+    to not match any subscription on the child window, then the client
+    should be able to reject the touch grab even if the parent window hasn't
+    accepted any of the touches, perhaps because the parent window
+    gesture hasn't timed out or crossed other thresholds yet.
+    
+    As an inverse example, the events may match a child window subscription
+    before the root window has rejected ownership. The child window should
+    be able to accept the touch proactively. This allows for further clients
+    to receive a TouchEnd event earlier, and means the client may be able to
+    reduce state being tracked. If this were not allowed, the client would
+    need to wait until it received ownership before accepting the sequence.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 2ea2f99f4fe1dcd3b8e539ca41c482fc40a0533d
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Wed Sep 14 09:46:18 2011 -0500
+
+    Extend XIAllowEvents for handling touch grab processing
+    
+    This removes the XIAllowTouchEvents request, which was the only new
+    request added for multitouch.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 3c400af4f98740debd7916ad711cf91124a0f994
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Sep 13 15:47:15 2011 -0500
+
+    Add event windows to ownership events
+    
+    Also, match device event structure to make things easy.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit dd9e4bc5f5f2e0eb87b08199ce417849070249ab
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Sep 13 15:30:34 2011 -0500
+
+    Really kill touch valuators
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 05fc509fdca8d8b414a20f1359b9cb80caf5240a
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Sep 14 05:46:43 2011 +1000
+
+    specs: if a sequence ends, all clients get TouchPendingEnd
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 94fecdf129d8ab5bece049a26eed03d24affb549
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Sep 14 05:26:54 2011 +1000
+
+    specs: remove broken asciidoc link to XIAllowTouchEvents
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 4782a76b6e679493f130a53afe158a13628fa504
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Sep 14 05:25:15 2011 +1000
+
+    specs: remove comment about overlapping selections, not true
+    
+    There are no overlapping selections for touch events.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit dd32802d2e6134cf9c4efd49c56c118ed02e6a2b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Sep 14 05:21:31 2011 +1000
+
+    specs: misc typos, rewording, etc.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit cfa06b98d50d6892e5961e86f6223b6b096d9ef4
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Sep 13 15:09:57 2011 -0500
+
+    Bump version to 2.1.99 for XI 2.2 multitouch changes
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 24e7dac91fb919c1668736f6e4309ae522a96d86
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Sep 13 14:27:13 2011 -0500
+
+    Switch multitouch additions to XI 2.2
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit b95adf9b14ff5ba2142e8521f02728dc6d903409
+Merge: d6dcfd4 9cfdeed
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Sep 13 14:20:31 2011 -0500
+
+    Merge remote-tracking branch 'inputproto/master' into multitouch-devel
+    
+    Conflicts:
+       XI2.h
+       XI2proto.h
+       specs/XI2proto.txt
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit d6dcfd4039ede37e9c858ab6e890fdb9582a5a9d
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Mon Sep 12 16:01:53 2011 -0500
+
+    Revert "Specify dependent device pointer/touch handling"
+    
+    See parent commit for details.
+    
+    This reverts commit 4adfb5ad6c064981e2c7eb57db4bdd81cc7029ea.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 42284fa0a233240d365ff2b49cc34c257e2d2bee
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Mon Sep 12 15:55:28 2011 -0500
+
+    Revert "Fix touch cancel/resume semantics"
+    
+    The main use case for this was drag and drop, which we realized does not
+    need any special handling that requires canceling touches.
+    
+    This reverts commit 9e46820e4a206ae48b3e87f6ef7506e583fa3793.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 1b40cc4ff63ebbf0a4b17507762b17fa1e91bea9
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Mon Aug 29 09:20:32 2011 +1000
+
+    specs: extend XI2.1 raw events to include touch events
+    
+    RawEvents are simple enough that we can re-use the detail field for the
+    touch ID tracking and just update the respective event types.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit b55d236a66a614b2192da6d8a7ed4b7d831976f5
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Mon Aug 29 09:20:31 2011 +1000
+
+    Add comment to XI2.h to mark where the 2.1 events start
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 3d23bf3782c9962b70dfa46ea34c86efee57eeb2
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Mon Aug 29 09:20:30 2011 +1000
+
+    Change file header to note version 2.x
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 63f3097d264f790419ce59744e8d2733f9bb1026
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Mon Aug 29 09:20:29 2011 +1000
+
+    specs: Fix event lists for asciidoc parsing
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 4329d45d49741aad0e93f8e064042ba83e6a23a0
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Mon Aug 29 09:20:28 2011 +1000
+
+    specs: Fix in-document references
+    
+    The primary format for the specs is still the txt format (since that's
+    guaranteed to be available anywhere, including cgit). Having in-paragraph
+    references breaks the flow of reading. Fix up some references that aren't
+    strictly necessary anyway, reword some to be easier to read and change the
+    titles of some to match the actual title of the section.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 9cfdeedd16e96c0e67e70537e97a8f8dd0358244
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Thu Jun 2 16:09:23 2011 +1000
+
+    inputproto 2.0.99.1 (first snapshot of 2.1)
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com>
+    Reviewed-by: Daniel Stone <daniel@fooishbar.org>
+
+commit 7d5a303cd8976a7eac1b96897c70d5d25c57ecf1
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Mon Aug 15 12:33:04 2011 +1000
+
+    Move scroll information into a new class.
+    
+    Using labels only to mark smooth scrolling axes disallows scrolling from
+    hardware events (e.g. a mouse wheel). If those axes are marked as scrolling
+    axes instead, the clients lose information which hardware axis this event
+    corresponds to.
+    
+    For example, on Wacom devices, the client can benefit from smooth scrolling
+    on the strip or wheel event but may still require the knowledge whether the
+    axis is a vertical strip (e.g. Intuos3) or a absolute scrolling wheel (e.g.
+    Intuos4).
+    
+    Thus, add a new class to XIQueryDevice that represents scrolling information
+    on a valuator. One of these ScrollClass may exist for each ValuatorClass if
+    that valuator is a scrolling valuator. The increment field of this class
+    removes the requirement for 1.0 == 1 unit of scrolling.
+    
+    This isn't true in most cases, especially where physical scroll axes are
+    involved. Wacom Intuos4 scroll rings have a unit size of 3.0 and the driver
+    historically sent one scroll event per 3.0 increment or decrement. Mapping
+    one scroll event to 1.0 makes the ring mostly unusable through legacy
+    button events.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 186aa20619d1720bde49fd92d2834c8f9eadf49b
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Wed Feb 23 17:37:29 2011 +0000
+
+    Document smooth-scrolling support
+    
+    Two new axes are added to support smooth scrolling: Rel Vert Scroll and
+    Rel Horiz Scroll.  Cumulative values of 1.0 with either magnitude on
+    these axes are considered to be equivalent to one legacy ButtonPress
+    event on the scroll buttons.
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 53b58e679f977550301130794c8cb19391ecceb7
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Tue Feb 15 14:27:53 2011 +0000
+
+    Add XIPointerEmulated for emulated events
+    
+    The XIPointerEmulated flag on pointer events means that the event was
+    emulated from a smooth-scroll or touch event to support legacy events,
+    and the client may ignore this if it is listening to the other events.
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit af1fb609beece899188469a81ac9d8c5e07bfa4a
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Jul 29 10:09:02 2011 +1000
+
+    Add sourceid to RawEvents (#34420)
+    
+    RawEvents in XI2 do not provide the source ID. The libXi headers however do
+    and it is currently always 0. Given that the sourceid may be useful for
+    some clients, send it down the wire.
+    
+    This has no effect on the wire size of the struct, we can re-use a pad byte
+    here.
+    
+    X.Org Bug 34420 <http://bugs.freedesktop.org/show_bug.cgi?id=34420>
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Daniel Stone <daniel@fooishbar.org>
+
+commit 1e63d01d041108db6fe5be32d033e80419a6ab05
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Tue Apr 12 13:07:53 2011 +1000
+
+    XI2.1: send RawEvents at all times.
+    
+    When a client grabbed a device, XI 2.0 only sends RawEvents to that client.
+    This behaviour is problematic and cannot be worked around for many
+    applications that need to continue receiving events.
+    
+    On the other hand, no client seems to rely on this behaviour or use it to
+    its advantage. For XI 2.1, disable this behaviour and continue to send raw
+    events regardless of the grab state of the device.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Acked-by: Chase Douglas <chase.douglas@canonical.com>
+    Reviewed-by: Daniel Stone <daniel@fooishbar.org>
+    Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com>
+
+commit b35f20b7bd9620710a7a6b63e39758fe83b4dec8
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Apr 8 13:26:27 2011 +1000
+
+    Announce 2.1 availability through the XI_2_Major and XI_2_Minor defines
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 47a2cc250398648732ba2086ca6ecb21e7dabdc0
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Apr 8 12:59:17 2011 +1000
+
+    Bump to 2.0.99
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 9e46820e4a206ae48b3e87f6ef7506e583fa3793
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Wed Aug 24 15:10:21 2011 -0700
+
+    Fix touch cancel/resume semantics
+    
+    If a touch is ended through a cancel, the client may never know if the
+    touch will come back as a resumed sequence. Instead, send a touch update
+    with the cancel flag, like the pending end flag, and send an end event
+    only when the full touch sequence has ended.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 79c22a2e7b3c2bf73cd8af7eba7182198f13d2e4
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Wed Aug 24 13:34:47 2011 -0700
+
+    Fix indentation of active_touches definition
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit cec253561ab3feaa0a5a57fa8aa47db15662cf3d
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Wed Aug 24 13:32:30 2011 -0700
+
+    Introduce Touch grab mode
+    
+    Touch grabs are not really synchronous nor asynchronous. Use a separate
+    grab mode value for touch grabs, just to make the protocol seem more
+    sane.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 1cb00433583341b3c52c8d3f62dcd19a55ddca29
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:23 2011 +1000
+
+    DeviceEvents: a TouchPendingEnd won't generate further TouchUpdate events
+    
+    Update, not motion.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit b025106fe8d8aa3043abd48ba3f50bde29527939
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:22 2011 +1000
+
+    DeviceEvent: active_touches needs marker that it's XI 2.1
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit f469fa99ae9ffda806c3e935bbebc73d633f8c10
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:21 2011 +1000
+
+    AllowTouchEvents can take any device id, not just slaves
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit d7fd289ee02d7ebc4cac5357edaaac1b55a7d10c
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:19 2011 +1000
+
+    Indent Ownership explanation for consistent formatting
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit e51dd1b6bd4aa506231a41cbb400a8ece5a6aeaa
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:18 2011 +1000
+
+    Reword the passive touch grab rules to be similar to the others
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 67e06b8f14ac39c6c38e851b94b879024ff806a9
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:17 2011 +1000
+
+    Fix missing 'and' in GrabTypeFocusIn description
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 5b8a8bd0b4e779b947093f9722a2af2568c27118
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:16 2011 +1000
+
+    XISelectEvents: BadValue is generated, not returned
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit ae6ba6b37e47134914b8fedb6524372f0a8119c0
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:15 2011 +1000
+
+    Coordinates are always absolute, no need to re-state it
+    
+    Coordinates in DeviceEvents are always absolute, regardless of the axis
+    mode. The same is true for touch events, stating it again here just adds to
+    the confusion.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 544ce0cee3cc146ed1df06ed5762d21ecdfe9e8a
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:14 2011 +1000
+
+    Add two linebreaks for asciidoc list parsing
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 9e46dd35896c2517b1c95224b979fc7126dce49f
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:13 2011 +1000
+
+    Changing the touch device mode generates a DeviceChangedEvent
+    
+    State it explicitly.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 1b0c016d1f7615e3670fa97fc8f24bc6b79e4f7b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 24 09:07:11 2011 +1000
+
+    XITouchClass' props needs a num_props
+    
+    In XI2 requests, the length field isn't enough to determine the number of
+    elements since it may vary in future versions.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 94b21b47b51c2c66aa0372dfc323d6aedf12b549
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Tue Aug 23 15:28:50 2011 +1000
+
+    specs: fix two typos in XI2proto.txt
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 9f33733fffddd166c64f0bfd293c3de385cf4411
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 17 16:02:39 2011 +1000
+
+    specs: ValuatorClass includes a mode
+    
+    Documented in the description, but missing in the definition.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Daniel Stone <daniel@fooishbar.org>
+
+commit 4adfb5ad6c064981e2c7eb57db4bdd81cc7029ea
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Fri Aug 5 15:28:51 2011 -0700
+
+    Specify dependent device pointer/touch handling
+    
+    With the added rules, trackpads should be manageable no matter what
+    occurs (button presses and pointer motion). Gesture and touch semantics
+    during these actions are not well defined, and cancelling touches cleans
+    up the protocol and implementation.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 29cd8aac674b1d831814b48b2ee2f2f7ff16497b
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Fri Aug 5 14:41:59 2011 -0700
+
+    Use the same valuator axes for pointer and touch events
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit b5e357c76dc5d8b2176fa470186688ec943d08e6
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Fri Aug 5 14:49:32 2011 -0700
+
+    Remove touch "Observe" grabs
+    
+    The semantics of these grabs doesn't work for all use cases. Raw touch
+    events will likely work better.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 3172e3c52eb45e4830d85ae53888d0b28c13df62
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Fri Aug 5 14:20:05 2011 -0700
+
+    Fix up pointer event emulation section
+    
+    * Wording cleanups for tense and to make some sentences flow better.
+    * Upon further review, it does seem to make more sense to deliver
+      emulated pointer events through the same slave device rather than the
+      master device. Thus, slave devices (including floating devices) may
+      emit emulated pointer events.
+    * Peter is correct, it doesn't make sense to set the PointerEmulated
+      flag on touch events.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit b15ad6e0dc1759e514c998eecd7e61b25308add6
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Fri Aug 5 13:59:05 2011 -0700
+
+    Peter is right, floating devices can emit touch events
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 951cb8314343fcd5cdc392dfc78024fa184fc694
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Aug 2 15:53:35 2011 -0700
+
+    Prettyify touch device types
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 45387042f8fa767dda610936557548adf76306c5
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Aug 2 15:29:54 2011 -0700
+
+    Update device type terminology
+    
+    Remove IndepedentTouch and SemiMultitouch devices. These may be handled
+    in an implementation specific manner through the props array of ATOMs in
+    the touch class information.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 3a2f149b33531d02fff8e46181ffdcfcecb0c8cb
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Aug 2 15:23:21 2011 -0700
+
+    Yes, send TouchEnd to owner, TouchPendingEnd to other listeners
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 343fd699457483d1572b5229874f8ce6460a9b2d
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Aug 2 15:22:15 2011 -0700
+
+    Separate "XI2.x" into "XI 2.x" for readability
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 3cbc9b68a314b2986afa811f81f76c941be1973b
+Merge: d331251 2ba875f
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Tue Aug 2 14:09:11 2011 -0700
+
+    Merge remote-tracking branch 'origin/master' into multitouch
+    
+    Conflicts:
+       XI2.h
+
+commit 2ba875f4f2907bb9735ee3317b7e07c5b9d1304b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Tue Aug 2 10:20:53 2011 +1000
+
+    Put a warning in about not adding any further libXi defines
+    
+    The matching commit in libXi is
+        e8531dd6a981c6cf19a1d256c29e886e34e8f51a
+        libXi-1.4.2-21-ge8531ddp
+    
+        Add XI2 library-internal array offsets to XIint.h
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit ee91dcda461513cdca45160df580841daa6f50e2
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Thu Mar 17 16:29:08 2011 +1000
+
+    specs: add a linebreak for asciidoc parsing
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 2cd2adb7a454072954704e1a215df49ce9dac410
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Jun 3 15:56:21 2011 +1000
+
+    Provide convenience defines for owner_events.
+    
+    No functional effect, just to improve readability of code.
+    
+    It's not obvious what "True" or "False" stands for in a function with 11
+    arguments. Compare
+        XIGrabButton(dpy, deviceid, button, grab_window, cursor,
+                     GrabModeAsync, GrabModeSync, True,
+                     event_mask, num_modifiers, &modifiers);
+    
+    vs.
+    
+    XIGrabButton(dpy, deviceid, button, grab_window, cursor,
+                 GrabModeAsync, GrabModeSync, XIOwnerEvents,
+                 event_mask, num_modifiers, &modifiers);
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Daniel Stone <daniel@fooishbar.org>
+
+commit bef7648827a0696debdd629472a45508a30144b1
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Jun 3 15:13:12 2011 +1000
+
+    Add XI2-specific defines for grab and property requests
+    
+    XI 2.0 headers forced clients to mix XI2 specific constants with defines for
+    core input. Most notable here are the grab code which required GrabModeAsync
+    or GrabModeSync from core, but _not_ AnyModifier (XIAnymodifier !=
+    AnyModifier). This is a hard-to-debug cause for bugs.
+    
+    Add defines for grab modes, grab return codes and property modes as well as
+    a define for the AnyPropertyType. These defines are identical to the ones
+    defined in core but stop the use of input-related defines from either core
+    or XI 1.x.
+    
+    Clients must use the core defines None and CurrentTime where applicable.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Daniel Stone <daniel@fooishbar.org>
+
+commit d331251884101c503c533e088bcace6b830b5a95
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Tue May 3 18:44:53 2011 +0100
+
+    Clean up and reword multitouch ownership/emulation
+    
+    Remove 'withheld' indirect section as well.
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+
+commit f17598c1beeadbc648588d192d2e7eb616019e2d
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Tue May 3 17:21:34 2011 +0100
+
+    Mostly typographical
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+
+commit 2d5294cb0b9dc641e0f8ef1ff5f2a1a1803a57ee
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Thu Apr 28 12:02:43 2011 +0100
+
+    Further cleanups and clarifications
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+
+commit 75790691706447cecc9f7948ea55caba05dc0d7d
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Tue Apr 26 20:30:13 2011 +0100
+
+    Reword touch introduction, labels for all
+    
+    Reword the introduction to the multitouch section to try to be a bit
+    clearer, and go on a mad section-labelling spree.
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+
+commit 400365a9bfa9ab3eaaa0bec08e32023f54d04207
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Tue Apr 26 19:51:41 2011 +0100
+
+    typo fix
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+
+commit 416f077d8747d3d96dd5a71600e1e394226c3dc1
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Apr 22 16:14:54 2011 +0100
+
+    Add FIXME sidebars, remove single-grab stipulation
+    
+    Add very visible FIXME sections to more clearly mark what's broken; also
+    remove the stipulation that only one grab may be active at a time.
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+
+commit a500bc990ba61bf32637114d1840db7147a0deaa
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Apr 22 15:42:09 2011 +0100
+
+    Add inline references, fix usecase bulleting
+    
+    Replace 'see section x.y.z' with better inline links; fix nested
+    bulleting of XI 2.1 usecases.
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+
+commit 3a89a5a3003309f810c9273fac8cf5943238df28
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Apr 22 15:31:52 2011 +0100
+
+    Doc note: No seriously, this is WIP
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+
+commit b46a3bafd95f1bb507e4851aaa6967cf20c4eb8e
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Apr 22 14:27:06 2011 +0100
+
+    Formatting fixups and minor rewording
+    
+    No semantic changes.
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+
+commit e19eaef83db9181787a13fa95d642971c33d559b
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Mon Apr 11 10:09:57 2011 +1000
+
+    Require configure flag to build this proto version.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit ca39f67c2aa5b255f2b85d7c649edff8295eed5e
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Apr 8 13:27:47 2011 +1000
+
+    Put a #warning and #error in to avoid unsuspecting XI 2.1 users.
+    
+    The #warning directive is intentionally outside the define to disable the
+    error. Early adopters of the protocol can't see this warning often enough.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit b1149ab782619eaeadf70affd94239184e082d03
+Author: Alexandre Julliard <julliard@winehq.org>
+Date:   Tue Apr 12 22:39:25 2011 +0200
+
+    XI2.h: Fix off-by-one error in the XIMaskLen definition.
+    
+    The previous definition would give the wrong result for events that are
+    a multiple of 8.
+    
+    Signed-off-by: Alexandre Julliard <julliard@winehq.org>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit ab930a51047f48c7befd4316a9b116f37075697f
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Mar 23 13:27:02 2011 +1000
+
+    specs: enable asciidoc parsing for XIproto.txt
+    
+    The vast majority of this patch are indentation changes, removing preceding
+    spaces from text.
+    Header lines  and some linebreaks to enable list parsing were added.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit ef7518cc6260e05a00c496c9e0f3a13c8a785b85
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Mar 23 13:32:42 2011 +1000
+
+    specs: move erroneous Errors: line to where it belongs
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Julien Cristau <jcristau@debian.org>
+
+commit ed840d79d3cac60b2fb17448afcc28828236e91b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 18 16:17:09 2011 +1000
+
+    specs: rewrite pointer emulation section
+    
+    plus a fixme
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 15e76dd365fce4e936a9f468496be3789495103b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 18 15:29:25 2011 +1000
+
+    specs: rewrite pointer emulation for indirect devices
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 9c2817fd761bbe6c6da4e2a5638d80fa53975c4b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 18 15:10:34 2011 +1000
+
+    specs: Rewrite Touch events delivery section
+    
+    And add a fixme
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit c883261f2bad6196e5ff1b3c1397300775e55da7
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 18 14:48:15 2011 +1000
+
+    specs: Add a fixme for using raw events instead of GrabModeObserve
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 35710924957791e389e10fcc67b75967769f001c
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 18 14:16:55 2011 +1000
+
+    specs: clean/rewrite touch grab and ownership bits
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit f24c9ae749c84d953ee3b35be1ea937dce7b86d3
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 18 13:58:29 2011 +1000
+
+    spec: Move ClientPointer up again.
+    
+    Prep work to have a separate first-class headline for touch processing
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 0e4a782339403f270de6e072262680b3a4baec01
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 18 13:52:09 2011 +1000
+
+    specs: move warning about out-of-band processing up a bit.
+    
+    The out-of-band processing is really only important for pointer emulation.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 1d720b30c996a693014f2c70004c9717945b574f
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 18 12:12:47 2011 +1000
+
+    specs: move touch sequence handling (owner-only) up a bit.
+    
+    This is to restructure to get the simple cases clarified up first before
+    explaining more complex changes.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit a4583dcd3e1c18e5c0cc616c143aafbf7ec1d88b
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Mar 18 12:02:21 2011 +1000
+
+    specs: move from "init move destroy" to "begin update end"
+    
+    And rewrite that paragraph a bit.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit fe19202c220ce010a85fe5abc0b5a6a0c314ea9a
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Thu Mar 17 16:29:08 2011 +1000
+
+    specs: add a linebreak for asciidoc parsing
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit f9fa8f9a7dc333b45bfac0b0c6f97b8b1a72d260
+Merge: a02566c 47901cd
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Thu Mar 17 14:51:52 2011 +1000
+
+    Merge branch 'master' into chase-multitouch
+    
+    Conflicts:
+       specs/XI2proto.txt
+    
+    Fixed up (added) asciidoc for touch proto.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 47901cd142e832eb930166cbfa769e4fbca969c5
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Mar 15 21:37:39 2011 -0400
+
+    XIproto.txt: fix whitespace issues
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 5f43b8b19e6abd00a6295692f3346295bb01b973
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Mar 15 21:29:43 2011 -0400
+
+    XI2proto.txt: fix whitespace issues
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 0ac450f47c55fb2bac394f6377f1aabde1ab8429
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Mar 15 15:43:48 2011 -0400
+
+    specs: convert XI2proto.txt to html using asciidoc
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit f21f00bd9b8e641d639d70d086df1b14faa34e38
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Mar 16 09:57:10 2011 +1000
+
+    Add minimal asciidoc syntax
+    
+    Though this protocol description is mainly to be viewed as textfile, a few
+    minor changes make it parsable for asciidoc to spit out reasonably
+    nicely-formatted html code.
+    
+    Changes include:
+    - underline section headers with the matching lines
+    - add linebreaks before lists to parse them as lists
+    - change indentation level for normal text to be left-marging aligned and
+      for <pre> text to be indented
+    - comment out section dividers
+    
+    It's possible to run asciidoc XI2proto.txt and get some nice html output
+    now.
+    
+    Reviewed-by: Gaetan Nadon <memsize@videotron.ca>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit a02566ca7fd37d279b957037e1251a3b3419866d
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Thu Mar 10 11:53:57 2011 -0500
+
+    Many more updates to the XI 2.1 protocol
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit db7c0eccc74e95f247d78541e4c4a28cfa87b5b4
+Author: Chase Douglas <chase.douglas@canonical.com>
+Date:   Sun Feb 20 16:35:09 2011 -0500
+
+    Updates for pointer emulation and more touch device modes
+    
+    Also includes resolutions for dependent devices and implicit grabs and
+    how to handle slave touch device attachment and touch selections.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+
+commit 99f15a2346c882237c78afbd638932f132d6113c
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Mon Feb 7 10:19:06 2011 +0000
+
+    Add touch classes and events, bump to 2.1
+    
+    Introduce multitouch support through a new TouchClass, as well as new
+    TouchBegin, TouchEnd, TouchOwnership, TouchUpdate, and TouchUpdateUnowned
+    events.  Bump to version 2.1.
+    
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+    Co-authored-by: Chase Douglas <chase.douglas@canonical.com>
+    Co-authored-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 13baef91f071ee1607f4c3bf6c1fea60e6651b89
+Author: Fernando Carrijo <fcarrijo@freedesktop.org>
+Date:   Thu Jan 27 22:40:11 2011 -0200
+
+    Fix typos in XIproto.txt
+    
+    Signed-off-by: Fernando Carrijo <fcarrijo@freedesktop.org>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 5c2d5fd99d73ae52aef62376046b5708c58a4271
+Author: Chase Douglas <chase.douglas@ubuntu.com>
+Date:   Fri Dec 17 17:11:09 2010 +0000
+
+    Include stdint.h
+    
+    I'm now getting build failures due to missing stdint.h. It seems we
+    should include it explicitly in XI2proto.h anyways.
+    
+    Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
+    Signed-off-by: Daniel Stone <daniel@fooishbar.org>
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
 commit 56ffb564712257e0f998170e83071a6ee85aa231
 Author: Peter Hutterer <peter.hutterer@who-t.net>
 Date:   Thu Nov 11 14:10:26 2010 +1000
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
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.
+
old mode 100755 (executable)
new mode 100644 (file)
index 77d1ea7..3312f2f
@@ -1,3 +1,6 @@
+
+SUBDIRS = specs
+
 inputdir = $(includedir)/X11/extensions
 input_HEADERS = \
        XI.h \
@@ -8,9 +11,6 @@ input_HEADERS = \
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = inputproto.pc
 
-dist_doc_DATA = XI2proto.txt XIproto.txt
-
-
 MAINTAINERCLEANFILES = ChangeLog INSTALL
 
 .PHONY: ChangeLog INSTALL
diff --git a/XI2.h b/XI2.h
index 6ba1377..e864b06 100644 (file)
--- a/XI2.h
+++ b/XI2.h
 #ifndef _XI2_H_
 #define _XI2_H_
 
-/* Indices into the versions[] array (XExtInt.c). Used as a index to
- * retrieve the minimum version of XI from _XiCheckExtInit.
- * For indices 0 to 6 see XI.h */
-#ifndef Dont_Check /* defined in XI.h */
-#define Dont_Check                              0
-#endif
 #define XInput_2_0                              7
-
+/* DO NOT ADD TO THIS LIST. These are libXi-specific defines.
+   See commit libXi-1.4.2-21-ge8531dd */
 
 #define XI_2_Major                              2
-#define XI_2_Minor                              0
+#define XI_2_Minor                              2
 
 /* Property event flags */
 #define XIPropertyDeleted                       0
 #define XIPropertyCreated                       1
 #define XIPropertyModified                      2
 
+/* Property modes */
+#define XIPropModeReplace                       0
+#define XIPropModePrepend                       1
+#define XIPropModeAppend                        2
+
+/* Special property type used for XIGetProperty */
+#define XIAnyPropertyType                       0L
+
 /* Enter/Leave and Focus In/Out modes */
 #define XINotifyNormal                          0
 #define XINotifyGrab                            1
 #define XINotifyPointerRoot                     6
 #define XINotifyDetailNone                      7
 
+/* Grab modes */
+#define XIGrabModeSync                          0
+#define XIGrabModeAsync                         1
+#define XIGrabModeTouch                         2
+
+/* Grab reply status codes */
+#define XIGrabSuccess                           0
+#define XIAlreadyGrabbed                        1
+#define XIGrabInvalidTime                       2
+#define XIGrabNotViewable                       3
+#define XIGrabFrozen                            4
+
+/* Grab owner events values */
+#define XIOwnerEvents                           True
+#define XINoOwnerEvents                         False
+
 /* Passive grab types */
 #define XIGrabtypeButton                        0
 #define XIGrabtypeKeycode                       1
 #define XIGrabtypeEnter                         2
 #define XIGrabtypeFocusIn                       3
+#define XIGrabtypeTouchBegin                    4
 
 /* Passive grab modifier */
 #define XIAnyModifier                           (1U << 31)
@@ -78,6 +98,8 @@
 #define XIAsyncPairedDevice                     3
 #define XIAsyncPair                             4
 #define XISyncPair                              5
+#define XIAcceptTouch                           6
+#define XIRejectTouch                           7
 
 /* DeviceChangedEvent change reasons */
 #define XISlaveSwitch                           1
 #define XISlaveKeyboard                         4
 #define XIFloatingSlave                         5
 
-/* Device classes */
+/* Device classes: classes that are not identical to Xi 1.x classes must be
+ * numbered starting from 8. */
 #define XIKeyClass                              0
 #define XIButtonClass                           1
 #define XIValuatorClass                         2
+#define XIScrollClass                           3
+#define XITouchClass                            8
+
+/* Scroll class types */
+#define XIScrollTypeVertical                    1
+#define XIScrollTypeHorizontal                  2
+
+/* Scroll class flags */
+#define XIScrollFlagNoEmulation                 (1 << 0)
+#define XIScrollFlagPreferred                   (1 << 1)
 
 /* Device event flags (common) */
 /* Device event flags (key events only) */
 #define XIKeyRepeat                             (1 << 16)
 /* Device event flags (pointer events only) */
+#define XIPointerEmulated                       (1 << 16)
+/* Device event flags (touch events only) */
+#define XITouchPendingEnd                       (1 << 16)
+#define XITouchEmulatingPointer                 (1 << 17)
+
+/* Touch modes */
+#define XIDirectTouch                           1
+#define XIDependentTouch                        2
 
 /* XI2 event mask macros */
 #define XISetMask(ptr, event)   (((unsigned char*)(ptr))[(event)>>3] |=  (1 << ((event) & 7)))
 #define XIClearMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] &= ~(1 << ((event) & 7)))
 #define XIMaskIsSet(ptr, event) (((unsigned char*)(ptr))[(event)>>3] &   (1 << ((event) & 7)))
-#define XIMaskLen(event)        (((event + 7) >> 3))
+#define XIMaskLen(event)        (((event) >> 3) + 1)
 
 /* Fake device ID's for event selection */
 #define XIAllDevices                            0
 #define XI_RawButtonPress                15
 #define XI_RawButtonRelease              16
 #define XI_RawMotion                     17
-#define XI_LASTEVENT                     XI_RawMotion
+#define XI_TouchBegin                    18 /* XI 2.2 */
+#define XI_TouchUpdate                   19
+#define XI_TouchEnd                      20
+#define XI_TouchOwnership                21
+#define XI_RawTouchBegin                 22
+#define XI_RawTouchUpdate                23
+#define XI_RawTouchEnd                   24
+#define XI_LASTEVENT                     XI_RawTouchEnd
 /* NOTE: XI2LASTEVENT in xserver/include/inputstr.h must be the same value
  * as XI_LASTEVENT if the server is supposed to handle masks etc. for this
  * type of event. */
 #define XI_RawButtonPressMask            (1 << XI_RawButtonPress)
 #define XI_RawButtonReleaseMask          (1 << XI_RawButtonRelease)
 #define XI_RawMotionMask                 (1 << XI_RawMotion)
+#define XI_TouchBeginMask                (1 << XI_TouchBegin)
+#define XI_TouchEndMask                  (1 << XI_TouchEnd)
+#define XI_TouchOwnershipChangedMask     (1 << XI_TouchOwnershipChanged)
+#define XI_TouchUpdateMask               (1 << XI_TouchUpdate)
+#define XI_RawTouchBeginMask             (1 << XI_RawTouchBegin)
+#define XI_RawTouchEndMask               (1 << XI_RawTouchEnd)
+#define XI_RawTouchUpdateMask            (1 << XI_RawTouchUpdate)
 
 #endif /* _XI2_H_ */
index 2fd91eb..733f923 100644 (file)
@@ -60,6 +60,7 @@
 #include <X11/Xproto.h>
 #include <X11/X.h>
 #include <X11/extensions/XI2.h>
+#include <stdint.h>
 
 /* make sure types have right sizes for protocol structures. */
 #define Window  uint32_t
@@ -187,6 +188,32 @@ typedef struct {
     uint16_t    pad2;
 } xXIValuatorInfo;
 
+/***
+ * Denotes a scroll valuator on a device.
+ * One XIScrollInfo describes exactly one scroll valuator that must have a
+ * XIValuatorInfo struct.
+ */
+typedef struct {
+    uint16_t    type;           /**< Always ValuatorClass         */
+    uint16_t    length;         /**< Length in 4 byte units       */
+    uint16_t    sourceid;       /**< source device for this class */
+    uint16_t    number;         /**< Valuator number              */
+    uint16_t    scroll_type;    /**< ::XIScrollTypeVertical, ::XIScrollTypeHorizontal */
+    uint16_t    pad0;
+    uint32_t    flags;          /**< ::XIScrollFlagEmulate, ::XIScrollFlagPreferred   */
+    FP3232      increment;      /**< Increment for one unit of scrolling              */
+} xXIScrollInfo;
+
+/**
+ * Denotes multitouch capability on a device.
+ */
+typedef struct {
+    uint16_t    type;           /**< Always TouchClass */
+    uint16_t    length;         /**< Length in 4 byte units */
+    uint16_t    sourceid;       /**< source device for this class */
+    uint8_t     mode;           /**< DirectTouch or DependentTouch */
+    uint8_t     num_touches;    /**< Maximum number of touches (0==unlimited) */
+} xXITouchInfo;
 
 /**
  * Used to select for events on a given window.
@@ -623,6 +650,23 @@ typedef struct {
 } xXIAllowEventsReq;
 #define sz_xXIAllowEventsReq                   12
 
+/**
+ * Allow or replay events on the specified grabbed device.
+ * Since XI 2.2
+ */
+typedef struct {
+    uint8_t     reqType;
+    uint8_t     ReqType;                /**< Always ::X_XIAllowEvents */
+    uint16_t    length;                 /**< Length in 4 byte units */
+    Time        time;
+    uint16_t    deviceid;
+    uint8_t     mode;
+    uint8_t     pad;
+    uint32_t    touchid;                /**< Since XI 2.2 */
+    Window      grab_window;            /**< Since XI 2.2 */
+} xXI2_2AllowEventsReq;
+#define sz_xXI2_2AllowEventsReq                20
+
 
 /**
  * Passively grab the device.
@@ -856,7 +900,31 @@ typedef struct
 } xXIDeviceChangedEvent;
 
 /**
- * Default input event for pointer or keyboard input.
+ * The owner of a touch stream has passed on ownership to another client.
+ */
+typedef struct
+{
+    uint8_t     type;               /**< Always GenericEvent */
+    uint8_t     extension;          /**< XI extension offset */
+    uint16_t    sequenceNumber;
+    uint32_t    length;             /**< Length in 4 byte units */
+    uint16_t    evtype;             /**< XI_TouchOwnership */
+    uint16_t    deviceid;           /**< Device that has changed */
+    Time        time;
+    uint32_t    touchid;
+    Window      root;
+    Window      event;
+    Window      child;
+/* └──────── 32 byte boundary ────────┘ */
+    uint16_t    sourceid;
+    uint16_t    pad0;
+    uint32_t    flags;
+    uint32_t    pad1;
+    uint32_t    pad2;
+} xXITouchOwnershipEvent;
+
+/**
+ * Default input event for pointer, keyboard or touch input.
  */
 typedef struct
 {
@@ -901,7 +969,7 @@ typedef struct
     uint16_t    deviceid;
     Time        time;
     uint32_t    detail;
-    uint16_t    pad0;
+    uint16_t    sourceid;               /**< The source device (XI 2.1) */
     uint16_t    valuators_len;          /**< Length of trailing valuator
                                              mask in 4 byte units */
     uint32_t    flags;                  /**< ::XIKeyRepeat */
diff --git a/XI2proto.txt b/XI2proto.txt
deleted file mode 100755 (executable)
index 10f58c2..0000000
+++ /dev/null
@@ -1,1677 +0,0 @@
-
-                            The X Input Extension
-                                Version 2.0
-
-                              Peter Hutterer
-                         peter.hutterer@redhat.com
-                               Red Hat, Inc.
-
-
-
-1. Introduction
-
-The X Input Extension version 2.0 (XI2) is the second major release of the X
-Input Extension.
-
-XI2 provides a number of enhancements over version 1.5, including:
-- use of XGE and GenericEvents. GenericEvents are of flexible length with a
-  minimum length of 32 bytes.
-- explicit device hierarchy of master and slave devices. See Section 4.
-- use of multiple independent master devices (Multi-Poiner X or MPX).
-- the ability for devices to change capabilities at runtime.
-- raw device events
-
-XI2's intent is to replace both core input processing and prior versions of
-the X Input Extension. Historically, the majority of applications employed the
-core protocol requests and events to handle user input. The core protocol does
-not provide information about which device generated the event. The X Input
-Extension version up to 1.5 requires the differentiation between core and
-extended devices. Extended devices may not be core devices and thus cannot be
-used on applications employing the core protocol. XI2 addresses both of these
-issues by enabling devices to be both extended and core devices and providing
-device information in each event (with the exception of core events).
-
-                              ❧❧❧❧❧❧❧❧❧❧❧
-
-2. Notations used in this document
-
-Notation for requests:
-┌───
-    Name of request
-        name of request field:       type of request field
-        name of request field:       type of request field
-        ▶
-        name of reply field:         type of reply field
-└───
-
-Notation for events:
-┌───
-    Name of event
-        name of field:               type of field
-        name of field:               type of field
-└───
-
-Complex fields are specified in the following notation:
-          name of field:                  COMPLEXFIELDTYPE
-or, if multiple of these fields exist:
-          name of field:                  LISTofCOMPLEXFIELDTYPE
-
-COMPLEXFIELDTYPE:  { name of subfield:   type of subfield,
-                    name of subfield:   type of subfield }
-
-                              ❧❧❧❧❧❧❧❧❧❧❧
-
-3. Interoperability between version 1.x and 2.0
-
-There is little interaction between 1.x and 2.x versions of the X Input
-Extension. Clients are requested to avoid mixing XI1.x and XI2 code as much as
-possible. Several direct incompatibilities are observable:
-
-3.1 Limitations resulting from different variable ranges
-
-XI2 provides a larger range for some fields than XI1. As a result, XI1 clients
-may not receive data an XI2 client receives.
-These fields include:
-- devices with a deviceid of greater than 127 are invisible to XI1 clients.
-- key events and key grabs featuring larger than 255 can only be sent to XI2
-  clients.
-- no subpixel information is avialable to XI1 clients. If motion events are in
-  a subpixel range only, the server may omit these events and an XI 1.x client
-  will not receive events until the pixel boundary is crossed.
-
-
-3.2 Blocking of grabs
-
-XI1 grabs are different to XI2 grab and a device may not be grabbed through an
-XI2 grab if an XI1 grab is currently active on this device or vice versa.
-Likewise, a keycode or button already grabbed by an XI 1.x or XI2 client may
-not be grabbed with the same modifier combination by an XI2 or XI 1.x client,
-respectively.
-
-3.3 Invisibility of Master Devices
-
-XI 1.x was not designed with support for multiple master devices (see Section
-4). As a result, only the first master pointer and master keyboard are visible
-to XI 1.x clients, all other master devices are invisible and cannot be
-accessed from XI 1.x calls.
-
-                              ❧❧❧❧❧❧❧❧❧❧❧
-
-4. The Master/Slave device hierarchy
-
-XI2 introduces a device hierarchy split up into so-called Master Devices (MD)
-and Slave Devices (SD).
-
-4.1 Master devices
-An MD is a virtual device created and managed by the server. MDs may send core
-events and XI events. However, an MD does not represent a physical device and
-relies on SDs for event generation. MDs come in two forms: as master pointers
-or as master keyboards. A master pointer is represented by a visible cursor on
-the screen. A master keyboard is represented by a keyboard focus.
-
-Each master pointer is paired with the respective master keyboard and vice
-versa, and this pairing is constant for the lifetime of both input devices.
-Clients can use this pairing behaviour to implement input paradigms that
-require pointer and keyboard interation (e.g. SHIFT + Click).
-
-4.2 Slave devices
-An SD is usually a physical device configured in the server. SDs are not
-represented by a cursor or keyboard focus and may be attached to a master
-pointer or master keyboard. SDs can only be attached to any master of the same
-type (e.g. a physical pointer device can be attached to any master pointer).
-
-If an event is generated by an SD
-- if the SD is attached to a master pointer, it changes the position and/or
-  button state of the master pointer.
-- if the SD is attached to a master keyboard, it sends events to this
-  keyboard's focus window (if applicable) and/or changes the modifier state of
-  this keyboard.
-- if the SD is not attached to an MD ("floating"), it does not change 
-  any master device. The SD has its own (invisible) sprite and its own focus.
-  Both the sprite and the focus must be managed explicitly by the client
-  program.
-
-4.3 Event processing for attached slave devices
-
-Whenever an SD changes its logical state,
-- the event is delivered as an XI event to any interested clients. If the
-  device is floating, event processing stops.
-  Otherwise, if the device is attached,
-- the master device changes its classes to reflect the SD's capabilities. All
-  interested clients are notified of this device change.
-- then, the event is delivered as an XI event from the MD to any interested
-  clients. If the event has been delivered, event processing stops.
-  Otherwise,
-- the event is delivered as a core event to any interested clients.
-
-Given that W is the event window, and P the parent window of W, event delivery
-to P is only attempted if neither the XI event, nor the core event has been
-delivered on W. Once an event has been delivered as either XI or core event,
-event processing stops.
-
-4.4. The ClientPointer principle
-
-Many core protocol and some extension requests are ambiguous when multiple
-master devices are available (e.g. QueryPointer does not specfy which pointer).
-The X server does not have the knowledge to chose the contextually correct
-master device. For each client, one master pointer is designated as this
-clients's "ClientPointer". Whenever a client sends an ambiguous request (e.g.
-QueryPointer), the ClientPointer or the keyboard paired with the ClientPointer
-is chosen to provide the data for this request.
-
-This ClientPointer may be explicitly assigned to a client with the
-SetClientPointer call. If no ClientPointer is set when a client issues an
-ambiguous request, the server choses one device as the ClientPointer. The
-method of chosing a ClientPointer from the available master pointers is
-implementation-specific.
-
-If the master pointer currently set as ClientPointer for one or more clients is
-removed, the server may either unset the ClientPointer setting or change the
-ClientPointer to a different master pointer.
-
-                              ❧❧❧❧❧❧❧❧❧❧❧
-5. Data types
-
-BUTTONMASK
-        A binary mask defined as (1 << button number).
-        A SETofBUTTONMASK is a binary OR of zero or more BUTTONMASK.
-
-DEVICE { DEVICEID, AllDevices, AllMasterDevices }
-        A DEVICE specifies either a DEVICEID or AllDevices or
-        AllMasterDevices.
-
-DEVICEID { CARD16 }
-        A DEVICEID is a numerical ID for a device currently available in the
-        server. The server may re-use a device ID after a device's removal.
-        The device IDs 0 and 1 are reserved.
-        AllDevices ........ 0
-        AllMasterDevices .. 1
-
-DEVICEUSE { MasterPointer, MasterKeyboard, SlavePointer,
-            SlaveKeyboard, FloatingSlave }
-        A DEVICEUSE field specifies the current use of a device in the MD/SD
-        device hierarchy. See Section 4 for more information.
-
-EVENTMASK
-        An EVENTMASK is a binary mask defined as (1 << event type).
-        A SETofEVENTMASK is a binary OR of zero or more EVENTMASK.
-
-FP1616
-        Fixed point decimal in 16.16 format as one INT16 and one CARD16.
-        The INT16 contains the integral part, the CARD32 the decimal fraction
-        shifted by 16.
-
-FP3232
-        Fixed point decimal in 32.32 format as one INT32 and one CARD32.
-        The INT32 contains the integral part, the CARD32 the decimal fraction
-        shifted by 32.
-
-VALUATORMASK
-        A binary mask defined as (1 << valuator number).
-        A SETofVALUATORMASK is a binary OR of zero or more VALUATORMASK.
-
-                              ❧❧❧❧❧❧❧❧❧❧❧
-6. Errors
-
-Errors are sent using core X error reports.
-
-Device
-        A value for a DEVICE argument does not specify a valid DEVICE.
-
-                              ❧❧❧❧❧❧❧❧❧❧❧
-7. Requests:
-
-The server does not guarantee that the length of a reply remains constant in
-future revisions of XI2. A client must always retrieve the exact length of the
-protocol reply from the connection, even if the reply is longer than defined
-for the XI2 version supported by the client.
-Additional bytes in a request may include data supported in later versions of
-XI2. Clients should ignore this data. Padding bytes in XI2 protocol requests
-are required to be 0.
-
-7.1 Requests introduced in version 2.0
-
-    ┌───
-        XIQueryVersion
-        major_version:          CARD16
-        minor_version:          CARD16
-        ▶
-        major_version:          CARD16
-        minor_version:          CARD16
-    └───
-
-    The client sends the highest supported version to the server and the
-    server sends the highest version it supports, but no higher than the
-    requested version. Major versions changes can introduce incompatibilities
-    in existing functionality, minor version changes introduce only backward
-    compatible changes.  It is the client's responsibility to ensure that the
-    server supports a version which is compatible with its expectations.
-
-    major_version
-        Major XI2 version.
-    minor_version
-        Minor XI2 version.
-
-    If major_version is less than 2, a BadValue error occurs.
-
-    ┌───
-        XIQueryDevice
-        DEVICE                  deviceid
-        ▶
-        num_devices:            CARD16
-        deviceinfo:             LISTofDEVICEINFO
-    └───
-
-    DEVICEINFO { deviceid:              DEVICEID
-                 use:                   DEVICEUSE
-                 attachment:            DEVICEID
-                 enabled:               BOOL
-                 num_classes:           CARD16
-                 name_len:              CARD16
-                 name:                  LISTofCHAR8
-                 classes:               LISTofCLASS }
-
-    CLASS { BUTTONCLASS, KEYCLASS, AXISCLASS }
-
-    BUTTONCLASS { type:                 ButtonClass
-                  length:               CARD16
-                  sourceid:             CARD16
-                  buttons_len:          CARD16
-                  state:                SETofBUTTONMASK
-                  labels:               LISTofATOM }
-
-    KEYCLASS    { type:                 KeyClass
-                  length:               CARD16
-                  sourceid:             CARD16
-                  num_keys:             CARD16
-                  keys:                 LISTofCARD32 }
-
-    AXISCLASS   { type:                 AxisClass
-                  length:               CARD16
-                  sourceid:             CARD16
-                  axisnumber:           CARD16
-                  label:                ATOM
-                  min:                  FP3232
-                  max:                  FP3232
-                  value:                FP3232
-                  resolution:           CARD32 }
-
-    XIQueryDevice details information about the requested input devices.
-
-    devices
-        The device to list. If devices is AllDevices, all enabled and
-        disabled devices are listed. If devices is AllMasterDevices, all
-        enabled and disabled master devices are listed. If devices is a
-        valid DEVICE, only this DEVICE is listed and num_devices is 1.
-    num_devices
-        The number of deviceinfos returned.
-
-    Each deviceinfo is detailed as follows:
-    deviceid
-        The unique ID of the device. Device IDs may get re-used when a device
-        is removed.
-    use
-        If the device is a master pointer, use is MasterPointer.
-        If the device is a master keyboard, use is MasterKeyboard.
-        If the device is a slave pointer, use is SlavePointer.
-        If the device is a slave keyboard, use is SlaveKeyboard.
-        If the device is a floating slave, use is FloatingSlave.
-    attachment
-        If the device is a master pointer or a master keyboard, attachment
-        specifies the paired master keyboard, or the paired master pointer,
-        respectively.  If the device is a non-floating slave device
-        attachment specifies the master device this device is attached to.
-        If the device is a floating slave, attachment is undefined.
-    enabled
-        Zero if the device is disabled, non-zero otherwise.
-    num_classes
-        Number of classes provided.
-    name_len
-        Length of the name in bytes not including padding.
-    classes
-        Details the available classes provided by the device in an undefined
-        order.
-    name
-        The device's name. padded to a multiple of 4 bytes.
-
-    For all classes, type specifies the device class. Clients are required
-    to ignore unknown device classes. The length field specifies the length
-    of the class in 4 byte units.
-    The following classes may occur only once: ButtonClass, KeyClass
-
-    ButtonClass:
-    type
-        Always ButtonClass.
-    length
-        Length in 4 byte units.
-    sourceid
-        The device this class originates from.
-    num_buttons
-        Number of buttons provided by the device.
-    labels
-        List of Atoms specifying the label for each button. An Atom of None
-        specifies an unlabeled button. Buttons are listed in the device-native
-        order regardless of the current button mapping.
-    state
-        The current button mask for this device after button mapping is
-        applied. Each bit representing a button is 1 if this button is
-        logically down, or 0 otherwise. State is a multiple of 4-byte units
-        and always contains at least num_buttons bits.
-
-    KeyClass:
-    type
-        Always KeyClass.
-    length
-        Length in 4 byte units.
-    sourceid
-        The device this class originates from.
-    num_keys
-        Number of keycodes provided by the device.
-    keys
-        List of keycodes provided.
-
-    AxisClass:
-    type
-        Always AxisClass.
-    length
-        Length in 4 byte units.
-    sourceid
-        The device this class originates from.
-    axisnumber
-        Axis number of this axis. The axis number is in device-native
-        order and potential axis mappings are ignored.
-    label
-        Atom specifying the axis name. An Atom of None specifies an unlabeled
-        axis.
-    min
-        Minimum value.
-    max
-        Minimum value.
-    resolution
-        Resolution in counts/meter.
-    mode
-        Relative or Absolute.
-    value
-        Last published axis value (if mode is absolute).
-
-    An axis in Relative mode may specify min and max as a hint to the
-    client. If no min and max information is available, both must be 0.
-
-    ┌───
-        XISelectEvents
-            window:         Window
-            num_masks:      CARD16
-            masks:          LISTofEVENTMASK
-
-    └───
-
-    EVENTMASK { deviceid:          DEVICE,
-                mask_len:          CARD16,
-                mask:              SETofEVENTMASK
-
-    window
-        The window to select the events on.
-    num_masks
-        Number of items in masks.
-    deviceid
-        Numerical deviceid, or AllDevices, or AllMasterDevices.
-    mask_len
-        Length of mask in 4 byte units.
-    mask
-        Event mask. An event mask for an event type T is defined as (1 << T).
-
-    XISelectEvents selects for XI2 events on window.
-
-    If num_masks is 0, a BadValue error occurs.
-
-    Each mask sets the (and overwrites a previous) event mask for the DEVICE
-    specified through deviceid. The device AllDevices or
-    AllMasterDevices is treated as a separate device by server. A client's
-    event mask is the union of AllDevices, AllMasterDevices and the
-    per-device event mask.
-    The removal of device from the server unsets the event masks for the
-    device. If an event mask is set for AllDevices or AllMasterDevices, the
-    event mask is not cleared on device removal and affects all future
-    devices.
-
-    If mask_len is 0, the event mask for the given device is cleared.
-
-    The mask for XIHierarchyEvents may only be selected for XIAllDevices.
-    Setting it for any other device results in a BadValue error.
-
-    ┌───
-        XIGetSelectedEvents
-            window:         Window
-            ▶
-            num_masks:      CARD16
-            masks:          LISTofEVENTMASK
-    └───
-
-    window
-        The window to select the events on.
-    num_masks
-        Number of items in masks.
-    masks
-        Selected event masks by this client.
-
-    Masks are returned on a per-device basis, with masks for AllDevices and
-    AllMasterDevices returned separately. A client can calculate the
-    effective mask for a device with a bitwise OR of the AllDevices, the
-    AllMasterDevices and the device-specific mask.
-
-    If num_masks is 0, no events have been selected by this client on the
-    given window.
-
-    ┌───
-        XIQueryPointer
-            window:         Window
-            deviceid:       DEVICEID
-            ▶
-            root:           Window
-            child:          Window
-            root_x:         FP1616
-            root_y:         FP1616
-            win_x:          FP1616
-            win_y:          FP1616
-            same_screen:    BOOL
-            mods:           MODIFIERINFO
-            group:          GROUPINFO
-            buttons_len:    CARD16
-            buttons:        SETofBUTTONMASK
-    └───
-
-    Query a master pointer device for its current position.
-
-    root
-        The root window the pointer is logically on.
-    child
-        The child window of window that contains the pointer or None.
-    root_x
-    root_y
-        Pointer position relative to the root window's origin.
-    win_x
-    win_y
-        Pointer position relative to window or 0 if same_screen is false.
-    same_screen
-        True if window is on the same screen as the pointer.
-    mods
-        XKB modifier state on the paired device.
-    group
-        XKB group state on the paired device.
-    buttons_len
-        The length of buttons in 4 byte units.
-    buttons
-        Button state.
-
-    If the device is not a master pointer device or not a floating slave
-    pointer, a BadDevice error results.
-
-    ┌───
-        XIWarpPointer
-            src_win:         Window
-            dst_win:         Window
-            src_x:           FP1616
-            src_y:           FP1616
-            src_width:       INT16
-            src_height:      INT16
-            dst_x:           FP1616
-            dst_y:           FP1616
-            deviceid:        DEVICEID
-    └───
-
-    WarpPointer moves the pointer of deviceid as if the user had moved
-    the pointer. WarpPointer can only be called for MasterPointer and
-    FloatingSlave devices.
-
-    src_win
-       If src_window is not None, the move only takes place if src_window
-       contains the pointer and the pointer is contained in the specified
-       rectangle of src_window.
-    dst_win
-       If dst_win is None, this request moves the pointer by offsets
-       dst_x/dst_y relative to the current position of the pointer. If
-        dst_window is a window, this request moves the pointer to
-       dst_x/dst_y relative to dst_win's origin.
-    src_x
-    src_y
-    src_width
-    src_height
-       Specifies the source window rectangle.
-    dst_x
-    dst_y
-        The relative coordinates to move the pointer if dst_win is None, or
-        the absolute coordinates if dst_win is a window.
-    deviceid
-        The device to warp.
-
-    This request cannot be used to move the pointer outside the confine-to
-    window of an active pointer grab. An attempt will only move the pointer as
-    far as the closest edge of the confine-to window.
-
-    This request will generate events just as if the user had instantaneously
-    moved the pointer.
-
-    ┌───
-        XIChangeCursor
-            win:             Window
-            cursor:          Cursor
-            deviceid:        DEVICEID
-    └───
-
-    Change a master pointer's cursor on the specified window.
-
-    window
-        The window.
-    cursor
-        The new cursor or None.
-    deviceid
-        The master pointer device.
-
-    Whenever device enters a window W, the cursor shape is selected in the
-    following order:
-    - if the current window has a device cursor C(d) defined for device,
-      display this cursor C(d).
-    - otherwise, if the current window has a cursor C(w) defined in the core
-      protocol's window attributes, display cursor C(w).
-    - repeat on parent window until a cursor has been found.
-
-    The device cursor for a given window is reset once the window is destroyed
-    or the device is removed, whichever comes earlier.
-
-    If deviceid does not specify a master pointer, a BadDevice error
-    is returned.
-
-    ┌───
-        XIChangeHierarchy
-            num_changes:     CARD8
-            changes:         LISTofHIERARCHYCHANGES
-    └───
-
-    HIERARCHYCHANGE { ADDMASTER, REMOVEMASTER, ATTACHSLAVE, DETACHSLAVE }
-
-    HIERARCHYCHANGETYPE { AddMaster, RemoveMaster, AttachSlave, DetachSlave }
-
-    CHANGEMODE { Float, Attach }
-
-    ADDMASTER { type:        HIERARCHYCHANGETYPE
-                length:      CARD16
-                name_len:    CARD16
-                send_core:   BOOL
-                enable:      BOOL
-                name:        LISTofCHAR8 }
-
-    REMOVEMASTER { type:            HIERARCHYCHANGETYPE
-                   length:          CARD16
-                   deviceid:        DEVICEID
-                   return_mode:     CHANGEMODE
-                   return_pointer:  DEVICEID
-                   return_keyboard: DEVICEID }
-
-    ATTACHSLAVE   { type:        HIERARCHYCHANGETYPE
-                    length:      CARD16
-                    deviceid:    DEVICEID
-                    master:      DEVICEID }
-
-    DETACHSLAVE { type:       HIERARCHYCHANGETYPE
-                  length:     CARD16
-                  deviceid:   DEVICEID }
-
-    XIChangeHierarchy allows a client to modify the MD/SD device
-    hierarchy (see Section 4).
-
-    num_changes
-        The number of changes to apply to the current hierarchy.
-    changes
-        The list of changes.
-
-    The server processes the changes in the order received from the client and
-    applies each requested change immediately. If an error occurs, processing
-    stops at the current change and returns the number of successfully applied
-    changes in the error.
-
-    ADDMASTER creates a pair of master devices.
-    type
-        Always AddMaster.
-    length
-        Length in 4 byte units.
-    name_len
-        Length of name in bytes.
-    send_core
-        True if the device should send core events.
-    enable
-        True if the device is to be enabled immediately.
-    name
-        The name for the new master devices. The master pointer's name is
-        automatically appended with " pointer", the master keyboard's name is
-        automatically appended with " keyboard".
-
-    REMOVEMASTER removes an existing master device.
-    type
-        Always RemoveMaster.
-    length
-        Length in 4 byte units.
-    deviceid
-        The device to remove.
-    return_mode
-        Return mode for attached slave devices.
-        If return_mode is Float, all slave devices are set to floating.
-        If return_mode is Attach, slave pointers are attached to
-        return_pointer and slave keyboards are attached to
-        return_keyboard.
-    return_pointer
-    return_keyboard
-        The master pointer and master keyboard to attach slave devices to, if
-        return_mode is Attach. If return_mode is Float, return_pointer
-        and return_keyboard are undefined.
-
-    Removing a master pointer removes the paired master keyboard and vice
-    versa.
-
-    ATTACHSLAVE attaches a slave device to a given master device.
-    type
-        Always ChangeAttachment.
-    length
-        Length in 4 byte units.
-    deviceid
-        Deviceid of the slave device.
-    master
-        The new master device to attach this slave device to.
-
-    DETACHSLAVE detaches a slave device from its current master device.
-    type
-        Always ChangeAttachment.
-    length
-        Length in 4 byte units.
-    deviceid
-        Deviceid of the slave device.
-
-    ┌───
-        XISetClientPointer
-            win:             Window
-            deviceid:        DEVICEID
-    └───
-
-    Set the ClientPointer for the client owning win to the given device.
-
-    win
-         Window or client ID.
-    deviceid
-         The master pointer or master keyboard that acts as ClientPointer.
-
-    Some protocol requests are ambiguous and the server has to choose a device
-    to provide data for a request or a reply. By default, the server will
-    choose a client's ClientPointer device to provide the data, unless the
-    client currently has a grab on another device. See section 4.4 for more
-    details.
-
-    If win is None, the ClientPointer for this client is set to the given
-    device. Otherwise, if win is a valid window, the ClientPointer for the
-    client owning this window is set to the given device. Otherwise, if win is
-    not a valid window but a client with the client mask equal to win exists,
-    this client's ClientPointer is set to the given device.
-
-    If deviceid does not specify a master pointer or master keyboard, a
-    BadDevice error is returned.
-
-    If window does not specify a valid window or client ID and is not None, a
-    BadWindow error is returned.
-
-    ┌───
-        XIGetClientPointer
-            win:             Window
-            ▶
-            set:             BOOL
-            deviceid:        DEVICEID
-    └───
-
-    Query the ClientPointer for the client owning win.
-
-    win
-        The window or client ID.
-    set
-        True if the client has a ClientPointer set.
-    deviceid
-        The master pointer that acts as a ClientPointer if set is True.
-
-    No difference is made between a ClientPointer set explicitly through
-    XISetClientPointer and a ClientPointer implicitly assigned by the server
-    in response to an ambiguous request.
-
-    ┌───
-        XISetFocus
-            focus:           Window
-            deviceid:        DEVICEID
-            time:            Time
-    └───
-
-    Set the focus for the given device to the given window. Future key events
-    from this device are sent to this window.
-    This request generates FocusIn and FocusOut events.
-
-    focus
-        A viewable window or None.
-    deviceid
-        The device to modify the focus window for.
-    time
-        Specifies the time to change the focus or CurrentTime.
-
-    If focus is None, key events from this device are discarded until a new
-    focus window is set. If focus is a viewable window, key events from this
-    device are sent to this window. If the window becomes unviewable, the
-    window's first viewable ancestor automatically becomes the focus window
-    and FocusIn and FocusOut events are sent as if a client had changed the
-    focus window.
-    This is equivalent to RevertToParent in the core XSetInputFocus window.
-
-    This request has no effect if the specified time is earlier than the
-    current last-focus-change time or is later than the current X server time.
-    Otherwise, the last-focus-change time is set to the specified time.
-
-    ┌───
-        XIGetFocus
-            deviceid:        DEVICEID
-            ▶
-            focus:           Window
-    └───
-
-    Return the current focus window for the given device.
-
-    ┌───
-        XIGrabDevice
-            deviceid:        DEVICEID
-            grab_window:     Window
-            owner_events:    BOOL
-            grab_mode:       { Synchronous, Asynchronous }
-            paired_device_mode: { Synchronous, Asynchronous }
-            time:            TIMESTAMP or CurrentTime
-            cursor:          Cursor
-            mask_len:        CARD16
-            masks:           SETofEVENTMASK
-            ▶
-            status:          Success, AlreadyGrabbed, Frozen, InvalidTime, NotViewable
-    └───
-
-    This request actively grabs control of the specified input device. Further
-    input events from this device are reported only to the grabbing client.
-    This request overides any previous active grab by this client for this
-    device.
-
-    deviceid
-        The device to grab.
-    grab_window
-        Events are reported relative to the grab window.
-    owner_events
-        Specifies whether event will be reported normally or relative to the
-        grab window.
-    grab_mode
-        Specifies if this device will be frozen as a result of the grab.
-    paired_device_mode
-        Specifies if the master device paired with this device will be frozen
-        as a result of the grab.
-    time
-        A valid server time or CurrentTime.
-    cursor
-        The cursor to display for the duration of the grab or None.
-    mask_len
-        Length of mask in 4 byte units.
-    mask
-        Event mask. An event mask for an event type T is defined as (1 << T).
-    status
-        Success or the reason why the grab could not be established.
-
-    The masks parameter specifies which events the client wishes to receive
-    while the device is grabbed.
-
-    If owner-events is False, input events generated from this device are
-    reported with respect to grab-window, and are only reported if selected by
-    being included in the event-list.  If owner-events is True, then if a
-    generated event would normally be reported to this client, it is reported
-    normally, otherwise the event is reported with respect to the grab-window,
-    and is only reported if selected by being included in the event-list. For
-    either value of owner-events, unreported events are discarded.
-
-    If grab-mode is Asynchronous, device event processing continues normally.
-    If the device is currently frozen by this client, then processing of
-    device events is resumed. If grab-mode is Synchronous, the state of the
-    grabbed device (as seen by means of the protocol) appears to freeze,
-    and no further device events are generated by the server until the
-    grabbing client issues a releasing XIAllowEvents request or until the
-    device grab is released. Actual device input events are not lost while the
-    device is frozen; they are simply queued for later processing.
-
-    If the device is a slave device, the paired-device-mode is ignored.
-    Otherwise, if this device is a master device and paired-device-mode is
-    Asynchronous, event processing is unaffected by activation of the grab. If
-    this device is a master device and paired-device-mode is Synchronous, the
-    state of the master device paired with this device (as seen by means of the
-    protocol) appears to freeze, and no further events are generated by the
-    server until the grabbing client issues a releasing XIAllowEvents request
-    or until the device grab is released. Actual events are not lost while the
-    devices are frozen; they are simply queued for later processing.
-
-    If the cursor is not None and the device is a master pointer device, the
-    cursor will be displayed until the device is ungrabbed.
-
-    This request fails and returns:
-    AlreadyGrabbed: If the device is actively grabbed by some other client.
-    NotViewable: If grab-window is not viewable.
-    InvalidTime: If the specified time is earlier than the last-grab-time for
-                 the specified device or later than the current X server time.
-                 Otherwise, the last-grab-time for the specified device is set
-                 to the specified time and CurrentTime is replaced by the
-                 current X server time.
-    Frozen: If the device is frozen by an active grab of another client.
-
-    To release a grab of a device, use XIUngrabDevice.
-
-    ┌───
-        XIUngrabDevice
-            deviceid:        DEVICEID
-            time:            TIMESTAMP or CurrentTime
-    └───
-
-    This request releases the device if this client has it actively grabbed
-    (from either XIGrabDevice or  XIPassiveGrabDevice) and
-    releases any queued events. If any devices were frozen by the grab,
-    XIUngrabDevice thaws them.
-
-    deviceid
-        The device to grab.
-    time
-        A valid server time or CurrentTime.
-
-    The request has no effect if the specified time is earlier than the
-    last-device-grab time or is later than the current server time.
-    This request generates FocusIn and FocusOut events.
-    An XIUngrabDevice is performed automatically if the event window for an
-    active device grab becomes not viewable.
-
-    ┌───
-        XIAllowEvents:
-            deviceid:        DEVICEID
-            time:            TIMESTAMP or CurrentTime
-            event_mode:      { AsyncDevice, SyncDevice,
-                               AsyncPairedDevice, SyncPairedDevice,
-                               ReplayDevice, AsyncPair, SyncPair }
-    └───
-
-    The XIAllowEvents request releases some queued events if the client
-    has caused a device to freeze.
-
-    deviceid
-        The device to grab.
-    time
-        A valid server time or CurrentTime.
-    event_mode
-        Specifies whether a device is to be thawed and events are to be
-        replayed.
-
-    The request has no effect if the specified time is earlier than the
-    last-grab time of the most recent active grab for the client, or if the
-    specified time is later than the current X server time.
-
-    The following describes the processing that occurs depending on what constant
-    you pass to the event-mode argument:
-    AsyncDevice:
-        If the specified device is frozen by the client, event processing for that
-        device continues as usual. If the device is frozen multiple times  by the
-        client on behalf of multiple separate grabs, AsyncDevice thaws for
-        all.
-        AsyncDevice has no effect if the specified device is not frozen by the
-        client, but the device need not be grabbed by the client.
-    SyncDevice:
-        If the specified device is frozen and actively grabbed by the client,
-        event processing for that device continues normally until the next
-        event is reported to the client. At this time, the specified device
-        again appears to freeze. However, if the reported event causes the
-        grab to be released, the specified device does not freeze.
-        SyncDevice has no effect if the specified device is not frozen by the
-        client or is not grabbed by the client.
-     ReplayDevice:
-        If the specified device is actively grabbed by the client and is frozen
-        as the result of an event having been sent to the client (either from
-        the activation of a XIGrabButton or from a previous XIAllowEvents with
-        mode SyncDevice, but not from a Grab), the grab is released and
-        that event is completely reprocessed.  This time, however, the request
-        ignores any passive grabs at or above (towards the root) the
-        grab-window of the grab just released.
-        The request has no effect if the specified device is not grabbed by
-        the client or if it is not frozen as the result of an event.
-     AsyncPairedDevice
-        If the paired master device is frozen by the client, event processing
-        for it continues as usual. If the paired device is frozen multiple
-        times by the client on behalf of multiple separate grabs,
-        AsyncPairedDevice thaws for all.
-        AsyncPairedDevice has no effect if the device is not frozen by the
-        client, but those devices need not be grabbed by the client.
-        AsyncPairedDevice has no effect if deviceid specifies a slave device.
-     SyncPairedDevice
-        If the paired master device is frozen by the client, event processing (for
-        the paired master device) continues normally until the next button or key
-        event is reported to the client for the grabbed device (button event for
-        the grabbed device, key or motion event for the device), at which time
-        the device again appears to freeze. However, if the reported event causes
-        the grab to be released, then the device does not freeze.
-        SyncPairedDevice has no effect if the specified device is not grabbed
-        by the client or if it is no frozen as the result of an event.
-        SyncPairedDevice has no effect if deviceid specifies a slave device.
-     SyncPair
-        If both the device and the paired master device are frozen by the
-        client, event processing (for both devices) continues normally until
-        the next XIButtonPress, XIButtonRelease, XIKeyPress, or XIKeyRelease
-        event is reported to the client for a grabbed device (button event for
-        a pointer, key event for a keyboard), at which time the devices again
-        appear to freeze. However, if the reported event causes the grab to be
-        released, then the devices do not freeze (but if the other device is
-        still grabbed, then a subsequent event for it will still cause both
-        devices to freeze).
-        SyncPair has no effect unless both the device and the paired master
-        device are frozen by the client. If the device or paired master device
-        is frozen twice by the client on behalf of two separate grabs,
-        SyncPair thaws for both (but a subsequent freeze for SyncPair will
-        only freeze each device once).
-        SyncPair has no effect if deviceid specifies a slave device.
-     AsyncPair
-        If the device and the paired master device are frozen by the client,
-        event processing for both devices continues normally. If a device is
-        frozen twice by the client on behalf of two separate grabs, AsyncBoth
-        thaws for both. AsyncPair has no effect unless both the device and the
-        paired master device frozen by the client.
-        AsyncPair has no effect if deviceid specifies a slave device.
-
-    ┌───
-        XIPassiveGrabDevice
-            deviceid:        DEVICE
-            detail:          CARD32
-            grab_type:       GRABTYPE
-            grab_window:     Window
-            cursor:          Cursor
-            owner_events:    Bool
-            grab_mode:       { Synchronous, Asynchronous }
-            paired_device_mode: { Synchronous, Asynchronous }
-            num_modifiers:   INT16
-            mask_len:        CARD16
-            masks:           SETofEVENTMASK
-            modifiers:       CARD32 or GrabAnyModifier
-            ▶
-            num_modifiers_return:    INT16
-            modifiers_return:        GRABMODIFIERINFO
-    └───
-
-        GRABTYPE         { GrabtypeButton, GrabtypeKeycode, GrabtypeEnter,
-                           GrabtypeFocusIn}
-
-        GRABMODIFIERINFO {   status:    Access
-                             modifiers: CARD32 }
-
-        Establish an explicit passive grab for a button or keycode
-        on the specified input device.
-
-        cursor
-            The cursor to display for the duration of the grab. If grab_type
-            is not GrabtypeButton, this argument is ignored.
-        deviceid
-            The device to establish the passive grab on or AllDevices or
-            AllMasterDevices.
-        detail
-            The button number, or key symbol to grab for.
-            Must be 0 for GrabtypeEnter and GrabtypeFocusIn.
-        grab_type
-            The type of grab to establish.
-        grab_window
-            Events are reported relative to the grab window.
-        grab_mode
-            If grab-mode is Asynchronous, device event processing continues
-            normally.  If the device is currently frozen by this client, then
-            processing of device events is resumed. If grab-mode is
-            Synchronous, the state of the grabbed device (as seen by means of
-            the protocol) appears to freeze, and no further device events are
-            generated by the server until the grabbing client issues a
-            releasing XIAllowEvents request or until the device grab is
-            released. Actual device input events are not lost while the device
-            is frozen; they are simply queued for later processing.
-        mask_len
-            Length of mask in 4 byte units.
-        mask
-            Event mask. An event mask for an event type T is defined as (1 << T).
-        modifiers
-            XKB modifier state to activate this passive grab.
-        num_modifiers
-            Number of elements in modifiers.
-        owner_events
-            Specifies whether event will be reported normally or relative to the
-            grab window.
-        num_modifiers_return
-            Number of elements in modifiers_return
-        modifiers_return
-            XKB modifier state that could not be grabbed.
-
-        If owner-events is False, input events generated from this device are
-        reported with respect to grab-window, and are only reported if
-        selected by being included in the event-list.  If owner-events is
-        True, then if a generated event would normally be reported to this
-        client, it is reported normally, otherwise the event is reported
-        with respect to the grab-window, and is only reported if selected
-        by being included in the event-list. For either value of
-        owner-events, unreported events are discarded.
-
-        If deviceid specifies a master pointer, the modifiers of the paired
-        master keyboard are used. If deviceid specifies a slave pointer
-        the modifiers of the master keyboard paired with the attached master
-        pointers are used. If deviceid specifies a slave keyboard, the
-        modifiers of the attached master keyboard are used. Note that
-        activating a grab on a slave device detaches the device from its
-        master. In this case, the modifiers after activation of the grab are
-        from the slave device only and may be different to the modifier state
-        when the grab was triggered.
-
-        In the future, if grab_type is GrabtypeButton or GrabtypeKeyboard, the
-        device is actively grabbed if:
-        - the device is not grabbed, and
-        - the specified modifier keys are down, and
-        - the grab_type is GrabtypeButton and the button specified in detail
-          is logically pressed or the grab_type is GrabtypeKeycode and the
-          keycode specified in detail is logically pressed, and
-        - the grab_window contains the pointer, and
-        - a passive grab on the same button/keycode + modifier
-          combination does not exist on an ancestor of grab_window.
-
-        Otherwise, if grab_type is GrabtypeEnter or GrabtypeFocusIn, the
-        device is actively grabbed if:
-        - the device is not actively grabbed, and
-        - the specified modifier keys are down, and
-        - the grab_type is GrabtypeEnter and the device's pointer has moved
-          into grab_window or a descendant of grab_window, or the grab_type is
-          GrabtypeFocusIn and the device's focus has been set to the
-          grab_window or a descendant of grab_window,
-        - a passive grab of the same grab_type + modifier combination does not
-          does not exist on an ancestor of grab_window.
-
-        A modifier of GrabAnyModifier is equivalent to issuing the request for
-        all possible modifier combinations (including no modifiers). A client
-        may request a grab for GrabAnyModifier and explicit modifier
-        combinations in the same request.
-
-        A GrabtypeButton or GrabtypeKeyboard grab is released when all buttons
-        or keycode are released, independent of the state of modifier keys.
-        A GrabtypeEnter or GrabtypeFocusIn grab is released when the
-        pointer or focus leaves the window and all of its descendants,
-        independent of the state of modifier keys.
-        Note that the logical state of a device (as seen by means of the
-        protocol) may lag the physical state if device event processing is
-        frozen.
-
-        This request overrides all previous passive grabs by the same
-        client on the same button/key/enter/focus in + modifier combinations
-        on the same window.
-
-        If some other client already has issued a XIPassiveGrabDevice request
-        with the same button or keycode and modifier combination, the
-        failed modifier combinations is returned in modifiers_return. If some
-        other client already has issued an XIPassiveGrabDevice request of
-        grab_type  XIGrabtypeEnter or XIGrabtypeFocusIn with the same
-        grab_window and the same modifier combination, the failed modifier
-        combinations are returned in modifiers_return. If num_modifiers_return
-        is zero, all passive grabs have been successful.
-
-        If a button grab or enter grab activates, EnterNotify and LeaveNotify
-        events with mode Grab are generated as if the pointer were to suddenly
-        warp from its current position some position in the grab_window.
-        However, the pointer does not warp, and the pointer position is used
-        as both the initial and final positions for the events.
-
-        If a keycode grab or focus grab activates, FocusIn and FocusOut events
-        with mode Grab are generated as if the focus were to change from the
-        current window to the grab_window.
-
-        If an enter or focus in grab activates, additional EnterNotify events
-        with mode XIPassiveGrabNotify are generated as if the pointer or focus
-        were to suddenly warp from its current position to some position in
-        the grab window.  These events are sent to the grabbing client only
-        and only if the grab event mask has selected for it. If such a passive
-        grab deactivates, addional LeaveNotify events with mode
-        XIPassiveUngrabNotify are generated and sent to the grabbing client
-        before the grab deactivates.
-
-    ┌───
-        XIPassiveUngrabDevice
-            deviceid:        DEVICEID
-            detail:          CARD32
-            grab_type:       GRABTYPE
-            grab_window:     Window
-            num_modifiers:   INT16
-            modifiers:       MODIFIERINFO
-    └───
-
-        Release an explicit passive grab on the specified input device.
-
-        deviceid
-            The device to establish the passive grab on.
-        detail
-            The button number or key symbol to ungrab.
-            Must be 0 for GrabtypeEnter and GrabtypeFocusIn.
-        grab_type
-            The type of grab to establish.
-        grab_window
-            Events are reported relative to the grab window.
-        modifiers
-            XKB modifier state to activate this passive grab.
-        num_modifiers
-            Number of elements in modifiers.
-
-        This request has no effect if the client does not have a passive grab
-        of the same type, same button or keycode (if applicable) and modifier
-        combination on the grab_window.
-
-    ┌───
-        XIListProperties
-            deviceid:        DEVICEID
-            ▶
-            num_properties:  INT16
-            properties:      LISTofATOM
-    └───
-
-        List the properties associated with the given device.
-
-        deviceid
-            The device to list the properties for.
-        num_atoms
-            Number of atoms in the reply
-        atoms
-            All properties on the device.
-
-    ┌───
-        XIChangeProperty
-            deviceid:        DEVICEID
-            property:        ATOM
-            type:            ATOM
-            format:          { 8, 16, 32 }
-            mode:            { Append, Prepend, Replace }
-            num_items:       CARD32
-            data:            LISTofINT8, or LISTofINT16, or LISTofINT32
-    └───
-
-        Change the given property on the given device.
-
-        deviceid
-            The device to change the property on.
-        property
-            The property to modify.
-        type
-            The property's type.
-        mode
-            One of Append, Prepend, or Replace
-        num_items
-            Number of items following this request.
-        data
-            Property data (nitems * format/8 bytes)
-
-        The type is uninterpreted by the server. The format specifies whether
-        the data should be viewed as a list of 8-bit, 16-bit, or 32-bit
-        quantities so that the server can correctly byte-swap as necessary.
-
-        If the mode is Replace, the previous propert y value is discarded.  If
-        the mode is Prepend or Append, then the type and format must match the
-        existing property value (or a Match error results). If the property is
-        undefined, it is treated as defined with the correct type and format
-        with zero-length data. For Prepend, the data is tacked on to the
-        beginning of the existing data, and for Append, it is tacked on to the
-        end of the existing data.
-
-        The lifetime of a property is not tied to the storing client. Properties
-        remain until explicitly deleted, until the device is removed, or
-        until server reset.
-
-        A property cannot be deleted by setting nitems to zero. To delete a
-        property, use XIDeleteProperty.
-
-        This request generates an XIPropertyEvent.
-
-    ┌───
-        XIDeleteProperty
-            deviceid:        DEVICEID
-            property:        ATOM
-    └───
-
-        Deletes the given property on the given device.
-
-        deviceid
-            The device to delete the property on.
-        property
-            The property to delete.
-
-        If the property is deleted, an XIPropertyEvent is generated on the device.
-        If the property does not exist, this request does nothing.
-
-    ┌───
-        XIGetProperty
-            deviceid:        DEVICEID
-            property:        ATOM
-            type:            Atom or AnyPropertyType
-            offset:          CARD32
-            len:             CARD32
-            delete:          BOOL
-            ▶
-            type:            Atom
-            bytes_after:     CARD32
-            num_items:       CARD32
-            format:          { 8, 16, 32 }
-            data:            LISTofINT8, or LISTofINT16, or LISTofINT32
-    └───
-        
-        Get the data for the given property on the given device.
-
-        deviceid
-            The device to retrieve the property data from.
-        property
-            The property to retrieve the data from..
-        type
-            The property type to retrieve or AnyPropertyType
-        offset
-            The offset in 4-byte units.
-        len
-            Number of bytes to receive in 4-byte units.
-        delete
-            Delete the property after retrieving the data.
-        bytes_after
-            Number of unread bytes in the stored property
-        num_items
-            Number of items in data
-        format
-            8, 16, or 32
-        data
-            Property data (nitems * format/8 bytes)
-
-        If the specified property does not exist for the specified device, then
-        the return type is None, the format and bytes-after are zero, and the value is
-        empty. The delete argument is ignored in this case. If the specified property
-        exists but its type does not match the specified type, then the return
-        type is the actual type of the property, the format is the actual format of the
-        property (never zero), the bytes-after is the length of the property in bytes
-        (even if the format is 16 or 32), and the value is empty. The delete
-        argument is ignored in this case. If the specified property exists and
-        either AnyPropertyType is specified or the specified type matches the actual
-        type of the property, then the return type is the actual type of the property,
-        the format is the actual format of the property
-        (never zero), and the bytes-after and value are as follows, given:
-                 N = actual length of the stored property in bytes
-                    (even if the format is 16 or 32)
-                 I = 4 * long-offset
-                 T = N−I
-                 L = MINIMUM(T, 4 * long-length)
-                 A = N − (I + L)
-        The returned value starts at byte index I in the property (indexing
-        from 0), and its length in bytes is L. However, it is a Value error if
-        offset is given such that L is negative. The value of bytes_after is A,
-        giving the number of trailing unread bytes in the stored property. If
-        delete is True and the bytes_after is zero, the property is also
-        deleted from the device, and a XIPropertyNotify event is generated on
-        the device.  
-     
-
-8. Events:
-
-An event specifies its length in 4-byte units after the initial 32 bytes.
-Future versions of the protocol may provide additional information
-in the same event, thus increasing the event size. Clients are required to
-always read the number of bytes specified by the event, not the size of the
-event they may have been compiled against.
-
-
-The following event types are available in XI2.
-
-Version 2.0:
-        HierarchyChanged
-        DeviceChanged
-        KeyPress
-        KeyRelease
-        ButtonPress
-        ButtonRelease
-        Motion
-        RawKeyPress
-        RawKeyRelease
-        RawButtonPress
-        RawButtonRelease
-        RawMotion
-        Enter
-        Leave
-        FocusIn
-        FocusOut
-        PropertyEvent
-
-All events have a set of common fields specified as EVENTHEADER.
-
-
-EVENTHEADER { type:                       BYTE
-              extension:                  BYTE
-              sequenceNumber:             CARD16
-              length:                     CARD32
-              evtype:                     CARD16
-              deviceid:                   DEVICEID
-              time:                       Time }
-
-    type
-        Always GenericEvent.
-    extension
-        Always the X Input extension offset.
-    sequenceNumber
-        Sequence number of last request processed by the server.
-    length
-        Length in 4-byte units after the initial 32 bytes.
-    evtype
-        XI-specific event type.
-    deviceid
-        Numerical device id for a device.
-    time
-        Time in ms.
-
-
-    ┌───
-        HierarchyEvent:
-            EVENTHEADER
-            flags:                      SETofHIERARCHYMASK
-            num_info:                   CARD16
-            info:                       LISTofHIERARCHYINFO
-    └───
-
-
-    HIERARCHYMASK { MasterAdded, MasterRemoved, SlaveAttached, SlaveDetached,
-                    SlaveAdded, SlaveRemoved, DeviceEnabled, DeviceDisabled }
-
-    HIERARCHYINFO { deviceid:           DEVICEID,
-                    attachment:         DEVICEID,
-                    type:               DEVICEUSE
-                    enabled:            BOOL
-                    flags:              SETofHIERARCHYMASK}
-
-    flags
-        Set of the changes that have occured, causing this event.
-    num_info
-        The number of device info structs following the request.
-    info:
-        The current hierarchy information.
-
-    An XIHierarchyEvent is sent whenever the device hierarchy been
-    changed. The flags specify all types of hierarchy modifiations that have
-    occured.
-    For all devices, info details the hierarchy information after the
-    modification of the hierarchy has occured. For each device specified with
-    deviceid:
-    - if type is MasterPointer or MasterKeyboard, attachment decribes the
-      pairing of this device.
-    - if type is SlavePointer or SlaveKeyboard, attachment describes the
-      master device this device is attached to.
-    - if type is FloatingSlave device, attachment is undefined.
-
-    enabled
-         True if the device is enabled and can send events. A disabled master
-         device will not forward events from an attached, enabled slave
-         device.
-
-    Note: Multiple devices may be affected in one hierarchy change,
-    deviceid in an XIHierarchyEvent is always the first affected
-    device. Clients should ignore deviceid and instead use the devices list.
-
-    ┌───
-        DeviceChangedEvent:
-            EVENTHEADER
-            reason:                CHANGEREASON
-            source:                DEVICEID
-            num_classes:           CARD16
-            classes:               LISTofCLASS
-    └───
-
-    CHANGEREASON { SlaveSwitch, DeviceChange }
-
-    A DeviceChangeEvent is sent whenever a device changes it's capabilities.
-    This can happen either by a new slave device sending events through a
-    master device, or by a physical device changing capabilities at runtime.
-
-    reason
-        The reason for generating this event.
-        If reason is SlaveSwitch, the slave device sending events through
-        this device has changed and source specifies the new slave device.
-        A SlaveSwitch reason can only occur on a master device.
-        If reason is DeviceChange, the device itself has changed through
-        other means (e.g. a physical device change) and source is
-        the device itself.
-    source
-        The source of the new classes.
-    num_classes
-        Number of classes provided.
-    classes
-        Details the available classes provided by the device.  The order the
-        classes are provided in is undefined.
-
-    For a detailed description of classes, see the XQueryDevice request.
-
-    ┌───
-        DeviceEvent:
-            EVENTHEADER
-            detail:                     CARD32
-            root:                       Window
-            event:                      Window
-            child:                      Window
-            root_x:                     FP1616
-            root_y:                     FP1616
-            event_x:                    FP1616
-            event_y:                    FP1616
-            buttons_len:                CARD16
-            valuators_len:              CARD16
-            sourceid:                   DEVICEID
-            mods:                       MODIFIERINFO
-            group:                      GROUPINFO
-            flags:                      DEVICEEEVENTFLAGS
-            buttons:                    SETofBUTTONMASK
-            valuators:                  SETofVALUATORMASK
-            axisvalues:                 LISTofFP3232
-    └───
-
-    BUTTONBIT { (1 << Button1), (1 << Button2), ... , (1 << ButtonN) }
-    VALUATORBIT { (1 << 1), ( 1 << 2), ... ( 1 << n) }
-
-    MODIFIERINFO  { base_mods:           CARD32,
-                    latched_mods:        CARD32,
-                    locked_mods:         CARD32,
-                    effective_mods:      CARD32}
-    GROUPINFO     { base_group:          CARD8,
-                    latched_group:       CARD8,
-                    locked_group:        CARD8,
-                    effective_group:     CARD8}
-
-    DEVICEEVENTFLAGS (all events): none
-    DEVICEEVENTFLAGS (key events only): { KeyRepeat }
-    DEVICEEVENTFLAGS (pointer events only): none
-
-    An XIDeviceEvent is generated whenever the logical state of a device
-    changes in response to a button press, a button release, a motion, a key
-    press or a key release. The event type may be one of KeyPress,
-    KeyRelease, ButtonPress, ButtonRelease, Motion.
-
-    detail
-        The button number or key code, or 0.
-    root
-    event
-    child
-        The root window, event window or subwindow, respectively. See core
-        protocol specification for more detail.
-    root_x
-    root_y
-        The position of the pointer in screen coordinates (16.16 fixed point).
-    event_x
-    event_y
-        The position of the pointer in screen coordinates relative to the
-        event window (16.16 fixed point).
-
-    buttons_len
-        The length of buttons in 4 byte units.
-    valuators_len
-        The length of valuators in 4 byte units.
-    sourceid
-        The source device that originally generated the event.
-    mods
-        XKB modifier state before the event occured.
-    group
-        XKB group state before the event.
-    buttons
-        Button state before the event.
-    valuators
-        Bitmask of valuators provided in axisvalues.
-    axisvalues
-        Valuator data in device-native resolution.
-    flags
-        Miscellaneous information about this event; the union of the
-        common flag set and either the key or pointer flag set,
-        depending on the event type.
-        KeyRepeat means that this event is for repeating purposes, and
-        the physical state of the key has not changed.  This is only
-        valid for KeyPress events.
-
-    Modifier state in mods is detailed as follows:
-    base_mods
-        XKB base modifier state.
-    latched_mods
-        XKB latched modifier state.
-    locked_mods
-        XKB locked modifier state.
-
-    Group state in group is detailed as follows:
-    base_group
-        XKB base group state.
-    latched_group
-        XKB latched group state.
-    locked_group
-        XKB locked group state.
-
-    ┌───
-        RawEvent
-            EVENTHEADER
-            detail:                    CARD32
-            flags:                     DEVICEEVENTFLAGS
-            valuators_len:             CARD16
-            valuators:                 SETofVALUATORMASK
-            axisvalues:                LISTofFP3232
-            axisvalues_raw:            LISTofFP3232
-    └───
-
-    A RawEvent provides the information provided by the driver to the
-    client. RawEvent provides both the raw data as supplied by the driver and
-    transformed data as used in the server. Transformations include, but are
-    not limited to, axis clipping and acceleration.
-    Transformed valuator data may be equivalent to raw data. In this case,
-    both raw and transformed valuator data is provided.
-    RawEvents are sent exclusively to all root windows or to the client
-    that grabbed the device only.
-
-    eventtype
-        The type of event that occured on the device.
-    detail
-        The button number or keycode.
-    flags
-        Flags as described in DeviceEvent.
-    valuators_len
-        The length of valuators in 4 byte units.
-    valuators
-        Bitmask of valuators provided in axisvalues and axisvalues_raw.
-    axisvalues
-        Valuator data in device-native resolution.
-    axisvalues_raw
-        Untransformed valuator data in device-native resolution.
-
-    ┌───
-        Enter or Leave or FocusIn or FocusOut
-            EVENTHEADER
-            root:               Window
-            event:              Window
-            child:              Window
-            sourceid:           DEVICEID
-            root_x:             FP1616
-            root_y:             FP1616
-            event_x             FP1616
-            event_y:            FP1616
-            mode:               NOTIFYMODE
-            detail:             NOTIFYDETAIL
-            same_screen:        BOOL
-            focus:              BOOL
-            mods:               MODIFIERINFO
-            group:              GROUPINFO
-            buttons_len:        CARD16
-            buttons:            SETofBUTTONMASK
-    └───
-
-    NOTIFYMODE { Normal, Grab, Ungrab }
-    NOTIFYDETAIL { Ancestor, Virtual, Inferior, Nonlinear, NonlinearVirtual,
-                   Pointer, PointerRoot, None }
-
-    Enter or Leave events are sent whenever a device's pointer enters or
-    leaves a window.
-    FocusIn or FocusOut events are sent whenever a device's focus is set to or
-    away from a window.
-    The enter/leave and focus in/out model is described in the core protocol
-    specification, Section 11. (EnterNotify, LeaveNotify events).
-
-    For enter and leave events, the modifier and group state is the state of
-    the paired master device if the device is a master device, or the state of
-    the attached master keyboard if the device is an attached slave device, or
-    zero if the device is a floating slave device.
-
-    For focus in and out events, the button state is the state of the paired
-    master device if the device is a master device, or the state of the
-    attached master keyboard if the device is an attached slave device, or
-    zero if the device is a floating slave device.
-
-    root
-    event
-    child
-        The root window, event window, and child window, respectively. See the
-        core protocol specification for more detail.
-    sourceid
-        The device that caused the pointer to move.
-    root_x
-    root_y
-        The pointer coordinates relative to the root window.
-    event_x
-    event_y
-        The pointer coordinates relative to the event window.
-    mode
-        Normal pointer motion events have mode Normal. Pseudo-motion events
-        when a grab activates have mode Grab, and pseudo-motion events when a
-        grab deactivates have mode Ungrab. Pseudo-motion events caused by the
-        activation or deactivation of a passive enter or focus in grab have mode
-        XIPassiveGrabNotify or XIPassiveUngrabNotify.
-    detail
-        Specifies the relation of the event window to the window the pointer
-        entered or left. See the core protocol spec for details.
-    same_screen
-        True if the event window is on the same screen as the pointer's root
-        window.
-    focus
-        If the event window is the focus window or an inferior of the focus
-        window, then focus is True. Otherwise, focus is False. This field is
-        unspecified for focus in/out events.
-    mods
-        XKB modifier state before the event occured.
-    group
-        XKB group state before the event.
-    buttons_len
-        The length of buttons in 4 byte units.
-    buttons
-        Button state before the event.
-
-    ┌───
-        XIPropertyEvent
-            EVENTHEADER
-            property:           ATOM
-            what:               { PropertyCreated, PropertyDeleted, PropertyModified }
-    └───
-
-    XIPropertyEvents are sent whenever a device property is created, deleted or
-    modified by a client.
-
-    property
-        The property that has been created, deleted, or modified
-    what
-        Specifies what has been changed.
-     
-
-                              ❧❧❧❧❧❧❧❧❧❧❧
diff --git a/XIproto.txt b/XIproto.txt
deleted file mode 100755 (executable)
index f9d19f0..0000000
+++ /dev/null
@@ -1,2544 +0,0 @@
-           X11 Input Extension Protocol Specification
-                      Version 1.0
-                   X Consortium Standard
-                 X Version 11, Release 6.8
-               Mark Patrick, Ardent Computer
-               George Sachs, Hewlett-Packard
-               
-                      Version 1.5
-                    Peter Hutterer
-
-   Copyright © 1989, 1990, 1991 by Hewlett-Packard Company and
-   Ardent Computer
-
-   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. Ardent and
-   Hewlett-Packard make no representations about the suitability
-   for any purpose of the information in this document. It is
-   provided "as is" without express or implied warranty. Copyright
-   © 1989, 1990, 1991, 1992 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. X
-   Window System is a trademark of The Open Group.
-
-   Copyright © 2008 by Peter Hutterer
-
-   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.
-
-1. Input Extension Overview
-
-   This document defines an extension to the X11 protocol to
-   support input devices other than the core X keyboard and
-   pointer. An accompanying document defines a corresponding
-   extension to Xlib (similar extensions for languages other than
-   C are anticipated). This first section gives an overview of the
-   input extension. The next section defines the new protocol
-   requests defined by the extension. We conclude with a
-   description of the new input events generated by the additional
-   input devices.
-
-   This document only describes the behaviour of servers supporting 
-   up to the X Input Extension 1.5. For servers supporting the X 
-   Input Extensions 2.0, see XI2proto.txt. New clients are discouraged
-   from using this protocol specification. Instead, the use of XI 2.x 
-   is recommended.
-
-1.1 Design Approach
-
-   The design approach of the extension is to define requests and
-   events analogous to the core requests and events. This allows
-   extension input devices to be individually distinguishable from
-   each other and from the core input devices. These requests and
-   events make use of a device identifier and support the
-   reporting of n-dimensional motion data as well as other data
-   that is not reportable via the core input events.
-
-1.2 Core Input Devices
-
-   The X server core protocol supports two input devices: a
-   pointer and a keyboard. The pointer device has two major
-   functions. First, it may be used to generate motion information
-   that client programs can detect. Second, it may also be used to
-   indicate the current location and focus of the X keyboard. To
-   accomplish this, the server echoes a cursor at the current
-   position of the X pointer. Unless the X keyboard has been
-   explicitly focused, this cursor also shows the current location
-   and focus of the X keyboard. The X keyboard is used to generate
-   input that client programs can detect.
-
-   In servers supporting XI 1.4 and above, the core pointer and
-   the core keyboard are virtual devices that do not represent a
-   physical device connected to the host computer.
-   In servers supporting XI 2.0 and above, there may be multiple 
-   core pointers and keyboards. Refer to XI2proto.txt for more 
-   information.
-
-   The X keyboard and X pointer are referred to in this document
-   as the core devices, and the input events they generate
-   (KeyPress, KeyRelease, ButtonPress, ButtonRelease, and
-   MotionNotify) are known as the core input events. All other
-   input devices are referred to as extension input devices and
-   the input events they generate are referred to as extension
-   input events.
-
-   In servers supporting only XI 1.x, this input extension does
-   not change the behavior or functionality of the core input
-   devices, core events, or core protocol requests, with the
-   exception of the core grab requests. These requests may affect
-   the synchronization of events from extension devices. See the
-   explanation in the section titled "Event Synchronization and
-   Core Grabs".
-
-   Selection of the physical devices to be initially used by the
-   server as the core devices is left implementation-dependent.
-   Requests are defined that allow client programs to change which
-   physical devices are used as the core devices.
-
-1.3 Extension Input Devices
-
-   The input extension v1.x controls access to input devices other
-   than the X keyboard and X pointer. It allows client programs to
-   select input from these devices independently from each other
-   and independently from the core devices.
-
-   A client that wishes to access a specific device must first
-   determine whether that device is connected to the X server.
-   This is done through the ListInputDevices request, which will
-   return a list of all devices that can be opened by the X
-   server. A client can then open one or more of these devices
-   using the OpenDevice request, specify what events they are
-   interested in receiving, and receive and process input events
-   from extension devices in the same way as events from the X
-   keyboard and X pointer. Input events from these devices are of
-   extension types ( DeviceKeyPress, DeviceKeyRelease,
-   DeviceButtonPress, DeviceButtonRelease, DeviceMotionNotify,
-   etc.) and contain a device identifier so that events of the
-   same type coming from different input devices can be
-   distinguished.
-
-   Any kind of input device may be used as an extension input
-   device. Extension input devices may have 0 or more keys, 0 or
-   more buttons, and may report 0 or more axes of motion. Motion
-   may be reported as relative movements from a previous position
-   or as an absolute position. All valuators reporting motion
-   information for a given extension input device must report the
-   same kind of motion information (absolute or relative).
-
-   This extension is designed to accommodate new types of input
-   devices that may be added in the future. The protocol requests
-   that refer to specific characteristics of input devices
-   organize that information by input classes. Server implementors
-   may add new classes of input devices without changing the
-   protocol requests. Input classes are unique numbers registered
-   with the X Consortium. Each extension input device may support
-   multiple input classes.
-
-   In XI 1.x, all extension input devices are treated like the
-   core X keyboard in determining their location and focus. The
-   server does not track the location of these devices on an
-   individual basis, and therefore does not echo a cursor to
-   indicate their current location. Instead, their location is
-   determined by the location of the core X pointer. Like the core
-   X keyboard, some may be explicitly focused. If they are not
-   explicitly focused, their focus is determined by the location
-   of the core X pointer.
-
-   Most input events reported by the server to a client are of
-   fixed size (32 bytes). In order to represent the change in
-   state of an input device the extension may need to generate a
-   sequence of input events. A client side library (such as Xlib)
-   will typically take these raw input events and format them into
-   a form more convenient to the client.
-
-1.4 Event Classes
-
-   In the core protocol a client registers interest in receiving
-   certain input events directed to a window by modifying that
-   window's event-mask. Most of the bits in the event mask are
-   already used to specify interest in core X events. The input
-   extension specifies a different mechanism by which a client can
-   express interest in events generated by this extension.
-
-   When a client opens a extension input device via the OpenDevice
-   request, an XDevice structure is returned. Macros are provided
-   that extract 32-bit numbers called event classes from that
-   structure, that a client can use to register interest in
-   extension events via the SelectExtensionEvent request. The
-   event class combines the desired event type and device id, and
-   may be thought of as the equivalent of core event masks.
-
-1.5 Input Classes
-
-   Some of the input extension requests divide input devices into
-   classes based on their functionality. This is intended to allow
-   new classes of input devices to be defined at a later time
-   without changing the semantics of these requests. The following
-   input device classes are currently defined:
-
-   KEY
-          The device reports key events.
-
-   BUTTON
-          The device reports button events.
-
-   VALUATOR
-          The device reports valuator data in motion events.
-
-   PROXIMITY
-          The device reports proximity events.
-
-   FOCUS
-          The device can be focused and reports focus events.
-
-   FEEDBACK
-          The device supports feedbacks.
-
-   OTHER
-          The ChangeDeviceNotify, DeviceMappingNotify, and
-          DeviceStateNotify macros may be invoked passing the
-          XDevice structure returned for this device.
-
-   Each extension input device may support multiple input classes.
-   Additional classes may be added in the future. Requests that
-   support multiple input classes, such as the ListInputDevices
-   function that lists all available input devices, organize the
-   data they return by input class. Client programs that use these
-   requests should not access data unless it matches a class
-   defined at the time those clients were compiled. In this way,
-   new classes can be added without forcing existing clients that
-   use these requests to be recompiled.
-
-2. Requests
-
-   Extension input devices are accessed by client programs through
-   the use of new protocol requests. This section summarizes the
-   new requests defined by this extension. The syntax and type
-   definitions used below follow the notation used for the X11
-   core protocol.
-
-2.1 Getting the Extension Version
-
-   The GetExtensionVersion request returns version information
-   about the input extension.
-
-                       GetExtensionVersion
-                               name: STRING
-                       =>
-                               present: BOOL
-                               protocol-major-version: CARD16
-                               protocol-minor-version: CARD16
-
-   The protocol version numbers returned indicate the version of
-   the input extension supported by the target X server. The
-   version numbers can be compared to constants defined in the
-   header file XI.h. Each version is a superset of the previous
-   versions.
-
-   The name must be the name of the Input Extension as defined 
-   in the header file XI.h.
-
-2.2 Listing Available Devices
-
-   A client that wishes to access a specific device must first
-   determine whether that device is connected to the X server.
-   This is done through the ListInputDevices request, which will
-   return a list of all devices that can be opened by the X
-   server.
-
-                   ListInputDevices
-                   =>
-                   input-devices: ListOfDeviceInfo
-
-   where
-
-                   DEVICEINFO:
-                           [type: ATOM
-                            id: CARD8
-                            num_classes: CARD8
-                            use: {IsXKeyboard, IsXPointer, IsXExtensionPointer,
-                                  IsXExtensionKeyboard, IsExtensionDevice}
-                            info: LISTofINPUTINFO
-                            name: STRING8]
-
-                   INPUTINFO: {KEYINFO, BUTTONINFO, VALUATORINFO}
-                   KEYINFO:
-                           [class: CARD8
-                            length: CARD8
-                            min-keycode: KEYCODE
-                            max-keycode: KEYCODE
-                            num-keys: CARD16]
-                   BUTTONINFO:
-                           [class: CARD8
-                            length: CARD8
-                            num-buttons: CARD16]
-                   VALUATORINFO:
-                           [class: CARD8
-                            length: CARD8
-                            num_axes: CARD8
-                            mode: SETofDEVICEMODE
-                            motion_buffer_size: CARD32
-                            axes: LISTofAXISINFO]
-
-                   AXISINFO:
-                           [resolution: CARD32
-                            min-val: CARD32
-                            max-val: CARD32]
-                   DEVICEMODE: {Absolute, Relative}
-
-   Errors: None
-
-   This request returns a list of all devices that can be opened
-   by the X server, including the core X keyboard and X pointer.
-   Some implementations may open all input devices as part of X
-   initialization, while others may not open an input device until
-   requested to do so by a client program.
-
-   The information returned for each device is as follows:
-
-   type
-          The type field is of type Atom and indicates the nature
-          of the device. Clients may determine device types by
-          invoking the XInternAtom request passing one of the
-          names defined in the header file XI.h. The following
-          names have been defined to date:
-
-                                      MOUSE
-                                      TABLET
-                                      KEYBOARD
-                                      TOUCHSCREEN
-                                      TOUCHPAD
-                                      BUTTONBOX
-                                      BARCODE
-                                      KNOB_BOX
-                                      TRACKBALL
-                                      QUADRATURE
-                                      SPACEBALL
-                                      DATAGLOVE
-                                      EYETRACKER
-                                      CURSORKEYS
-                                      FOOTMOUSE
-                                      ID_MODULE
-                                      ONE_KNOB
-                                      NINE_KNOB
-                                      JOYSTICK
-
-
-   id
-          The id is a small cardinal value in the range 0-128 that
-          uniquely identifies the device. It is assigned to the
-          device when it is initialized by the server. Some
-          implementations may not open an input device until
-          requested by a client program, and may close the device
-          when the last client accessing it requests that it be
-          closed. If a device is opened by a client program via
-          XOpenDevice, then closed via XCloseDevice, then opened
-          again, it is not guaranteed to have the same id after
-          the second open request.
-
-   num_classes
-          The num_classes field is a small cardinal value in the
-          range 0-255 that specifies the number of input classes
-          supported by the device for which information is
-          returned by ListInputDevices. Some input classes, such
-          as class Focus and class Proximity do not have any
-          information to be returned by ListInputDevices.
-
-   use
-          The use field specifies how the device is currently
-          being used. If the value is IsXKeyboard, the device is
-          currently being used as the X keyboard. If the value is
-          IsXPointer, the device is currently being used as the X
-          pointer. If the value is IsXExtensionPointer, the device
-          is available for use as an extension pointer. If the value
-          is IsXExtensionKeyboard, the device is available for use as
-          and extension keyboard.
-          Older versions of XI report all extension devices as
-          IsXExtensionDevice.
-
-   name
-          The name field contains a pointer to a null-terminated
-          string that corresponds to one of the defined device
-          types.
-
-   InputInfo
-          InputInfo is one of: KeyInfo, ButtonInfo or
-          ValuatorInfo. The first two fields are common to all
-          three:
-
-        class
-                The class field is a cardinal value in the range
-                0-255. It uniquely identifies the class of input
-                for which information is returned.
-
-        length
-                The length field is a cardinal value in the range
-                0-255. It specifies the number of bytes of data
-                that are contained in this input class. The length
-                includes the class and length fields.
-
-          The remaining information returned for input class
-          KEYCLASS is as follows:
-
-        min_keycode
-                min_keycode is of type KEYCODE. It specifies the
-                minimum keycode that the device will report. The
-                minimum keycode will not be smaller than 8.
-
-        max_keycode
-                max_keycode is of type KEYCODE. It specifies the
-                maximum keycode that the device will report. The
-                maximum keycode will not be larger than 255.
-
-        num_keys
-                num_keys is a cardinal value that specifies the
-                number of keys that the device has.
-
-          The remaining information returned for input class
-          BUTTONCLASS is as follows:
-
-        num_buttons
-                num_buttons is a cardinal value that specifies the
-                number of buttons that the device has.
-
-          The remaining information returned for input class
-          VALUATORCLASS is as follows:
-
-        mode
-                mode is a constant that has one of the following
-                values: Absolute or Relative. Some devices allow
-                the mode to be changed dynamically via the
-                SetDeviceMode request.
-
-        motion_buffer_size
-                motion_buffer_size is a cardinal number that
-                specifies the number of elements that can be
-                contained in the motion history buffer for the
-                device.
-
-        axes
-                The axes field contains a pointer to an AXISINFO
-                struture.
-
-          The information returned for each axis reported by the
-          device is:
-
-        resolution
-                The resolution is a cardinal value in
-                counts/meter.
-
-        min_val
-                The min_val field is a cardinal value in that
-                contains the minimum value the device reports for
-                this axis. For devices whose mode is Relative, the
-                min_val field will contain 0.
-
-        max_val
-                The max_val field is a cardinal value in that
-                contains the maximum value the device reports for
-                this axis. For devices whose mode is Relative, the
-                max_val field will contain 0.
-
-2.3 Enabling Devices
-
-   Client programs that wish to access an extension device must
-   request that the server open that device. This is done via the
-   OpenDevice request.
-
-                   OpenDevice
-                           id: CARD8
-                   =>
-                   DEVICE:
-                           [device_id: XID
-                            num_classes: INT32
-                            classes: LISTofINPUTCLASSINFO]
-                   INPUTCLASSINFO:
-                            [input_class: CARD8
-                            event_type_base: CARD8]
-
-   Errors: Device
-
-   This request returns the event classes to be used by the client
-   to indicate which events the client program wishes to receive.
-   Each input class may report several event classes. For example,
-   input class Keys reports DeviceKeyPress and DeviceKeyRelease
-   event classes. Input classes are unique numbers registered with
-   the X Consortium. Input class Other exists to report event
-   classes that are not specific to any one input class, such as
-   DeviceMappingNotify, ChangeDeviceNotify, and DeviceStateNotify.
-
-   The information returned for each device is as follows:
-
-   device_id
-          The device_id is a number that uniquely identifies the
-          device.
-
-   num_classes
-          The num_classes field contains the number of input
-          classes supported by this device.
-
-   For each class of input supported by the device, the
-   InputClassInfo structure contains the following information:
-
-   input_class
-          The input_class is a small cardinal number that
-          identifies the class of input.
-
-   event_type_base
-          The event_type_base is a small cardinal number that
-          specifies the event type of one of the events reported
-          by this input class. This information is not directly
-          used by client programs. Instead, the Device is used by
-          macros that return extension event types and event
-          classes. This is described in the section of this
-          document entitled "Selecting Extension Device Events".
-
-   The information in the InputClassInfo reflects the state of
-   this device at the time the request was processed.
-
-   Before it exits, the client program should explicitly request
-   that the server close the device. This is done via the
-   CloseDevice request.
-
-   A client may open the same extension device more than once.
-   Requests after the first successful one return an additional
-   XDevice structure with the same information as the first, but
-   otherwise have no effect. A single CloseDevice request will
-   terminate that client's access to the device.
-
-   Closing a device releases any active or passive grabs the
-   requesting client has established. If the device is frozen only
-   by an active grab of the requesting client, the queued events
-   are released when the client terminates.
-
-   If a client program terminates without closing a device, the
-   server will automatically close that device on behalf of the
-   client. This does not affect any other clients that may be
-   accessing that device.
-
-                       CloseDevice:
-                               device: DEVICE
-
-   Errors: Device
-
-2.4 Changing The Mode Of A Device
-
-   Some devices are capable of reporting either relative or
-   absolute motion data. To change the mode of a device from
-   relative to absolute, use the SetDeviceMode request. The valid
-   values are Absolute or Relative.
-
-   This request will fail and return DeviceBusy if another client
-   already has the device open with a different mode. It will fail
-   and return AlreadyGrabbed if another client has the device
-   grabbed. The request will fail with a BadMatch error if the
-   device has no valuators and reports no axes of motion. The
-   request will fail with a BadMode error if the requested mode
-   is not supported by the device.
-
-                       SetDeviceMode
-                               device:DEVICE
-                               mode: {Absolute, Relative}
-                       =>
-                               status: {Success, DeviceBusy, AlreadyGrabbed}
-
-   Errors: Device, Match, Mode
-
-2.5 Initializing Valuators on an Input Device
-
-   Some devices that report absolute positional data can be
-   initialized to a starting value. Devices that are capable of
-   reporting relative motion or absolute positional data may
-   require that their valuators be initialized to a starting value
-   after the mode of the device is changed to Absolute. To
-   initialize the valuators on such a device, use the
-   SetDeviceValuators request.
-
-                   SetDeviceValuators
-                           device: DEVICE
-                           first_valuator: CARD8
-                           num_valuators: CARD8
-                           valuators: LISTOFINT32
-                   =>
-                           status: {Success, AlreadyGrabbed}
-
-   Errors: Length, Device, Match, Value
-
-   This request initializes the specified valuators on the
-   specified extension input device. Valuators are numbered
-   beginning with zero. Only the valuators in the range specified
-   by first_valuator and num_valuators are set. If the number of
-   valuators supported by the device is less than the expression
-   first_valuator + num_valuators, a Value error will result.
-
-   If the request succeeds, Success is returned. If the specifed
-   device is grabbed by some other client, the request will fail
-   and a status of AlreadyGrabbed will be returned.
-
-2.6 Getting Input Device Controls
-
-                   GetDeviceControl
-                           device: DEVICE
-                           control: XID
-                   =>
-                   controlState: {DeviceState}
-
-   where
-
-                   DeviceState: DeviceResolutionState
-
-   Errors: Length, Device, Match, Value
-
-   This request returns the current state of the specified device
-   control. The device control must be supported by the target
-   server and device or an error will result.
-
-   If the request is successful, a pointer to a generic
-   DeviceState structure will be returned. The information
-   returned varies according to the specified control and is
-   mapped by a structure appropriate for that control.
-
-   GetDeviceControl will fail with a BadValue error if the server
-   does not support the specified control. It will fail with a
-   BadMatch error if the device does not support the specified
-   control.
-
-   Supported device controls and the information returned for them
-   include:
-
-                   DEVICE_RESOLUTION:
-                       [control: CARD16
-                       length: CARD16
-                       num_valuators: CARD8
-                       resolutions: LISTofCARD32
-                       min_resolutions: LISTofCARD32
-                       max_resolutions: LISTofCARD32]
-
-   This device control returns a list of valuators and the range
-   of valid resolutions allowed for each. Valuators are numbered
-   beginning with 0. Resolutions for all valuators on the device
-   are returned. For each valuator i on the device, resolutions[i]
-   returns the current setting of the resolution,
-   min_resolutions[i] returns the minimum valid setting, and
-   max_resolutions[i] returns the maximum valid setting.
-
-   When this control is specified, XGetDeviceControl will fail
-   with a BadMatch error if the specified device has no valuators.
-
-                   ChangeDeviceControl:
-                           device: DEVICE
-                           XID: controlId
-                           control: DeviceControl
-
-   where
-
-                   DeviceControl: DeviceResolutionControl
-                   =>
-                           status: {Success, DeviceBusy, AlreadyGrabbed}
-
-   Errors: Length, Device, Match, Value
-
-   ChangeDeviceControl changes the specifed device control
-   according to the values specified in the DeviceControl
-   structure. The device control must be supported by the target
-   server and device or an error will result.
-
-   The information passed with this request varies according to
-   the specified control and is mapped by a structure appropriate
-   for that control.
-
-   ChangeDeviceControl will fail with a BadValue error if the
-   server does not support the specified control. It will fail
-   with a BadMatch error if the server supports the specified
-   control, but the requested device does not. The request will
-   fail and return a status of DeviceBusy if another client
-   already has the device open with a device control state that
-   conflicts with the one specified in the request. It will fail
-   with a status of AlreadyGrabbed if some other client has
-   grabbed the specified device. If the request succeeds, Success
-   is returned. If it fails, the device control is left unchanged.
-
-   Supported device controls and the information specified for
-   them include:
-
-                   DEVICE_RESOLUTION:
-                           [control: CARD16
-                            length: CARD16
-                            first_valuator: CARD8
-                            num_valuators: CARD8
-                            resolutions: LISTofCARD32]
-
-   This device control changes the resolution of the specified
-   valuators on the specified extension input device. Valuators
-   are numbered beginning with zero. Only the valuators in the
-   range specified by first_valuator and num_valuators are set. A
-   value of -1 in the resolutions list indicates that the
-   resolution for this valuator is not to be changed.
-   num_valuators specifies the number of valuators in the
-   resolutions list.
-
-   When this control is specified, XChangeDeviceControl will fail
-   with a BadMatch error if the specified device has no valuators.
-   If a resolution is specified that is not within the range of
-   valid values (as returned by XGetDeviceControl) the request
-   will fail with a BadValue error. If the number of valuators
-   supported by the device is less than the expression
-   first_valuator + num_valuators, a BadValue error will result.
-
-   If the request fails for any reason, none of the valuator
-   resolutions will be changed.
-
-   ChangeDeviceControl causes the server to send a DevicePresence
-   event to interested clients.
-
-2.7 Selecting Extension Device Events
-
-   Extension input events are selected using the
-   SelectExtensionEvent request.
-
-                   SelectExtensionEvent
-                           interest: LISTofEVENTCLASS
-                           window: WINDOW
-
-   Errors: Window, Class, Access
-
-   This request specifies to the server the events within the
-   specified window which are of interest to the client. As with
-   the core XSelectInput function, multiple clients can select
-   input on the same window.
-
-   XSelectExtensionEvent requires a list of event classes. An
-   event class is a 32-bit number that combines an event type and
-   device id, and is used to indicate which event a client wishes
-   to receive and from which device it wishes to receive it.
-   Macros are provided to obtain event classes from the data
-   returned by the XOpenDevice request. The names of these macros
-   correspond to the desired events, i.e. the DeviceKeyPress is
-   used to obtain the event class for DeviceKeyPress events. The
-   syntax of the macro invocation is:
-                    DeviceKeyPress (device, event_type, event_class);
-                        device: DEVICE
-                        event_type: INT
-                        event_class: INT
-
-   The value returned in event_type is the value that will be
-   contained in the event type field of the XDeviceKeyPressEvent
-   when it is received by the client. The value returned in
-   event_class is the value that should be passed in making an
-   XSelectExtensionEvent request to receive DeviceKeyPress events.
-
-   For DeviceButtonPress events, the client may specify whether or
-   not an implicit passive grab should be done when the button is
-   pressed. If the client wants to guarantee that it will receive
-   a DeviceButtonRelease event for each DeviceButtonPress event it
-   receives, it should specify the DeviceButtonPressGrab event
-   class as well as the DeviceButtonPress event class. This
-   restricts the client in that only one client at a time may
-   request DeviceButtonPress events from the same device and
-   window if any client specifies this class.
-
-   If any client has specified the DeviceButtonPressGrab class,
-   any requests by any other client that specify the same device
-   and window and specify DeviceButtonPress or
-   DeviceButtonPressGrab will cause an Access error to be
-   generated.
-
-   If only the DeviceButtonPress class is specified, no implicit
-   passive grab will be done when a button is pressed on the
-   device. Multiple clients may use this class to specify the same
-   device and window combination.
-
-   A client may also specify the DeviceOwnerGrabButton class. If
-   it has specified both the DeviceButtonPressGrab and the
-   DeviceOwnerGrabButton classes, implicit passive grabs will
-   activate with owner_events set to True. If only the
-   DeviceButtonPressGrab class is specified, implicit passive
-   grabs will activate with owner_events set to False.
-
-   The client may select DeviceMotion events only when a button is
-   down. It does this by specifying the event classes
-   Button1Motion through Button5Motion, or ButtonMotion. An input
-   device will only support as many button motion classes as it
-   has buttons.
-
-2.8 Determining Selected Events
-
-   To determine which extension events are currently selected from
-   a given window, use GetSelectedExtensionEvents.
-
-                   GetSelectedExtensionEvents
-                           window: WINDOW
-                   =>
-                           this-client: LISTofEVENTCLASS
-                           all-clients: LISTofEVENTCLASS
-
-   Errors: Window
-
-   This request returns two lists specifying the events selected
-   on the specified window. One list gives the extension events
-   selected by this client from the specified window. The other
-   list gives the extension events selected by all clients from
-   the specified window. This information is equivalent to that
-   returned by your-event-mask and all-event-masks in a
-   GetWindowAttributes request.
-
-2.9 Controlling Event Propagation
-
-   Extension events propagate up the window hierarchy in the same
-   manner as core events. If a window is not interested in an
-   extension event, it usually propagates to the closest ancestor
-   that is interested, unless the dont_propagate list prohibits
-   it. Grabs of extension devices may alter the set of windows
-   that receive a particular extension event.
-
-   Client programs may control extension event propagation through
-   the use of the following two requests.
-
-   XChangeDeviceDontPropagateList adds an event to or deletes an
-   event from the do_not_propagate list of extension events for
-   the specified window. This list is maintained for the life of
-   the window, and is not altered if the client terminates.
-
-                   ChangeDeviceDontPropagateList
-                           window: WINDOW
-                           eventclass: LISTofEVENTCLASS
-                           mode: {AddToList, DeleteFromList}
-
-   Errors: Window, Class, Mode
-
-   This function modifies the list specifying the events that are
-   not propagated to the ancestors of the specified window. You
-   may use the modes AddToList or DeleteFromList.
-
-                   GetDeviceDontPropagateList
-                           window: WINDOW
-                           Errors: Window
-                   =>
-                           dont-propagate-list: LISTofEVENTCLASS
-
-   This function returns a list specifying the events that are not
-   propagated to the ancestors of the specified window.
-
-2.10 Sending Extension Events
-
-   One client program may send an event to another via the
-   XSendExtensionEvent function.
-
-   The event in the XEvent structure must be one of the events
-   defined by the input extension, so that the X server can
-   correctly byte swap the contents as necessary. The contents of
-   the event are otherwise unaltered and unchecked by the X server
-   except to force send_event to True in the forwarded event and
-   to set the sequence number in the event correctly.
-
-   XSendExtensionEvent returns zero if the conversion-to-wire
-   protocol failed, otherwise it returns nonzero.
-
-                   SendExtensionEvent
-                           device: DEVICE
-                           destination: WINDOW
-                           propagate: BOOL
-                           eventclass: LISTofEVENTCLASS
-                           event: XEVENT
-
-   Errors: Device, Value, Class, Window
-
-2.11 Getting Motion History
-
-                   GetDeviceMotionEvents
-                           device: DEVICE
-                           start, stop: TIMESTAMP or CurrentTime
-                   =>
-                           nevents_return: CARD32
-                           mode_return: {Absolute, Relative}
-                           axis_count_return: CARD8
-                           events: LISTofDEVICETIMECOORD
-
-   where
-
-                   DEVICETIMECOORD:
-                           [data: LISTofINT32
-                            time: TIMESTAMP]
-
-   Errors: Device, Match
-
-   This request returns all positions in the device's motion
-   history buffer that fall between the specified start and stop
-   times inclusive. If the start time is in the future, or is
-   later than the stop time, no positions are returned.
-
-   The data field of the DEVICETIMECOORD structure is a sequence
-   of data items. Each item is of type INT32, and there is one
-   data item per axis of motion reported by the device. The number
-   of axes reported by the device is returned in the axis_count
-   variable.
-
-   The value of the data items depends on the mode of the device,
-   which is returned in the mode variable. If the mode is
-   Absolute, the data items are the raw values generated by the
-   device. These may be scaled by the client program using the
-   maximum values that the device can generate for each axis of
-   motion that it reports. The maximum and minimum values for each
-   axis are reported by the ListInputDevices request.
-
-   If the mode is Relative, the data items are the relative values
-   generated by the device. The client program must choose an
-   initial position for the device and maintain a current position
-   by accumulating these relative values.
-
-2.12 Changing The Core Devices
-
-   These requests are provided to change which physical device is
-   used as the X pointer or X keyboard. These requests are
-   deprecated in servers supporting XI 1.4 and above, and will
-   always return a a BadDevice error.
-
-   Using these requests may change the characteristics of the core
-   devices. The new pointer device may have a different number of
-   buttons than the old one did, or the new keyboard device may
-   have a different number of keys or report a different range of
-   keycodes. Client programs may be running that depend on those
-   characteristics. For example, a client program could allocate
-   an array based on the number of buttons on the pointer device,
-   and then use the button numbers received in button events as
-   indicies into that array. Changing the core devices could cause
-   such client programs to behave improperly or abnormally
-   terminate.
-
-   These requests change the X keyboard or X pointer device and
-   generate an ChangeDeviceNotify event and a MappingNotify event.
-   The ChangeDeviceNotify event is sent only to those clients that
-   have expressed an interest in receiving that event via the
-   XSelectExtensionEvent request. The specified device becomes the
-   new X keyboard or X pointer device. The location of the core
-   device does not change as a result of this request.
-
-   These requests fail and return AlreadyGrabbed if either the
-   specified device or the core device it would replace are
-   grabbed by some other client. They fail and return GrabFrozen
-   if either device is frozen by the active grab of another
-   client.
-
-   These requests fail with a BadDevice error if the specified
-   device is invalid, or has not previously been opened via
-   OpenDevice. To change the X keyboard device, use the
-   ChangeKeyboardDevice request. The specified device must support
-   input class Keys (as reported in the ListInputDevices request)
-   or the request will fail with a BadMatch error. Once the device
-   has successfully replaced one of the core devices, it is
-   treated as a core device until it is in turn replaced by
-   another ChangeDevice request, or until the server terminates.
-   The termination of the client that changed the device will not
-   cause it to change back. Attempts to use the CloseDevice
-   request to close the new core device will fail with a BadDevice
-   error.
-
-   The focus state of the new keyboard is the same as the focus
-   state of the old X keyboard. If the new keyboard was not
-   initialized with a FocusRec, one is added by the
-   ChangeKeyboardDevice request. The X keyboard is assumed to have
-   a KbdFeedbackClassRec. If the device was initialized without a
-   KbdFeedbackClassRec, one will be added by this request. The
-   KbdFeedbackClassRec will specify a null routine as the control
-   procedure and the bell procedure.
-
-                   ChangeKeyboardDevice
-                           device: DEVICE
-                           Errors: Device, Match
-                   =>
-                           status: Success, AlreadyGrabbed, Frozen
-
-   To change the X pointer device, use the ChangePointerDevice
-   request. The specified device must support input class
-   Valuators (as reported in the ListInputDevices request) or the
-   request will fail with a BadMatch error. The valuators to be
-   used as the x- and y-axes of the pointer device must be
-   specified. Data from other valuators on the device will be
-   ignored.
-
-   The X pointer device does not contain a FocusRec. If the new
-   pointer was initialized with a FocusRec, it is freed by the
-   ChangePointerDevice request. The X pointer is assumed to have a
-   ButtonClassRec and a PtrFeedbackClassRec. If the device was
-   initialized without a ButtonClassRec or a PtrFeedbackClassRec,
-   one will be added by this request. The ButtonClassRec added
-   will have no buttons, and the PtrFeedbackClassRec will specify
-   a null routine as the control procedure.
-
-   If the specified device reports absolute positional
-   information, and the server implementation does not allow such
-   a device to be used as the X pointer, the request will fail
-   with a BadDevice error.
-
-   Once the device has successfully replaced one of the core
-   devices, it is treated as a core device until it is in turn
-   replaced by another ChangeDevice request, or until the server
-   terminates. The termination of the client that changed the
-   device will not cause it to change back. Attempts to use the
-   CloseDevice request to close the new core device will fail with
-   a BadDevice error.
-
-                   ChangePointerDevice
-                           device: DEVICE
-                           xaxis: CARD8
-                           yaxis: CARD8
-                   =>
-                           status: Success, AlreadyGrabbed, Frozen
-
-   Errors: Device, Match
-
-2.12 Event Synchronization And Core Grabs
-
-   Implementation of the input extension requires an extension of
-   the meaning of event synchronization for the core grab
-   requests. This is necessary in order to allow window managers
-   to freeze all input devices with a single request.
-
-   The core grab requests require a pointer_mode and keyboard_mode
-   argument. The meaning of these modes is changed by the input
-   extension. For the XGrabPointer and XGrabButton requests,
-   pointer_mode controls synchronization of the pointer device,
-   and keyboard_mode controls the synchronization of all other
-   input devices. For the XGrabKeyboard and XGrabKey requests,
-   pointer_mode controls the synchronization of all input devices
-   except the X keyboard, while keyboard_mode controls the
-   synchronization of the keyboard. When using one of the core
-   grab requests, the synchronization of extension devices is
-   controlled by the mode specified for the device not being
-   grabbed.
-
-2.13 Extension Active Grabs
-
-   Active grabs of extension devices are supported via the
-   GrabDevice request in the same way that core devices are
-   grabbed using the core GrabKeyboard request, except that a
-   Device is passed as a function parameter. A list of events that
-   the client wishes to receive is also passed. The UngrabDevice
-   request allows a previous active grab for an extension device
-   to be released.
-
-   To grab an extension device, use the GrabDevice request. The
-   device must have previously been opened using the OpenDevice
-   request.
-
-                   GrabDevice
-                           device: DEVICE
-                           grab-window: WINDOW
-                           owner-events: BOOL
-                           event-list: LISTofEVENTCLASS
-                           this-device-mode: {Synchronous, Asynchronous}
-                           other-device-mode: {Synchronous, Asynchronous}
-                           time:TIMESTAMP or CurrentTime
-                   =>
-                           status: Success, AlreadyGrabbed, Frozen,
-                                   InvalidTime, NotViewable
-
-   Errors: Device, Window, Value
-
-   This request actively grabs control of the specified input
-   device. Further input events from this device are reported only
-   to the grabbing client. This request overrides any previous
-   active grab by this client for this device.
-
-   The event-list parameter is a pointer to a list of event
-   classes. These are used to indicate which events the client
-   wishes to receive while the device is grabbed. Only event
-   classes obtained from the grabbed device are valid.
-
-   If owner-events is False, input events generated from this
-   device are reported with respect to grab-window, and are only
-   reported if selected by being included in the event-list. If
-   owner-events is True, then if a generated event would normally
-   be reported to this client, it is reported normally, otherwise
-   the event is reported with respect to the grab-window, and is
-   only reported if selected by being included in the event-list.
-   For either value of owner-events, unreported events are
-   discarded.
-
-   If this-device-mode is Asynchronous, device event processing
-   continues normally. If the device is currently frozen by this
-   client, then processing of device events is resumed. If
-   this-device-mode is Synchronous, the state of the grabbed
-   device (as seen by means of the protocol) appears to freeze,
-   and no further device events are generated by the server until
-   the grabbing client issues a releasing AllowDeviceEvents
-   request or until the device grab is released. Actual device
-   input events are not lost while the device is frozen; they are
-   simply queued for later processing.
-
-   If other-device-mode is Asynchronous, event processing is
-   unaffected by activation of the grab. If other-device-mode is
-   Synchronous, the state of all input devices except the grabbed
-   one (as seen by means of the protocol) appears to freeze, and
-   no further events are generated by the server until the
-   grabbing client issues a releasing AllowDeviceEvents request or
-   until the device grab is released. Actual events are not lost
-   while the devices are frozen; they are simply queued for later
-   processing.
-
-   This request generates DeviceFocusIn and DeviceFocusOut events.
-
-   This request fails and returns:
-
-   AlreadyGrabbed
-          If the device is actively grabbed by some other client.
-
-   NotViewable
-          If grab-window is not viewable.
-
-   InvalidTime
-          If the specified time is earlier than the last-grab-time
-          for the specified device or later than the current X
-          server time. Otherwise, the last-grab-time for the
-          specified device is set to the specified time and
-          CurrentTime is replaced by the current X server time.
-
-   Frozen
-          If the device is frozen by an active grab of another
-          client.
-
-   If a grabbed device is closed by a client while an active grab
-   by that client is in effect, that active grab will be released.
-   Any passive grabs established by that client will be released.
-   If the device is frozen only by an active grab of the
-   requesting client, it is thawed.
-
-   To release a grab of an extension device, use UngrabDevice.
-
-                   UngrabDevice
-                           device: DEVICE
-                           time: TIMESTAMP or CurrentTime
-
-   Errors: Device
-
-   This request releases the device if this client has it actively
-   grabbed (from either GrabDevice or GrabDeviceKey) and releases
-   any queued events. If any devices were frozen by the grab,
-   UngrabDevice thaws them. The request has no effect if the
-   specified time is earlier than the last-device-grab time or is
-   later than the current server time.
-
-   This request generates DeviceFocusIn and DeviceFocusOut events.
-
-   An UngrabDevice is performed automatically if the event window
-   for an active device grab becomes not viewable.
-
-2.14 Passively Grabbing A Key
-
-   Passive grabs of buttons and keys on extension devices are
-   supported via the GrabDeviceButton and GrabDeviceKey requests.
-   These passive grabs are released via the UngrabDeviceKey and
-   UngrabDeviceButton requests.
-
-   To passively grab a single key on an extension device, use
-   GrabDeviceKey. That device must have previously been opened
-   using the OpenDevice request.
-
-                   GrabDeviceKey
-                           device: DEVICE
-                           keycode: KEYCODE or AnyKey
-                           modifiers: SETofKEYMASK or AnyModifier
-                           modifier-device: DEVICE or NULL
-                           grab-window: WINDOW
-                           owner-events: BOOL
-                           event-list: LISTofEVENTCLASS
-                           this-device-mode: {Synchronous, Asynchronous}
-                           other-device-mode: {Synchronous, Asynchronous}
-
-   Errors: Device, Match, Access, Window, Value
-
-   This request is analogous to the core GrabKey request. It
-   establishes a passive grab on a device. Consequently, in the
-   future:
-     * IF the device is not grabbed and the specified key, which
-       itself can be a modifier key, is logically pressed when the
-       specified modifier keys logically are down on the specified
-       modifier device (and no other keys are down),
-     * AND no other modifier keys logically are down,
-     * AND EITHER the grab window is an ancestor of (or is) the
-       focus window OR the grab window is a descendent of the
-       focus window and contains the pointer,
-     * AND a passive grab on the same device and key combination
-       does not exist on any ancestor of the grab window,
-     * THEN the device is actively grabbed, as for GrabDevice, the
-       last-device-grab time is set to the time at which the key
-       was pressed (as transmitted in the DeviceKeyPress event),
-       and the DeviceKeyPress event is reported.
-
-   The interpretation of the remaining arguments is as for
-   GrabDevice. The active grab is terminated automatically when
-   logical state of the device has the specified key released
-   (independent of the logical state of the modifier keys).
-
-   Note that the logical state of a device (as seen by means of
-   the X protocol) may lag the physical state if device event
-   processing is frozen.
-
-   A modifier of AnyModifier is equivalent to issuing the request
-   for all possible modifier combinations (including the
-   combination of no modifiers). It is not required that all
-   modifiers specified have currently assigned keycodes. A key of
-   AnyKey is equivalent to issuing the request for all possible
-   keycodes. Otherwise, the key must be in the range specified by
-   min-keycode and max-keycode in the ListInputDevices request. If
-   it is not within that range, GrabDeviceKey generates a Value
-   error.
-
-   NULL may be passed for the modifier_device. If the
-   modifier_device is NULL, the core X keyboard is used as the
-   modifier_device.
-
-   An Access error is generated if some other client has issued a
-   GrabDeviceKey with the same device and key combination on the
-   same window. When using AnyModifier or AnyKey, the request
-   fails completely and the X server generates a Access error and
-   no grabs are established if there is a conflicting grab for any
-   combination.
-
-   This request cannot be used to grab a key on the X keyboard
-   device. The core GrabKey request should be used for that
-   purpose.
-
-   To release a passive grab of a single key on an extension
-   device, use UngrabDeviceKey.
-
-                   UngrabDeviceKey
-                           device: DEVICE
-                           keycode: KEYCODE or AnyKey
-                           modifiers: SETofKEYMASK or AnyModifier
-                           modifier-device: DEVICE or NULL
-                           grab-window: WINDOW
-
-   Errors: Device, Match, Window, Value, Alloc
-
-   This request is analogous to the core UngrabKey request. It
-   releases the key combination on the specified window if it was
-   grabbed by this client. A modifier of AnyModifier is equivalent
-   to issuing the request for all possible modifier combinations
-   (including the combination of no modifiers). A key of AnyKey is
-   equivalent to issuing the request for all possible keycodes.
-   This request has no effect on an active grab.
-
-   NULL may be passed for the modifier_device. If the
-   modifier_device is NULL, the core X keyboard is used as the
-   modifier_device.
-
-2.15 Passively Grabbing A Button
-
-   To establish a passive grab for a single button on an extension
-   device, use GrabDeviceButton.
-
-                   GrabDeviceButton
-                           device: DEVICE
-                           button: BUTTON or AnyButton
-                           modifiers: SETofKEYMASK or AnyModifier
-                           modifier-device: DEVICE or NULL
-                           grab-window: WINDOW
-                           owner-events: BOOL
-                           event-list: LISTofEVENTCLASS
-                           this-device-mode: {Synchronous, Asynchr
-   onous}
-                           other-device-mode: {Synchronous, Asynch
-   ronous}
-
-   Errors: Device, Match, Window, Access, Value
-
-   This request is analogous to the core GrabButton request. It
-   establishes an explicit passive grab for a button on an
-   extension input device. Since the server does not track
-   extension devices, no cursor is specified with this request.
-   For the same reason, there is no confine-to parameter. The
-   device must have previously been opened using the OpenDevice
-   request.
-
-   The GrabDeviceButton request establishes a passive grab on a
-   device. Consequently, in the future,
-
-   •
-          IF the device is not grabbed and the specified button is
-          logically pressed when the specified modifier keys
-          logically are down (and no other buttons or modifier
-          keys are down),
-
-   •
-          AND the grab window contains the device,
-
-   •
-          AND a passive grab on the same device and button/ key
-          combination does not exist on any ancestor of the grab
-          window,
-
-   •
-          THEN the device is actively grabbed, as for GrabDevice,
-          the last-grab time is set to the time at which the
-          button was pressed (as transmitted in the
-          DeviceButtonPress event), and the DeviceButtonPress
-          event is reported.
-
-   The interpretation of the remaining arguments is as for
-   GrabDevice. The active grab is terminated automatically when
-   logical state of the device has all buttons released
-   (independent of the logical state of the modifier keys).
-
-   Note that the logical state of a device (as seen by means of
-   the X protocol) may lag the physical state if device event
-   processing is frozen.
-
-   A modifier of AnyModifier is equivalent to issuing the request
-   for all possible modifier combinations (including the
-   combination of no modifiers). It is not required that all
-   modifiers specified have currently assigned keycodes. A button
-   of AnyButton is equivalent to issuing the request for all
-   possible buttons. It is not required that the specified button
-   be assigned to a physical button.
-
-   NULL may be passed for the modifier_device. If the
-   modifier_device is NULL, the core X keyboard is used as the
-   modifier_device.
-
-   An Access error is generated if some other client has issued a
-   GrabDeviceButton with the same device and button combination on
-   the same window. When using AnyModifier or AnyButton, the
-   request fails completely and the X server generates a Access
-   error and no grabs are established if there is a conflicting
-   grab for any combination. The request has no effect on an
-   active grab.
-
-   This request cannot be used to grab a button on the X pointer
-   device. The core GrabButton request should be used for that
-   purpose.
-
-   To release a passive grab of a button on an extension device,
-   use UngrabDeviceButton.
-
-                   UngrabDeviceButton
-                           device: DEVICE
-                           button: BUTTON or AnyButton
-                           modifiers: SETofKEYMASK or AnyModifier
-                           modifier-device: DEVICE or NULL
-                           grab-window: WINDOW
-
-   Errors: Device, Match, Window, Value, Alloc
-
-   This request is analogous to the core UngrabButton request. It
-   releases the passive button/key combination on the specified
-   window if it was grabbed by the client. A modifiers of
-   AnyModifier is equivalent to issuing the request for all
-   possible modifier combinations (including the combination of no
-   modifiers). A button of AnyButton is equivalent to issuing the
-   request for all possible buttons. This request has no effect on
-   an active grab. The device must have previously been opened
-   using the OpenDevice request otherwise a Device error will be
-   generated.
-
-   NULL may be passed for the modifier_device. If the
-   modifier_device is NULL, the core X keyboard is used as the
-   modifier_device.
-
-   This request cannot be used to ungrab a button on the X pointer
-   device. The core UngrabButton request should be used for that
-   purpose.
-
-2.16 Thawing A Device
-
-   To allow further events to be processed when a device has been
-   frozen, use AllowDeviceEvents.
-
-                   AllowDeviceEvents
-                           device: DEVICE
-                           event-mode: {AsyncThisDevice, SyncThisD
-   evice, AsyncOtherDevices,
-                           ReplayThisdevice, AsyncAll, or SyncAll}
-                           time:TIMESTAMP or CurrentTime
-
-   Errors: Device, Value
-
-   The AllowDeviceEvents request releases some queued events if
-   the client has caused a device to freeze. The request has no
-   effect if the specified time is earlier than the last-grab time
-   of the most recent active grab for the client, or if the
-   specified time is later than the current X server time.
-
-   The following describes the processing that occurs depending on
-   what constant you pass to the event-mode argument:
-
-   * If the specified device is frozen by the client, event
-     processing for that device continues as usual. If the
-     device is frozen multiple times by the client on behalf
-     of multiple separate grabs, AsyncThisDevice thaws for
-     all. AsyncThisDevice has no effect if the specified
-     device is not frozen by the client, but the device need
-     not be grabbed by the client.
-
-   * If the specified device is frozen and actively grabbed
-     by the client, event processing for that device
-     continues normally until the next button or key event is
-     reported to the client. At this time, the specified
-     device again appears to freeze. However, if the reported
-     event causes the grab to be released, the specified
-     device does not freeze. SyncThisDevice has no effect if
-     the specified device is not frozen by the client or is
-     not grabbed by the client.
-
-   * If the specified device is actively grabbed by the
-     client and is frozen as the result of an event having
-     been sent to the client (either from the activation of a
-     GrabDeviceButton or from a previous AllowDeviceEvents
-     with mode SyncThisDevice, but not from a Grab), the grab
-     is released and that event is completely reprocessed.
-     This time, however, the request ignores any passive
-     grabs at or above (towards the root) the grab-window of
-     the grab just released. The request has no effect if the
-     specified device is not grabbed by the client or if it
-     is not frozen as the result of an event.
-
-   * If the remaining devices are frozen by the client, event
-     processing for them continues as usual. If the other
-     devices are frozen multiple times by the client on
-     behalf of multiple separate grabs, AsyncOtherDevices
-     “thaws” for all. AsyncOtherDevices has no effect if the
-     devices are not frozen by the client, but those devices
-     need not be grabbed by the client.
-
-   * If all devices are frozen by the client, event
-     processing (for all devices) continues normally until
-     the next button or key event is reported to the client
-     for a grabbed device (button event for the grabbed
-     device, key or motion event for the device), at which
-     time the devices again appear to freeze. However, if the
-     reported event causes the grab to be released, then the
-     devices do not freeze (but if any device is still
-     grabbed, then a subsequent event for it will still cause
-     all devices to freeze). SyncAll has no effect unless all
-     devices are frozen by the client. If any device is
-     frozen twice by the client on behalf of two separate
-     grabs, SyncAll "thaws" for both (but a subsequent freeze
-     for SyncAll will only freeze each device once).
-
-   * If all devices are frozen by the client, event
-     processing (for all devices) continues normally. If any
-     device is frozen multiple times by the client on behalf
-     of multiple separate grabs, AsyncAll "thaws" for all.
-     AsyncAll has no effect unless all devices are frozen by
-     the client.
-
-     AsyncThisDevice, SyncThisDevice, and ReplayThisDevice
-     have no effect on the processing of events from the
-     remaining devices. AsyncOtherDevices has no effect on
-     the processing of events from the specified device. When
-     the event_mode is SyncAll or AsyncAll, the device
-     parameter is ignored.
-
-     It is possible for several grabs of different devices
-     (by the same or different clients) to be active
-     simultaneously. If a device is frozen on behalf of any
-     grab, no event processing is performed for the device.
-     It is possible for a single device to be frozen because
-     of several grabs. In this case, the freeze must be
-     released on behalf of each grab before events can again
-     be processed.
-
-2.17 Controlling Device Focus
-
-   The current focus window for an extension input device can be
-   determined using the GetDeviceFocus request. Extension devices
-   are focused using the SetDeviceFocus request in the same way
-   that the keyboard is focused using the SetInputFocus request,
-   except that a device is specified as part of the request. One
-   additional focus state, FollowKeyboard, is provided for
-   extension devices.
-
-   To get the current focus state, revert state, and focus time of
-   an extension device, use GetDeviceFocus.
-
-                   GetDeviceFocus
-                           device: DEVICE
-                   =>
-                           focus: WINDOW, PointerRoot, FollowKeyboard, or None
-                           revert-to: Parent, PointerRoot, FollowKeyboard, or None
-                           focus-time: TIMESTAMP
-
-   Errors: Device, Match
-
-   This request returns the current focus state, revert-to state,
-   and last-focus-time of an extension device.
-
-   To set the focus of an extension device, use SetDeviceFocus.
-
-                   SetDeviceFocus
-                           device: DEVICE
-                           focus: WINDOW, PointerRoot, FollowKeyboard, or None
-                           revert-to: Parent, PointerRoot, FollowKeyboard, or None
-                           focus-time: TIMESTAMP
-
-   Errors: Device, Window, Value, Match
-
-   This request changes the focus for an extension input device
-   and the last-focus-change-time. The request has no effect if
-   the specified time is earlier than the last-focus-change-time
-   or is later than the current X server time. Otherwise, the
-   last-focus-change-time is set to the specified time, with
-   CurrentTime replaced by the current server time.
-
-   The action taken by the server when this request is requested
-   depends on the value of the focus argument:
-
-   * If the focus argument is None, all input events from
-     this device will be discarded until a new focus window
-     is set. In this case, the revert-to argument is ignored.
-
-   * If a window ID is assigned to the focus argument, it
-     becomes the focus window of the device. If an input
-     event from the device would normally be reported to this
-     window or to one of its inferiors, the event is reported
-     normally. Otherwise, the event is reported relative to
-     the focus window.
-
-   * If you assign PointerRoot to the focus argument, the
-     focus window is dynamically taken to be the root window
-     of whatever screen the pointer is on at each input
-     event. In this case, the revert-to argument is ignored.
-
-   * If you assign FollowKeyboard to the focus argument, the
-     focus window is dynamically taken to be the same as the
-     focus of the X keyboard at each input event.
-
-     The specified focus window must be viewable at the time
-     of the request (else a Match error). If the focus window
-     later becomes not viewable, the X server evaluates the
-     revert-to argument to determine the new focus window.
-
-   * If you assign RevertToParent to the revert-to argument,
-     the focus reverts to the parent (or the closest viewable
-     ancestor), and the new revert-to value is taken to be
-     RevertToNone.
-
-   * If you assign RevertToPointerRoot,
-     RevertToFollowKeyboard, or RevertToNone to the revert-to
-     argument, the focus reverts to that value.
-
-   When the focus reverts, the X server generates DeviceFocusIn
-   and DeviceFocusOut events, but the last-focus-change time is
-   not affected.
-
-   This request causes the X server to generate DeviceFocusIn and
-   DeviceFocusOut events.
-
-2.18 Controlling Device Feedback
-
-   To get the settings of feedbacks on an extension device, use
-   GetFeedbackControl. This request provides functionality
-   equivalent to the core GetKeyboardControl and GetPointerControl
-   functions. It also provides a way to control displays
-   associated with an input device that are capable of displaying
-   an integer or string.
-
-                   GetFeedbackControl
-                           device: DEVICE
-                   =>
-                           num_feedbacks_return: CARD16
-                           return_value: LISTofFEEDBACKSTATE
-
-   where
-
-                       FEEDBACKSTATE: {KbdFeedbackState, PtrFeedbackState,
-                                       IntegerFeedbackState, StringFeedbackState,
-                                       BellFeedbackState, LedFeedbackState}
-
-   Feedbacks are reported by class. Those feedbacks that are
-   reported for the core keyboard device are in class KbdFeedback,
-   and are returned in the KbdFeedbackState structure. The members
-   of that structure are as follows:
-
-                   CLASS Kbd:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            key_click_percent: CARD8
-                            bell_percent: CARD8
-                            bell_pitch: CARD16
-                            bell_duration: CARD16
-                            led_value: BITMASK
-                            global_auto_repeat: {AutoRepeatModeOn, AutoRepeatModeOff}
-                            auto_repeats: LISTofCARD8]
-
-   Those feedbacks that are equivalent to those reported for the
-   core pointer are in feedback class PtrFeedback and are reported
-   in the PtrFeedbackState structure. The members of that
-   structure are:
-
-                   CLASS Ptr:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            accelNumerator: CARD16
-                            accelDenominator: CARD16
-                            threshold: CARD16]
-
-   Some input devices provide a means of displaying an integer.
-   Those devices will support feedback class IntegerFeedback,
-   which is reported in the IntegerFeedbackState structure. The
-   members of that structure are:
-
-                     CLASS Integer:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            resolution: CARD32
-                            min-val: INT32
-                            max-val: INT32]
-
-   Some input devices provide a means of displaying a string.
-   Those devices will support feedback class StringFeedback, which
-   is reported in the StringFeedbackState structure. The members
-   of that structure are:
-
-                     CLASS String:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            max_symbols: CARD16
-                            num_keysyms_supported: CARD16
-                            keysyms_supported: LISTofKEYSYM]
-
-   Some input devices contain a bell. Those devices will support
-   feedback class BellFeedback, which is reported in the
-   BellFeedbackState structure. The members of that structure are:
-
-                     CLASS String:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            percent: CARD8
-                            pitch: CARD16
-                            duration: CARD16]
-
-   The percent sets the base volume for the bell between 0 (off)
-   and 100 (loud) inclusive, if possible. Setting to -1 restores
-   the default. Other negative values generate a Value error.
-
-   The pitch sets the pitch (specified in Hz) of the bell, if
-   possible. Setting to -1 restores the default. Other negative
-   values generate a Value error.
-
-   The duration sets the duration (specified in milliseconds) of
-   the bell, if possible. Setting to -1 restores the default.
-   Other negative values generate a Value error.
-
-   A bell generator connected with the console but not directly on
-   the device is treated as if it were part of the device. Some
-   input devices contain LEDs. Those devices will support feedback
-   class Led, which is reported in the LedFeedbackState structure.
-   The members of that structure are:
-
-                     CLASS String:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            led_mask: BITMASK
-                            led_value: BITMASK]
-
-   Each bit in led_mask indicates that the corresponding led is
-   supported by the feedback. At most 32 LEDs per feedback are
-   supported. No standard interpretation of LEDs is defined.
-
-   This function will fail with a BadMatch error if the device
-   specified in the request does not support feedbacks.
-
-   Errors: Device, Match
-
-   To change the settings of a feedback on an extension device,
-   use ChangeFeedbackControl.
-
-                   ChangeFeedbackControl
-                           device: DEVICE
-                           feedbackid: CARD8
-                           value-mask: BITMASK
-                           value: FEEDBACKCONTROL
-                           FEEDBACKCONTROL: {KBDFEEDBACKCONTROL,
-                                             PTRFEEDBACKCONTROL,
-                                             INTEGERFEEDBACKCONTROL,
-                                             STRINGFEEDBACKCONTROL,
-                                             BELLFEEDBACKCONTROL,
-                                             LEDFEEDBACKCONTROL}
-
-   Errors: Device, Match, Value
-
-   Feedback controls are grouped by class. Those feedbacks that
-   are equivalent to those supported by the core keyboard are
-   controlled by feedback class KbdFeedbackClass using the
-   KbdFeedbackControl structure. The members of that structure
-   are:
-
-                   KBDFEEDBACKCTL
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            key_click_percent: INT8
-                            bell_percent: INT8
-                            bell_pitch: INT16
-                            bell_duration: INT16
-                            led_mask: INT32
-                            led_value: INT32
-                            key: KEYCODE
-                            auto_repeat_mode: {AutoRepeatModeOn, AutoRepeatModeOff,
-                                               AutoRepeatModeDefault}]
-
-   The key_click_percent sets the volume for key clicks between 0
-   (off) and 100 (loud) inclusive, if possible. Setting to -1
-   restores the default. Other negative values generate a Value
-   error.
-
-   If both auto_repeat_mode and key are specified, then the
-   auto_repeat_mode of that key is changed, if possible. If only
-   auto_repeat_mode is specified, then the global auto-repeat mode
-   for the entire keyboard is changed, if possible, without
-   affecting the per-key settings. It is a Match error if a key is
-   specified without an auto_repeat_mode.
-
-   The order in which controls are verified and altered is
-   server-dependent. If an error is generated, a subset of the
-   controls may have been altered.
-
-   Those feedback controls equivalent to those of the core pointer
-   are controlled by feedback class PtrFeedbackClass using the
-   PtrFeedbackControl structure. The members of that structure are
-   as follows:
-
-                   PTRFEEDBACKCTL:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            accelNumerator: INT16
-                            accelDenominator: INT16
-                            threshold: INT16]
-
-   The acceleration, expressed as a fraction, is a multiplier for
-   movement. For example, specifying 3/1 means the device moves
-   three times as fast as normal. The fraction may be rounded
-   arbitrarily by the X server. Acceleration only takes effect if
-   the device moves more than threshold pixels at once and only
-   applies to the amount beyond the value in the threshold
-   argument. Setting a value to -1 restores the default. The
-   values of the do-accel and do-threshold arguments must be
-   nonzero for the device values to be set. Otherwise, the
-   parameters will be unchanged. Negative values generate a Value
-   error, as does a zero value for the accel-denominator argument.
-
-   Some devices are capable of displaying an integer. This is done
-   using feedback class IntegerFeedbackClass using the
-   IntegerFeedbackControl structure. The members of that structure
-   are as follows:
-
-                   INTEGERCTL:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            int_to_display: INT32]
-
-   Some devices are capable of displaying an string. This is done
-   using feedback class StringFeedbackClass using the
-   StringFeedbackCtl structure. The members of that structure are
-   as follows:
-
-                   STRINGCTL:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            syms_to_display: LISTofKEYSYMS]
-
-   Some devices contain a bell. This is done using feedback class
-   BellFeedbackClass using the BellFeedbackControl structure. The
-   members of that structure are as follows:
-
-                   BELLCTL:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            percent: INT8
-                            pitch: INT16
-                            duration: INT16]
-
-   Some devices contain leds. These can be turned on and off using
-   the LedFeedbackControl structure. The members of that structure
-   are as follows:
-
-                   LEDCTL:
-                           [class: CARD8
-                            length: CARD16
-                            feedback id: CARD8
-                            led_mask: BITMASK
-                            led_value: BITMASK]
-
-   Errors: Device, Match, Value
-
-2.20 Ringing a Bell on an Input Device
-
-   To ring a bell on an extension input device, use DeviceBell.
-
-                   DeviceBell:
-                           device: DEVICE
-                           feedbackclass: CARD8
-                           feedbackid: CARD8
-                           percent: INT8
-
-   Errors: Device, Value
-
-   This request is analogous to the core Bell request. It rings
-   the specified bell on the specified input device feedback,
-   using the specified volume. The specified volume is relative to
-   the base volume for the feedback. If the value for the percent
-   argument is not in the range -100 to 100 inclusive, a Value
-   error results. The volume at which the bell rings when the
-   percent argument is nonnegative is:
-
-                   base - [(base * percent) / 100] + percent
-
-   The volume at which the bell rings when the percent argument is
-   negative is:
-
-                   base + [(base * percent) / 100]
-
-   To change the base volume of the bell, use
-   ChangeFeedbackControl request.
-
-Controlling Device Encoding
-
-   To get the keyboard mapping of an extension device that has
-   keys, use GetDeviceKeyMapping.
-
-                   GetDeviceKeyMapping
-                           device: DEVICE
-                           first-keycode: KEYCODE
-                           count: CARD8
-                   =>
-                           keysyms-per-keycode: CARD8
-                           keysyms: LISTofKEYSYM
-
-   Errors: Device, Match, Value
-
-   This request returns the symbols for the specified number of
-   keycodes for the specified extension device, starting with the
-   specified keycode. The first-keycode must be greater than or
-   equal to min-keycode as returned in the connection setup (else
-   a Value error), and
-
-                   first-keycode + count - 1
-
-   must be less than or equal to max-keycode as returned in the
-   connection setup (else a Value error). The number of elements
-   in the keysyms list is
-
-                   count * keysyms-per-keycode
-
-   and KEYSYM number N (counting from zero) for keycode K has an
-   index (counting from zero) of
-
-                   (K - first-keycode) * keysyms-per-keycode + N
-
-   in keysyms. The keysyms-per-keycode value is chosen arbitrarily
-   by the server to be large enough to report all requested
-   symbols. A special KEYSYM value of NoSymbol is used to fill in
-   unused elements for individual keycodes.
-
-   If the specified device has not first been opened by this
-   client via OpenDevice, or if that device does not support input
-   class Keys, this request will fail with a Device error.
-
-   To change the keyboard mapping of an extension device that has
-   keys, use ChangeDeviceKeyMapping.
-
-                   ChangeDeviceKeyMapping
-                           device: DEVICE
-                           first-keycode: KEYCODE
-                           keysyms-per-keycode: CARD8
-                           keysyms: LISTofKEYSYM
-                           num_codes: CARD8
-
-   Errors: Device, Match, Value, Alloc
-
-   This request is analogous to the core ChangeKeyMapping request.
-   It defines the symbols for the specified number of keycodes for
-   the specified extension device. If the specified device has not
-   first been opened by this client via OpenDevice, or if that
-   device does not support input class Keys, this request will
-   fail with a Device error.
-
-   The number of elements in the keysyms list must be a multiple
-   of keysyms_per_keycode. Otherwise, ChangeDeviceKeyMapping
-   generates a Length error. The specified first_keycode must be
-   greater than or equal to the min_keycode value returned by the
-   ListInputDevices request, or this request will fail with a
-   Value error. In addition, if the following expression is not
-   less than the max_keycode value returned by the
-   ListInputDevices request, the request will fail with a Value
-   error:
-
-                   first_keycode + (num_codes / keysyms_per_keycode) - 1
-
-   To obtain the keycodes that are used as modifiers on an
-   extension device that has keys, use GetDeviceModifierMapping.
-
-                   GetDeviceModifierMapping
-                           device: DEVICE
-                   =>
-                           keycodes-per-modifier: CARD8
-                           keycodes: LISTofKEYCODE
-
-   Errors: Device, Match
-
-   This request is analogous to the core GetModifierMapping
-   request. This request returns the keycodes of the keys being
-   used as modifiers. The number of keycodes in the list is
-   8*keycodes-per-modifier. The keycodes are divided into eight
-   sets, with each set containing keycodes-per-modifier elements.
-   The sets are assigned in order to the modifiers Shift, Lock,
-   Control, Mod1, Mod2, Mod3, Mod4, and Mod5. The
-   keycodes-per-modifier value is chosen arbitrarily by the
-   server; zeroes are used to fill in unused elements within each
-   set. If only zero values are given in a set, the use of the
-   corresponding modifier has been disabled. The order of keycodes
-   within each set is chosen arbitrarily by the server.
-
-   To set which keycodes that are to be used as modifiers for an
-   extension device, use SetDeviceModifierMapping.
-
-                   SetDeviceModifierMapping
-                           device: DEVICE
-                           keycodes-per-modifier: CARD8
-                           keycodes: LISTofKEYCODE
-                   =>
-                           status: {Success, Busy, Failed}
-
-   Errors: Device, Match, Value, Alloc
-
-   This request is analogous to the core SetModifierMapping
-   request. This request specifies the keycodes (if any) of the
-   keys to be used as modifiers. The number of keycodes in the
-   list must be 8*keycodes-per-modifier (else a Length error). The
-   keycodes are divided into eight sets, with the sets, with each
-   set containing keycodes-per-modifier elements. The sets are
-   assigned in order to the modifiers Shift, Lock, Control, Mod1,
-   Mod2, Mod3, Mod4, and Mod5. Only non-zero keycode values are
-   used within each set; zero values are ignored. All of the
-   non-zero keycodes must be in the range specified by min-keycode
-   and max-keycode in the ListInputDevices request (else a Value
-   error). The order of keycodes within a set does not matter. If
-   no non-zero values are specified in a set, the use of the
-   corresponding modifier is disabled, and the modifier bit will
-   always be zero. Otherwise, the modifier bit will be one
-   whenever at least one of the keys in the corresponding set is
-   in the down position.
-
-   A server can impose restrictions on how modifiers can be
-   changed (for example, if certain keys do not generate up
-   transitions in hardware or if multiple keys per modifier are
-   not supported). The status reply is Failed if some such
-   restriction is violated, and none of the modifiers are changed.
-
-   If the new non-zero keycodes specified for a modifier differ
-   from those currently defined, and any (current or new) keys for
-   that modifier are logically in the down state, then the status
-   reply is Busy, and none of the modifiers are changed.
-
-   This request generates a DeviceMappingNotify event on a Success
-   status. The DeviceMappingNotify event will be sent only to
-   those clients that have expressed an interest in receiving that
-   event via the XSelectExtensionEvent request.
-
-   A X server can impose restrictions on how modifiers can be
-   changed, for example, if certain keys do not generate up
-   transitions in hardware or if multiple modifier keys are not
-   supported. If some such restriction is violated, the status
-   reply is MappingFailed , and none of the modifiers are changed.
-   If the new keycodes specified for a modifier differ from those
-   currently defined and any (current or new) keys for that
-   modifier are in the logically down state, the status reply is
-   MappingBusy, and none of the modifiers are changed.
-
-2.20 Controlling Button Mapping
-
-   These requests are analogous to the core GetPointerMapping and
-   ChangePointerMapping requests. They allow a client to determine
-   the current mapping of buttons on an extension device, and to
-   change that mapping.
-
-   To get the current button mapping for an extension device, use
-   GetDeviceButtonMapping.
-
-                   GetDeviceButtonMapping
-                           device: DEVICE
-                           nmap: CARD8
-                   =>
-                           map_return: LISTofCARD8
-
-   Errors: Device, Match
-
-   The GetDeviceButtonMapping function returns the current mapping
-   of the buttons on the specified device. Elements of the list
-   are indexed starting from one. The length of the list indicates
-   the number of physical buttons. The nominal mapping is the
-   identity mapping map[i]=i.
-
-   nmap indicates the number of elements in the map_return array.
-   Only the first nmap entries will be copied by the library into
-   the map_return array.
-
-   To set the button mapping for an extension device, use
-   SetDeviceButtonMapping.
-
-                   SetDeviceButtonMapping
-                           device: DEVICE
-                           map: LISTofCARD8
-                           nmap: CARD8
-                   =>
-                           status: CARD8
-
-   Errors: Device, Match, Value
-
-   The SetDeviceButtonMapping function sets the mapping of the
-   specified device and causes the X server to generate a
-   DeviceMappingNotify event on a status of MappingSuccess.
-   Elements of the list are indexed starting from one. The length
-   of the list, specified in nmap, must be the same as
-   GetDeviceButtonMapping would return. Otherwise,
-   SetDeviceButtonMapping generates a Value error. A zero element
-   disables a button, and elements are not restricted in value by
-   the number of physical buttons. If any of the buttons to be
-   altered are in the down state, the status reply is MappingBusy
-   and the mapping is not changed.
-
-   In servers supporting XI 1.x, no two elements can have the same
-   nonzero value. Otherwise, this function generates a Value
-   error.
-
-2.21 Obtaining The State Of A Device
-
-   To obtain vectors that describe the state of the keys, buttons
-   and valuators of an extension device, use QueryDeviceState.
-
-                   QueryDeviceState
-                           device: DEVICE
-                   =>
-                           device-id: CARD8
-                           data: LISTofINPUTCLASS
-
-   where
-
-                   INPUTCLASS: {VALUATOR, BUTTON, KEY}
-                   CLASS VALUATOR:
-                               [class: CARD8
-                                num_valuators: CARD8
-                                mode: CARD8
-                                #x01 device mode (0 = Relative, 1 = Absolute)
-                                #x02 proximity state (0 = InProximity, 1 = OutOfProximity)
-                                valuators: LISTofINT32]
-                   CLASS BUTTON:
-                               [class: CARD8
-                                num_buttons: CARD8
-                                buttons: LISTofCARD8]
-                   CLASS KEY:
-                               [class: CARD8
-                                num_keys: CARD8
-                                keys: LISTofCARD8]
-
-   Errors: Device
-
-   The QueryDeviceState request returns the current logical state
-   of the buttons, keys, and valuators on the specified input
-   device. The buttons and keys arrays, byte N (from 0) contains
-   the bits for key or button 8N to 8N+7 with the least
-   significant bit in the byte representing key or button 8N.
-
-   If the device has valuators, a bit in the mode field indicates
-   whether the device is reporting Absolute or Relative data. If
-   it is reporting Absolute data, the valuators array will contain
-   the current value of the valuators. If it is reporting Relative
-   data, the valuators array will contain undefined data.
-
-   If the device reports proximity information, a bit in the mode
-   field indicates whether the device is InProximity or
-   OutOfProximity.
-
-2.22 Listing Device Properties
-
-   Introduced with XI 1.5
-
-               ListDeviceProperties
-                        deviceid: CARD8
-               =>
-                        nAtoms: CARD16
-                        Atoms: LISTofATOM
-
-   Errors: Device
-
-   Each device can store an arbitrary number of properties. These
-   properties can be allocated by either the client or the driver.
-   The client can change device properties and the server
-   guarantees that the device driver is notified about a change of
-   the device's properties.
-
-   ListDeviceProperties returns all properties of a device. The
-   client is expected to retrieve details about the properties it
-   is interested in separately.
-
-2.23 Getting a Device Property
-
-   Introduced with XI 1.5
-
-               GetDeviceProperty:
-                        property: ATOM
-                        type: ATOM
-                        longOffset: CARD32
-                        longLength: CARD32
-                        deviceid: CARD8
-                        delete: BOOL
-               =>
-                        propertyType: ATOM
-                        bytesAfter: CARD32
-                        nItems: CARD32
-                        format: CARD8
-                        deviceid: CARD8
-                        data: [LISTofCARD8]
-
-   Errors: Atom, Device, Value, Access
-
-   Retrieve the value for a property. If the property does not
-   exist, propertyType is None and all other fields are undefined.
-
-   If type is not AnyPropertyType and does not match the
-   property's actual type, the propertyType, bytesAfter, and
-   format are returned but not the actual data.
-
-   longOffset and longLength specify the offset and length
-   respectively in 32-bit multiples of the data to retrieve.
-
-   If delete is True, the property is deleted after querying its
-   data. If the property cannot be deleted, a BadAccess error is
-   returned.
-
-   propertyType returns the atom identifier that defines the
-   actual type of the property.
-
-   If bytesAfter is non-zero, it specifies the number of data
-   4-byte units after the retrieved chunk of data.
-
-   format specifies whether the data should be viewed as a list of
-   8-bit, 16-bit, or 32-bit quantities. Possible values are 8, 16,
-   and 32. This information allows the X server to correctly
-   perform byte-swap operations as necessary.
-
-   nItem specifies the number of 8-bit, 16-bit, or 32-bit items
-   returned after the request.
-
-2.24 Changing a Device Property
-
-   Introduced with XI 1.5
-
-               ChangeDeviceProperty:
-                        property: ATOM
-                        type: ATOM
-                        deviceid: CARD8
-                        format: CARD8
-                        mode: CARD8
-                        nUnits: CARD32
-
-   Errors: Atom, Device, Value, Match, Access
-
-   Changes the value of a specified property.
-
-   The type specifies the atom identifier that defines the type of
-   the property. If mode is not PropModeReplace, the type must
-   match the current type of the property or a BadMatch error is
-   returned.
-
-   format specifies whether the data should be viewed as a list of
-   8-bit, 16-bit, or 32-bit quantities. Possible values are 8, 16,
-   and 32. This information allows the X server to correctly
-   perform byte-swap operations as necessary.
-
-   If mode is PropModeReplace, a preexising value for this
-   property is replaced with the new value. If mode is
-   PropModePrepend or PropModeAppend, the value is prepended or
-   appended, respectively, to the current value of the property.
-
-   nUnits specifies the number of 8-bit, 16-bit, or 32-bit items
-   supplied after the reply.
-
-   Changing a device property results in a
-   DevicePropertyNotifyEvent being sent to all clients.
-
-2.25 Deleting a Device Property
-
-   Introduced with XI 1.5
-
-               DeleteDeviceProperty:
-                        property: ATOM
-                        deviceid: CARD8
-
-   Errors: Atom, Device, Match, Access.
-
-   Deletes the specified property. If the property cannot be
-   deleted by the client, a BadAccess error is returned.
-
-3. Events
-
-   The input extension creates input events analogous to the core
-   input events. These extension input events are generated by
-   manipulating one of the extension input devices.
-
-3.1 Button, Key, and Motion Events
-
-               DeviceKeyPress
-               DeviceKeyRelease
-               DeviceButtonPress,
-               DeviceButtonRelease
-               DeviceMotionNotify
-                       device: CARD8
-                       root, event: WINDOW
-                       child: Window or None
-                       same-screen: BOOL
-                       root-x, root-y, event-x, event-y: INT16
-                       detail: <see below>
-                       state: SETofKEYBUTMASK
-                       time: TIMESTAMP
-
-   These events are generated when a key, button, or valuator
-   logically changes state. The generation of these logical
-   changes may lag the physical changes, if device event
-   processing is frozen. Note that DeviceKeyPress and
-   DeviceKeyRelease are generated for all keys, even those mapped
-   to modifier bits. The “source” of the event is the window the
-   pointer is in. The window with respect to which the event is
-   normally reported is found by looking up the hierarchy
-   (starting with the source window) for the first window on which
-   any client has selected interest in the event. The actual
-   window used for reporting can be modified by active grabs and
-   by the focus window.The window the event is reported with
-   respect to is called the “event” window.
-
-   The root is the root window of the “source” window, and root-x
-   and root-y are the pointer coordinates relative to root's
-   origin at the time of the event. Event is the “event” window.
-   If the event window is on the same screen as root, then event-x
-   and event-y are the pointer coordinates relative to the event
-   window's origin. Otherwise, event-x and event-y are zero. If
-   the source window is an inferior of the event window, then
-   child is set to the child of the event window that is an
-   ancestor of (or is) the source window. Otherwise, it is set to
-   None.
-
-   The state component gives the logical state of the buttons on
-   the X pointer and modifier keys on the core X keyboard just
-   before the event.
-
-   The detail component type varies with the event type:
-   Event               Component
-   DeviceKeyPress      KEYCODE
-   DeviceKeyRelease    KEYCODE
-   DeviceButtonPress   BUTTON
-   DeviceButtonRelease BUTTON
-   DeviceMotionNotify  { Normal , Hint }
-
-   The granularity of motion events is not guaranteed, but a
-   client selecting for motion events is guaranteed to get at
-   least one event when a valuator changes. If DeviceMotionHint is
-   selected, the server is free to send only one
-   DeviceMotionNotify event (with detail Hint) to the client for
-   the event window, until either a key or button changes state,
-   the pointer leaves the event window, or the client issues a
-   QueryDeviceState or GetDeviceMotionEvents request.
-
-3.2 DeviceValuator Event
-
-                   DeviceValuator
-                           device: CARD8
-                           device_state: SETofKEYBUTMASK
-                           num_valuators: CARD8
-                           first_valuator: CARD8
-                           valuators: LISTofINT32
-
-   DeviceValuator events are generated to contain valuator
-   information for which there is insufficient space in DeviceKey,
-   DeviceButton, DeviceMotion, and Proximity wire events. For
-   events of these types, a second event of type DeviceValuator
-   follows immediately. The library combines these events into a
-   single event that a client can receive via XNextEvent.
-   DeviceValuator events are not selected for by clients, they
-   only exist to contain information that will not fit into some
-   event selected by clients.
-
-   The device_state component gives the state of the buttons and
-   modifiers on the device generating the event.
-
-   Extension motion devices may report motion data for a variable
-   number of axes. The valuators array contains the values of all
-   axes reported by the device. If more than 6 axes are reported,
-   more than one DeviceValuator event will be sent by the server,
-   and more than one DeviceKey, DeviceButton, DeviceMotion, or
-   Proximity event will be reported by the library. Clients should
-   examine the corresponding fields of the event reported by the
-   library to determine the total number of axes reported, and the
-   first axis reported in the current event. Axes are numbered
-   beginning with zero.
-
-   For Button, Key and Motion events on a device reporting
-   absolute motion data the current value of the device's
-   valuators is reported. For devices that report relative data,
-   Button and Key events may be followed by a DeviceValuator event
-   that contains 0s in the num_valuators field. In this case, only
-   the device_state component will have meaning.
-
-3.3 Device Focus Events
-
-                   DeviceFocusIn
-                   DeviceFocusOut
-                           device: CARD8
-                           time: TIMESTAMP
-                           event: WINDOW
-                           mode: { Normal, WhileGrabbed, Grab, Ungrab}
-                           detail: { Ancestor, Virtual, Inferior, Nonlinear,
-                                     NonlinearVirtual, Pointer, PointerRoot, None}
-
-   These events are generated when the input focus changes and are
-   reported to clients selecting DeviceFocusChange for the
-   specified device and window. Events generated by SetDeviceFocus
-   when the device is not grabbed have mode Normal. Events
-   generated by SetDeviceFocus when the device is grabbed have
-   mode WhileGrabbed. Events generated when a device grab actives
-   have mode Grab, and events generated when a device grab
-   deactivates have mode Ungrab.
-
-   All DeviceFocusOut events caused by a window unmap are
-   generated after any UnmapNotify event, but the ordering of
-   DeviceFocusOut with respect to generated EnterNotify,
-   LeaveNotify, VisibilityNotify and Expose events is not
-   constrained.
-
-   DeviceFocusIn and DeviceFocusOut events are generated for focus
-   changes of extension devices in the same manner as focus events
-   for the core devices are generated.
-
-3.4 Device State Notify Event
-
-                   DeviceStateNotify
-                   time: TIMESTAMP
-                   device: CARD8
-                   num_keys: CARD8
-                   num_buttons: CARD8
-                   num_valuators: CARD8
-                   classes_reported: CARD8 {SetOfDeviceMode | SetOfInputClass}
-                       SetOfDeviceMode:
-                           #x80 ProximityState 0 = InProxmity, 1 = OutOfProximity
-                           #x40 Device Mode (0 = Relative, 1 = Absolute)
-                       SetOfInputClass: #x04 reporting valuators
-                           #x02 reporting buttons
-                           #x01 reporting keys
-                   buttons: LISTofCARD8
-                   keys: LISTofCARD8
-                   valuators: LISTofCARD32
-
-   This event reports the state of the device just as in the
-   QueryDeviceState request. This event is reported to clients
-   selecting DeviceStateNotify for the device and window and is
-   generated immediately after every EnterNotify and
-   DeviceFocusIn. If the device has no more than 32 buttons, no
-   more than 32 keys, and no more than 3 valuators, This event can
-   report the state of the device. If the device has more than 32
-   buttons, the event will be immediately followed by a
-   DeviceButtonStateNotify event. If the device has more than 32
-   keys, the event will be followed by a DeviceKeyStateNotify
-   event. If the device has more than 3 valuators, the event will
-   be followed by one or more DeviceValuator events.
-
-3.5 Device KeyState and ButtonState Notify Events
-
-                   DeviceKeyStateNotify
-                           device: CARD8
-                           keys: LISTofCARD8
-                   DeviceButtonStateNotify
-                           device: CARD8
-                           buttons: LISTofCARD8
-
-   These events contain information about the state of keys and
-   buttons on a device that will not fit into the
-   DeviceStateNotify wire event. These events are not selected by
-   clients, rather they may immediately follow a DeviceStateNotify
-   wire event and be combined with it into a single
-   DeviceStateNotify client event that a client may receive via
-   XNextEvent.
-
-3.6 DeviceMappingNotify Event
-
-                   DeviceMappingNotify
-                           time: TIMESTAMP
-                           device: CARD8
-                           request: CARD8
-                           first_keycode: CARD8
-                           count: CARD8
-
-   This event reports a change in the mapping of keys, modifiers,
-   or buttons on an extension device. This event is reported to
-   clients selecting DeviceMappingNotify for the device and window
-   and is generated after every client SetDeviceButtonMapping,
-   ChangeDeviceKeyMapping, or ChangeDeviceModifierMapping request.
-
-3.7 ChangeDeviceNotify Event
-
-                   ChangeDeviceNotify
-                           device: CARD8
-                           time: TIMESTAMP
-                           request: CARD8
-
-   This event reports a change in the physical device being used
-   as the core X keyboard or X pointer device. ChangeDeviceNotify
-   events are reported to clients selecting ChangeDeviceNotify for
-   the device and window and is generated after every client
-   ChangeKeyboardDevice or ChangePointerDevice request.
-
-3.7 Proximity Events
-
-                   ProximityIn
-                   ProximityOut
-                           device: CARD8
-                           root, event: WINDOW
-                           child: Window or None
-                           same-screen: BOOL
-                           root-x, root-y, event-x, event-y: INT16
-                           state: SETofKEYBUTMASK
-                           time: TIMESTAMP
-                           device-state: SETofKEYBUTMASK
-                           axis-count: CARD8
-                           first-axis: CARD8
-                           axis-data: LISTofINT32
-
-   These events are generated by some devices (such as graphics
-   tablets or touchscreens) to indicate that a stylus has moved
-   into or out of contact with a positional sensing surface.
-
-   The “source” of the event is the window the pointer is in. The
-   window with respect to which the event is normally reported is
-   found by looking up the hierarchy (starting with the source
-   window) for the first window on which any client has selected
-   interest in the event. The actual window used for reporting can
-   be modified by active grabs and by the focus window.The window
-   the event is reported with respect to is called the “event”
-   window.
-
-   The root is the root window of the “source” window, and root-x
-   and root-y are the pointer coordinates relative to root's
-   origin at the time of the event. Event is the “event” window.
-   If the event window is on the same screen as root, then event-x
-   and event-y are the pointer coordinates relative to the event
-   window's origin. Otherwise, event-x and event-y are zero. If
-   the source window is an inferior of the event window, then
-   child is set to the child of the event window that is an
-   ancestor of (or is) the source window. Otherwise, it is set to
-   None. The state component gives the logical state of the
-   buttons on the core X pointer and modifier keys on the core X
-   keyboard just before the event. The device-state component
-   gives the state of the buttons and modifiers on the device
-   generating the event.
-
-3.8 DevicePresenceEvents
-
-   Introduced with XI 1.4.
-
-                   DevicePresence
-                           time: TIMESTAMP
-                           devchange: BYTE
-                               #x00: DeviceAdded
-                               #x01: DeviceRemoved
-                               #x02: DeviceEnabled
-                               #x03: DeviceDisabled
-                               #x04: DeviceUnrecoverable
-                               #x05: DeviceControlChanged
-                           deviceid: BYTE
-                           control: CARD16
-
-   DevicePresence events are sent when the server adds or removes,
-   or enables or disables an input device. The client is expected
-   to query the server for the list of input devices using the
-   ListInputDevices request to obtain the updated list of input
-   devices. DevicePresence events are also sent when a control on
-   the device has been changed.
-
-   The devchange field specifies the type of operation. In case of
-   DeviceAdded, a new device has been added to the server, but
-   this device does not yet send events. If devchange is set to
-   DeviceEnabled, the device is enabled and will generate events.
-   If the field is DeviceDisabled or DeviceRemoved, the given
-   device is disabled and stops sending events or was removed from
-   the server, respectively. If the field is DeviceUnrecoverable,
-   an IO-error has occured on the device and the device is
-   forcibly disabled and removed by the server. If devchange is
-   DeviceControlChanged, control specifies the type of control
-   that has been changed.
-
-3.9 DevicePropertyNotifyEvent
-
-   Introduced with XI 1.5.
-
-                   DevicePropertyNotifyEvent
-                           deviceid: CARD8
-                           state: CARD8
-                           time: TIMESTAMP
-                           atom: ATOM
-
-   A DevicePropertyNotifyEvent is sent to all clients when a
-   property on the device is created, deleted, or changes value.
-
-   The deviceid specifies the device which's property has been
-   modified.
-
-   The atom specifies the named identifier of the property that
-   has been altered.
-
-   If state is PropertyNewValue, the given property has a new
-   value or has been newly created. If state is PropertyDeleted,
-   the given property has been deleted.
old mode 100644 (file)
new mode 100755 (executable)
old mode 100755 (executable)
new mode 100644 (file)
index 39e4df9..1c74810
@@ -1,13 +1,16 @@
 AC_PREREQ([2.60])
-AC_INIT([InputProto], [2.0.1], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg])
+AC_INIT([InputProto], [2.2], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
 
-# Require xorg-macros: XORG_DEFAULT_OPTIONS
+# Require xorg-macros: XORG_WITH_ASCIIDOC
 m4_ifndef([XORG_MACROS_VERSION],
-          [m4_fatal([must install xorg-macros 1.3 or later before running autoconf/autogen])])
-XORG_MACROS_VERSION(1.3)
+          [m4_fatal([must install xorg-macros 1.10 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.10)
 XORG_DEFAULT_OPTIONS
+XORG_ENABLE_SPECS
+XORG_WITH_ASCIIDOC(8.4.5)
 
 AC_OUTPUT([Makefile
+           specs/Makefile
            inputproto.pc])
diff --git a/packaging/xorg-x11-proto-input.spec b/packaging/xorg-x11-proto-input.spec
new file mode 100644 (file)
index 0000000..68187f6
--- /dev/null
@@ -0,0 +1,45 @@
+Name:     xorg-x11-proto-input
+Summary:  X.Org X11 Protocol inputproto
+Version:  2.2
+Release:  1
+Group:    Development/System
+License:  MIT
+URL:      http://www.x.org
+Source0:  %{name}-%{version}.tar.gz
+Provides: inputproto
+
+BuildRequires: pkgconfig
+BuildRequires: pkgconfig(xorg-macros)
+
+# some file to be intalled can be ignored when rpm generates packages
+%define _unpackaged_files_terminate_build 0
+
+%description
+Description: %{summary}
+
+%prep
+%setup -q
+
+%build
+
+./autogen.sh
+%reconfigure --disable-static \
+             --libdir=%{_datadir} \
+             --without-xmlto
+
+# Call make instruction with smp support
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+%remove_docs
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root,-)
+%{_includedir}/X11/extensions/*.h
+%{_datadir}/pkgconfig/*.pc
\ No newline at end of file
diff --git a/packaging/xorg-x11-proto-inputproto.spec b/packaging/xorg-x11-proto-inputproto.spec
deleted file mode 100644 (file)
index e086f5d..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-
-Name:       xorg-x11-proto-inputproto
-Summary:    X.Org X11 Protocol inputproto
-Version:    2.0.1
-Release:    0
-Group:      Development/System
-License:    MIT
-URL:        http://www.x.org
-Source0:    http://xorg.freedesktop.org/releases/individual/proto/inputproto-%{version}.tar.gz
-Provides:   inputproto
-BuildRequires: pkgconfig(xorg-macros)
-
-
-%description
-Description: %{summary}
-
-
-
-%prep
-%setup -q -n inputproto-%{version}
-
-%build
-
-%reconfigure --disable-shared
-
-# Call make instruction with smp support
-make %{?jobs:-j%jobs}
-
-%install
-rm -rf %{buildroot}
-%make_install
-
-
-%clean
-rm -rf %{buildroot}
-
-
-
-
-
-%files
-%defattr(-,root,root,-)
-%{_libdir}/pkgconfig/inputproto.pc
-%{_includedir}/X11/extensions/XI.h
-%{_includedir}/X11/extensions/XIproto.h
-%{_includedir}/X11/extensions/XI2.h
-%{_includedir}/X11/extensions/XI2proto.h
-%{_docdir}/inputproto
-
-
diff --git a/specs/Makefile.am b/specs/Makefile.am
new file mode 100644 (file)
index 0000000..a83cf40
--- /dev/null
@@ -0,0 +1,14 @@
+
+if ENABLE_SPECS
+if HAVE_ASCIIDOC
+
+doc_DATA = XI2proto.html XIproto.html
+dist_doc_DATA = XI2proto.txt XIproto.txt
+
+%.html: %.txt
+       $(AM_V_GEN)$(ASCIIDOC) -o $@ $<
+
+CLEANFILES = $(doc_DATA)
+
+endif
+endif
diff --git a/specs/XI2proto.txt b/specs/XI2proto.txt
new file mode 100644 (file)
index 0000000..fb32768
--- /dev/null
@@ -0,0 +1,2445 @@
+The X Input Extension 2.x
+=========================
+:toc:
+:numbered:
+
+Authors:
+
+- Peter Hutterer (Red Hat) <peter.hutterer@redhat.com>
+- Daniel Stone (Collabora Ltd.) <daniel@fooishbar.org>
+- Chase Douglas (Canonical, Ltd.) <chase.douglas@canonical.com>
+
+[[history]]
+History 
+-------
+
+- v2.2, March 2012: Multitouch support added
+- v2.1, December 2011: new raw event behaviour, smooth scrolling support
+  added
+- v2.0, October 2009: Initial release of XI2 protocol
+
+[[intro-xi20]]
+Introduction
+------------
+
+The X Input Extension version 2.0 (XI2) is the second major release of the X
+Input Extension.
+
+XI2 provides a number of enhancements over version 1.5, including:
+
+- use of XGE and GenericEvents. GenericEvents are of flexible length with a
+  minimum length of 32 bytes.
+- explicit device hierarchy of master and slave devices. See Section
+<<hierarchy,The Master/Slave device hierarchy>>.
+- use of multiple independent master devices (Multi-Poiner X or MPX).
+- the ability for devices to change capabilities at runtime.
+- raw device events
+
+XI2's intent is to replace both core input processing and prior versions of
+the X Input Extension. Historically, the majority of applications employed the
+core protocol requests and events to handle user input. The core protocol does
+not provide information about which device generated the event. The X Input
+Extension version up to 1.5 requires the differentiation between core and
+extended devices. Extended devices may not be core devices and thus cannot be
+used on applications employing the core protocol. XI2 addresses both of these
+issues by enabling devices to be both extended and core devices and providing
+device information in each event (with the exception of core events).
+
+Changes in version 2.1
+----------------------
+
+- RawEvents are sent regardless of the grab state.
+- Addition of the ScrollClass for smooth scrolling
+
+Changes in version 2.2
+----------------------
+
+- Multitouch support added
+
+
+//                            ❧❧❧❧❧❧❧❧❧❧❧
+
+Notations used in this document
+-------------------------------
+
+Notation for requests:
+
+    ┌───
+        Name of request
+            name of request field:       type of request field
+            name of request field:       type of request field
+            ▶
+            name of reply field:         type of reply field
+    └───
+
+Notation for events:
+
+    ┌───
+        Name of event
+            name of field:               type of field
+            name of field:               type of field
+    └───
+
+Complex fields are specified in the following notation:
+
+          name of field:                  COMPLEXFIELDTYPE
+
+or, if multiple of these fields exist:
+
+          name of field:                  LISTofCOMPLEXFIELDTYPE
+
+    COMPLEXFIELDTYPE:  { name of subfield:   type of subfield,
+                         name of subfield:   type of subfield }
+
+//                            ❧❧❧❧❧❧❧❧❧❧❧
+
+Interoperability between version 1.x and 2.0
+--------------------------------------------
+
+There is little interaction between 1.x and 2.x versions of the X Input
+Extension. Clients are requested to avoid mixing XI1.x and XI2 code as much as
+possible. Several direct incompatibilities are observable:
+
+[[interop-xi1-limitations]]
+Limitations resulting from different variable ranges
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+XI2 provides a larger range for some fields than XI1. As a result, XI1 clients
+may not receive data an XI2 client receives.
+These fields include:
+
+- devices with a deviceid of greater than 127 are invisible to XI1 clients.
+- key events and key grabs featuring larger than 255 can only be sent to XI2
+  clients.
+- no subpixel information is available to XI1 clients. If motion events are in
+  a subpixel range only, the server may omit these events and an XI 1.x client
+  will not receive events until the pixel boundary is crossed.
+
+
+[[interop-xi1-grabs]]
+Blocking of grabs
+~~~~~~~~~~~~~~~~~
+
+XI1 grabs are different to XI2 grab and a device may not be grabbed through an
+XI2 grab if an XI1 grab is currently active on this device or vice versa.
+Likewise, a keycode or button already grabbed by an XI 1.x or XI2 client may
+not be grabbed with the same modifier combination by an XI2 or XI 1.x client,
+respectively.
+
+[[interop-xi1-device-list]]
+Invisibility of Master Devices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+XI 1.x was not designed with support for multiple master devices. As a
+result, only the first master pointer and master keyboard are visible to XI
+1.x clients; all other master devices are invisible and cannot be accessed
+from XI 1.x calls.
+
+Smooth scrolling
+~~~~~~~~~~~~~~~~
+
+Historically, X implemented scrolling events by using button press events:
+button 4 was one “click” of the scroll wheel upwards, button 5 was downwards,
+button 6 was one unit of scrolling left, and button 7 was one unit of scrolling
+right.  This is insufficient for e.g. touchpads which are able to provide
+scrolling events through multi-finger drag gestures, or simply dragging your
+finger along a designated strip along the side of the touchpad.
+
+Newer X servers may provide scrolling information through valuators to
+provide clients with more precision than the legacy button events. This
+scrolling information is part of the valuator data in device events.
+Scrolling events do not have a specific event type.
+
+Valuators for axes sending scrolling information must have one
+ScrollClass for each scrolling axis. If scrolling valuators are present on a
+device, the server must provide two-way emulation between these valuators
+and the legacy button events for each delta unit of scrolling.
+
+One unit of scrolling in either direction is considered to be equivalent to
+one button event, e.g. for a unit size of 1.0, -2.0 on an valuator type
+Vertical sends two button press/release events for button 4. Likewise, a
+button press event for button 7 generates an event on the Horizontal
+valuator with a value of +1.0. The server may accumulate deltas of less than
+one unit of scrolling.
+
+Any server providing this behaviour marks emulated button or valuator events
+with the XIPointerEmulated flag for DeviceEvents, and the XIRawEmulated flag
+for raw events, to hint at applications which event is a hardware event.
+
+If more than one scroll valuator of the same type is present on a device,
+the valuator marked with Preferred for the same scroll direction is used to
+convert legacy button events into scroll valuator events. If no valuator is
+marked Preferred or more than one valuator is marked with Preferred for this
+scroll direction, this should be considered a driver bug and the behaviour
+is implementation-dependent.
+
+[[hierarchy]]
+The Master/Slave device hierarchy
+---------------------------------
+
+XI2 introduces a device hierarchy split up into so-called Master Devices (MD)
+and Slave Devices (SD).
+
+[[hierarchy-master]]
+Master devices
+~~~~~~~~~~~~~~
+An MD is a virtual device created and managed by the server. MDs may send core
+events and XI events. However, an MD does not represent a physical device and
+relies on SDs for event generation. MDs come in two forms: as master pointers
+or as master keyboards. A master pointer is represented by a visible cursor on
+the screen. A master keyboard is represented by a keyboard focus.
+
+Each master pointer is paired with the respective master keyboard and vice
+versa, and this pairing is constant for the lifetime of both input devices.
+Clients can use this pairing behaviour to implement input paradigms that
+require pointer and keyboard interation (e.g. SHIFT + Click).
+
+[[hierarchy-slave]]
+Slave devices
+~~~~~~~~~~~~~
+An SD is usually a physical device configured in the server. SDs are not
+represented by a cursor or keyboard focus and may be attached to a master
+pointer or master keyboard. SDs can only be attached to any master of the same
+type (e.g. a physical pointer device can be attached to any master pointer).
+
+If an event is generated by an SD
+
+- if the SD is attached to a master pointer, it changes the position and/or
+  button state of the master pointer.
+- if the SD is attached to a master keyboard, it sends events to this
+  keyboard's focus window (if applicable) and/or changes the modifier state of
+  this keyboard.
+- if the SD is not attached to an MD ("floating"), it does not change
+  any master device. The SD has its own (invisible) sprite and its own focus.
+  Both the sprite and the focus must be managed explicitly by the client
+  program.
+
+[[hierarchy-dcce]]
+Event processing for attached slave devices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Whenever an SD changes its logical state,
+
+- the event is delivered as an XI event to any interested clients. If the
+  device is floating, event processing stops.
+  Otherwise, if the device is attached,
+- the master device changes its classes to reflect the SD's capabilities. All
+  interested clients are notified of this device change.
+- then, the event is delivered as an XI event from the MD to any interested
+  clients. If the event has been delivered, event processing stops.
+  Otherwise,
+- the event is delivered as a core event to any interested clients.
+
+Given that W is the event window, and P the parent window of W, event delivery
+to P is only attempted if neither the XI event, nor the core event has been
+delivered on W. Once an event has been delivered as either XI or core event,
+event processing stops.
+
+[[clientpointer]]
+The ClientPointer principle
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Many core protocol and some extension requests are ambiguous when multiple
+master devices are available (e.g. QueryPointer does not specify which pointer).
+The X server does not have the knowledge to chose the contextually correct
+master device. For each client, one master pointer is designated as this
+clients's "ClientPointer". Whenever a client sends an ambiguous request (e.g.
+QueryPointer), the ClientPointer or the keyboard paired with the ClientPointer
+is chosen to provide the data for this request.
+
+This ClientPointer may be explicitly assigned to a client with the
+SetClientPointer call. If no ClientPointer is set when a client issues an
+ambiguous request, the server choses one device as the ClientPointer. The
+method of chosing a ClientPointer from the available master pointers is
+implementation-specific.
+
+If the master pointer currently set as ClientPointer for one or more clients is
+removed, the server may either unset the ClientPointer setting or change the
+ClientPointer to a different master pointer.
+
+[[multitouch]]
+Touch device support
+--------------------
+
+XI 2.2 introduces support for multi-touch devices. The traditional
+pointer/keyboard approach enforced by XI 2.0 with the master/slave device
+hierarchy is not always suitable for multi-touch devices that can provide a
+dynamic number of touchpoints per physical device; it is not known without
+client-specific interpretation whether the touchpoints must be considered
+separately or grouped together.
+
+The additions in XI 2.2 aim to:
+
+- support a dynamic number of simultaneous touch points,
+- support devices that are both multi-touch and traditional pointer devices,
+- allow touchpoints to be either grouped together or handled separately,
+- be backwards-compatible to pre-XI 2.2 clients through emulation of XI 2.x/XI 1.x and core
+  pointer events.
+
+Touch events are only available to clients supporting version 2.2 or later of
+the X Input Extension. Clients must use the XIQueryVersion request to announce
+support for this version. Touch devices may generate emulated pointer events
+alongside XI 2.2 touch events to support older clients; see Section
+<<multitouch-processing,Touch event delivery>>.
+
+Touch event processing differs from normal event processing in a few ways.
+The most notable differences are that touch events are processed partially
+out-of-band from pointer and keyboard events, and that touch events may be
+sent to multiple clients simultaneously. For more details see Section
+<<multitouch-processing, Touch event delivery>>.
+
+[[multitouch-lifecycle]]
+Touch event sequences
+~~~~~~~~~~~~~~~~~~~~~
+
+Touch input follows a three-stage cycle:
+
+        begin - update - update - ... - end
+
+i.e. “begin” the sequence by touching the device, “update” the current
+touch location or properties any number of times, and finally “end” the
+sequence by ceasing to touch the device.  Within this document, the term
+"touch sequence" is used to describe the above sequence of events.
+In the protocol, the three stages are represented with the event
+types TouchBegin, TouchUpdate, and TouchEnd, respectively. A touch sequence
+always generates TouchBegin and TouchEnd events, and may also generate
+TouchUpdate events.  Clients must select for all three of these events
+simultaneously.
+
+When a touch starts, clients are sent a TouchBegin event
+detailing the position of the touchpoint, as well as the
+initial properties of the touchpoint.  Note that the logical state of the
+device (as seen through the input protocol) may lag the physical state if event
+processing is affected by grabs.  Multiple touchpoints may be active on the
+same device at any time, potentially owned by and/or delivered to a different
+set of clients.
+
+Whenever the touch position or any other property of the touchpoint changes,
+a TouchUpdate event is sent to all clients listening
+to events for that touchpoint with the updated information.
+
+When the touch has physically ended, or a client will otherwise not receive
+any more events for a given touchpoint, a TouchEnd event will be sent to
+that client.
+
+Passive touch grabs are similar to standard input event grabs in that they
+take precedence over event selections and are searched from the root window
+to the child window (as opposed to selections, which start their search at the
+child window and continue up to the root window).  When a touch grab activates,
+the client whose grab activates becomes the “owner” of this touch sequence,
+and must decide what to do with it, as per Section
+<<multitouch-ownership,Ownership of touch sequences>>.  See the
+<<requests-passivegrabdevice,XIPassiveGrabDevice>> request
+documentation for more information on passive grab activation.
+
+Only one client may select for touch events from a given device on a window.
+
+[[multitouch-ownership]]
+Ownership of touch sequences
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Once a grabbing client becomes the owner of a touch, it must either “accept” or
+"reject" the touch sequence using the XIAllowEvents request. If a touch sequence
+is rejected, a TouchEnd event is sent to the rejecting client, and it will not
+receive any more events for this touch.  The server then looks to the next
+window in the stack for another passive grab, and attempts to pass ownership
+on to the next candidate for a passive grab (i.e. the next window towards
+the final child window with a matching grab), or to the first applicable
+event selection if there are no more grabs.
+
+If a touch sequence is accepted by its owner, all other clients receive
+TouchEnd events, and the touch sequence is exclusively delivered to the
+owner from that point on.
+
+If the touch sequence physically ends while the owner of the touch sequence
+has not yet accepted or rejected ownership, the owner receives a TouchEnd
+event and all other clients receive a TouchUpdate event with the
+TouchPendingEnd flag set. The owner must still accept or reject the sequence
+nonetheless. If the owner rejects the touch sequence, the server will still
+attempt to exhaust all other passive grabs and/or event selections looking
+for a final owner.
+
+If the touch sequence has not physically ended yet and the owner of the
+touch sequence rejects, the owner receives a TouchEnd event and ownership is
+passed to the next client.
+
+Clients may opt for touch events to be delivered before they become the
+owner of the touch sequence. In this case, the logical state of the device (as
+seen by means of the protocol) always matches the physical state of the device.
+Clients must use caution if they opt for this feature; any action taken must be
+undone if the touch sequence ends without the client becoming the owner.
+
+To select for touch events regardless of ownership, a client must set the
+TouchOwnership event mask in addition to the
+TouchBegin, TouchUpdate and TouchEnd mask. When selected, a client will receive
+touch events as they occur on the device. If and when the client
+becomes the owner of a touch sequence, a TouchOwnership event is sent to the
+client. If the client is the initial owner of the sequence, the TouchBegin is
+immediately followed by the TouchOwnership event. Otherwise, TouchUpdate events
+may preceed a TouchOwnership event. A client is not guaranteed to become the
+owner of any given touch sequence.
+
+The server delivers touch events to all clients that have selected for
+TouchOwnership and to the current owner of the sequence in parallel.
+
+If a client has selected for TouchOwnership and is not the current owner of
+the sequence and the current owner accepts the sequence, the client receives
+a TouchEnd event and no further events from this sequence are sent to this
+client.
+
+If a client has selected for TouchOwnership and the physical touch ends
+before the current owner has accepted or rejected the sequence, the client
+receives a TouchUpdate event with the TouchPendingEnd flag set. No further
+TouchUpdate events will be sent for this sequence. If the current owner
+accepts the sequence, the client receives a TouchEnd event. Otherwise, if
+the current owner rejects the sequence, the client may become 
+the owner of the touch sequence and receive a TouchOwnership event and a
+TouchEnd event.
+
+[[multitouch-device-modes]]
+Touch device modes
+~~~~~~~~~~~~~~~~~~
+
+Touch devices come in many different forms with varying capabilities. The
+following device modes are defined for this protocol:
+
+'DirectTouch':
+    These devices map their input region to a subset of the screen region. Touch
+    events are delivered to window at the location of the touch. "direct"
+    here refers to the user manipulating objects at their screen location.
+    An example of a DirectTouch device is a touchscreen.
+
+'DependentTouch':
+    These devices do not have a direct correlation between a touch location and
+    a position on the screen. Touch events are delivered according to the
+    location of the device's cursor and often need to be interpreted
+    relative to the current position of that cursor. Such interactions are
+    usually the result of a gesture performed on the device, rather than
+    direct manipulation. An example of a DependentTouch device is a
+    trackpad.
+
+A device is identified as only one of the device modes above at any time, and
+the touch mode may change at any time. If a device's touch mode changes, an
+XIDeviceChangedEvent is generated.
+
+[[multitouch-processing]]
+Touch event delivery
+~~~~~~~~~~~~~~~~~~~~
+
+For direct touch devices, the window set for event propagation is the set of
+windows from the root window to the topmost window lying at the co-ordinates
+of the touch.
+
+For dependent devices, the window set for event propagation is the set of
+windows from the root window to the window that contains the device's
+pointer. A dependent device may only have one window set at a time, for all
+touches. Any future touch sequence will use the same window set. The window set
+is cleared when all touch sequences on the device end.
+
+A window set is calculated on TouchBegin and remains constant until the end
+of the sequence. Modifications to the window hierarchy, new grabs or changed
+event selection do not affect the window set.
+
+Pointer control of dependent devices
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+On a dependent device, the device may differ between a pointer-controlling
+touch and a non-pointer-controlling touch. For example, on a touchpad the
+first touch is pointer-controlling (i.e. serves only to move the visible
+pointer). Multi-finger gestures on a touchpad cause all touches to be
+non-pointer-controlling.
+
+For pointer-controlling touches, no touch events are sent; the touch
+generates regular pointer events instead. Non-pointer-controlling touches
+send touch events. A touch may change from pointer-controlling to
+non-pointer-controlling, or vice versa.
+
+- If a touch changes from pointer-controlling to non-pointer-controlling,
+ a new touch ID is assigned and a TouchBegin is sent for the last known
+ position of the touch. Further events are sent as TouchUpdate events, or as
+ TouchEnd event if the touch terminates.
+
+- If a touch changes from non-pointer-controlling to pointer-controlling, a
+  TouchEnd is sent for that touch at the last known position of the touch.
+  Further events are sent as pointer events.
+
+The conditions to switch from pointer-controlling to non-pointer-controlling
+touch is implementation-dependent. A device may support touches that are
+both pointer-controlling and a touch event.
+
+In the dependent touch example event sequence below, touches are marked when
+switching to pointer-controlling (pc) or to non-pointer-controlling (np).
+
+.Dependent touch example event sequence on a touchpad
+[width="50%", options="header"]
+|====================================================
+| Finger 1 | Finger 2 | Event generated(touchid)
+|  down    |          | Motion
+|  move    |          | Motion
+|  move    |          | Motion
+|  (np)    |   down   | TouchBegin(0), TouchBegin(1)
+|  move    |    --    | TouchUpdate(0)
+|   --     |   move   | TouchUpdate(1)
+|   up     |   (pc)   | TouchEnd(0), TouchEnd(1)
+|          |   move   | Motion
+|  down    |   (np)   | TouchBegin(2), TouchBegin(3)
+|  move    |    --    | TouchUpdate(2)
+|   up     |   (pc)   | TouchEnd(2), TouchEnd(3)
+|          |    up    | Motion
+|  down    |          | Motion
+|  (np)    |   down   | TouchBegin(4), TouchBegin(5)
+|  (pc)    |    up    | TouchEnd(4), TouchEnd(5)
+|  move    |          | Motion
+|   up     |          | Motion
+|====================================================
+
+
+[[multitouch-emulation]]
+Pointer emulation from multitouch events
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Touch sequences from direct touch devices may emulate pointer events. Only one
+touch sequence from a device may emulate pointer events at a time; which touch
+sequence emulates pointer events is implementation-dependent.
+
+Pointer events are emulated as follows:
+
+- A TouchBegin event generates a pointer motion event to the location of the
+  touch with the same axis values of the touch event, followed by a button press
+  event for button 1.
+- A TouchUpdate event generates a pointer motion event to the location of the
+  touch and/or to update axis values of the pointer device. The button state
+  as seen from the protocol includes button 1 set.
+- A TouchEnd event generates a pointer motion event to the location of the touch
+  and/or to update the axis values if either have changed, followed by a button
+  release event for button 1. The button state as seen from the protocol
+  includes button 1 set.
+
+If a touch sequence emulates pointer events and an emulated pointer event
+triggers the activation of a passive grab, the grabbing client becomes the
+owner of the touch sequence.
+
+The touch sequence is considered to have been accepted if
+
+- the grab mode is asynchronous, or
+- the grab mode is synchronous and the device is thawed as a result of
+  AllowEvents with AsyncPointer or AsyncDevice
+
+Otherwise, if the button press is replayed by the client, the touch sequence
+is considered to be rejected.
+
+Touch event delivery precedes pointer event delivery. A touch event emulating
+pointer events is delivered:
+
+- as a touch event to the top-most window of the current window set if a
+  client has a touch grab on this window,
+- otherwise, as a pointer event to the top-most window of the current window
+  set if a client has a pointer grab on this window,
+- otherwise, to the next child window in the window set until a grab has been
+  found.
+
+If no touch or pointer grab on any window is active and the last window in the
+window set has been reached, the event is delivered:
+
+- as a touch event to the window if a client has selected for touch events
+  on this window
+- otherwise, as a pointer event to the window if a client has selected for
+  pointer events.
+- otherwise, to the next parent window in the window set until a selection has
+  been found.
+
+Emulated pointer events will have the PointerEmulated flag set. A touch
+event that emulates pointer events has the TouchEmulatingPointer flag set.
+
+[[glossary-notations]]
+Notations used in this document
+-------------------------------
+
+Notation for requests:
+
+    ┌───
+        Name of request
+            name of request field:       type of request field
+            name of request field:       type of request field
+            ▶
+            name of reply field:         type of reply field
+    └───
+
+Notation for events:
+
+    ┌───
+        Name of event
+            name of field:               type of field
+            name of field:               type of field
+    └───
+
+Complex fields are specified in the following notation:
+
+          name of field:                  COMPLEXFIELDTYPE
+
+or, if multiple of these fields exist:
+
+          name of field:                  LISTofCOMPLEXFIELDTYPE
+
+    COMPLEXFIELDTYPE:  { name of subfield:   type of subfield,
+                         name of subfield:   type of subfield }
+
+
+[[glossary-datatypes]]
+Data types
+----------
+
+    BUTTONMASK
+            A binary mask defined as (1 << button number).
+            A SETofBUTTONMASK is a binary OR of zero or more BUTTONMASK.
+
+    DEVICE { DEVICEID, AllDevices, AllMasterDevices }
+            A DEVICE specifies either a DEVICEID or AllDevices or
+            AllMasterDevices.
+
+    DEVICEID { CARD16 }
+            A DEVICEID is a numerical ID for a device currently available in the
+            server. The server may re-use a device ID after a device's removal.
+            The device IDs 0 and 1 are reserved.
+            AllDevices ........ 0
+            AllMasterDevices .. 1
+
+    DEVICEUSE { MasterPointer, MasterKeyboard, SlavePointer,
+                SlaveKeyboard, FloatingSlave }
+            A DEVICEUSE field specifies the current use of a device in the MD/SD
+            device hierarchy. See Section "The Master/Slave device hierarchy"
+            for more information.
+
+    EVENTMASK
+            An EVENTMASK is a binary mask defined as (1 << event type).
+            A SETofEVENTMASK is a binary OR of zero or more EVENTMASK.
+
+    FP1616
+            Fixed point decimal in 16.16 format as one INT16 and one CARD16.
+            The INT16 contains the integral part, the CARD32 the decimal fraction
+            shifted by 16.
+
+    FP3232
+            Fixed point decimal in 32.32 format as one INT32 and one CARD32.
+            The INT32 contains the integral part, the CARD32 the decimal fraction
+            shifted by 32.
+
+    VALUATORMASK
+            A binary mask defined as (1 << valuator number).
+            A SETofVALUATORMASK is a binary OR of zero or more VALUATORMASK.
+
+
+[[errors]]
+Errors
+------
+
+Errors are sent using core X error reports.
+
+    Device
+            A value for a DEVICE argument does not specify a valid DEVICE.
+
+
+[[requests]]
+Requests:
+---------
+
+The server does not guarantee that the length of a reply remains constant in
+future revisions of XI2. A client must always retrieve the exact length of the
+protocol reply from the connection, even if the reply is longer than defined
+for the XI2 version supported by the client.
+Additional bytes in a request may include data supported in later versions of
+XI2. Clients should ignore this data. Padding bytes in XI2 protocol requests
+are required to be 0.
+
+[[requests-xi20]]
+Requests introduced in version 2.0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+[[requests-queryversion]]
+    ┌───
+        XIQueryVersion
+        major_version:          CARD16
+        minor_version:          CARD16
+        ▶
+        major_version:          CARD16
+        minor_version:          CARD16
+    └───
+
+The client sends the highest supported version to the server and the
+server sends the highest version it supports, but no higher than the
+requested version. Major versions changes can introduce incompatibilities
+in existing functionality, minor version changes introduce only backward
+compatible changes.  It is the client's responsibility to ensure that the
+server supports a version which is compatible with its expectations.
+
+    major_version
+        Major XI2 version.
+    minor_version
+        Minor XI2 version.
+
+If major_version is less than 2, a BadValue error occurs.
+
+[[requests-querydevice]]
+    ┌───
+        XIQueryDevice
+        DEVICE                  deviceid
+        ▶
+        num_devices:            CARD16
+        deviceinfo:             LISTofDEVICEINFO
+    └───
+
+    DEVICEINFO { deviceid:              DEVICEID
+                 use:                   DEVICEUSE
+                 attachment:            DEVICEID
+                 enabled:               BOOL
+                 num_classes:           CARD16
+                 name_len:              CARD16
+                 name:                  LISTofCHAR8
+                 classes:               LISTofCLASS }
+
+    CLASS { BUTTONCLASS, KEYCLASS, AXISCLASS, SCROLLCLASS, TOUCHCLASS }
+
+    BUTTONCLASS { type:                 ButtonClass
+                  length:               CARD16
+                  sourceid:             CARD16
+                  buttons_len:          CARD16
+                  state:                SETofBUTTONMASK
+                  labels:               LISTofATOM }
+
+    KEYCLASS    { type:                 KeyClass
+                  length:               CARD16
+                  sourceid:             CARD16
+                  num_keys:             CARD16
+                  keys:                 LISTofCARD32 }
+
+    AXISCLASS   { type:                 AxisClass
+                  length:               CARD16
+                  sourceid:             CARD16
+                  axisnumber:           CARD16
+                  label:                ATOM
+                  min:                  FP3232
+                  max:                  FP3232
+                  value:                FP3232
+                  resolution:           CARD32
+                  mode:                 CARD8 }
+
+    SCROLLCLASS¹ {type:                 ScrollClass
+                  length:               CARD16
+                  sourceid:             CARD16
+                  axisnumber:           CARD16
+                  scroll_type:          SCROLLTYPE
+                  flags:                SETofSCROLLFLAGS
+                  increment:            FP3232 }
+
+    SCROLLTYPE { Vertical, Horizontal }
+
+    SCROLLFLAGS { NoEmulation, Preferred }
+
+    TOUCHCLASS² { type:                 TouchClass
+                  length:               CARD16
+                  sourceid:             CARD16
+                  mode:                 TOUCHMODE
+                  num_touches:          CARD16 }
+
+    TOUCHMODE { DirectTouch, DependentTouch }
+
+    ¹ since XI 2.1
+    ² since XI 2.2
+
+XIQueryDevice details information about the requested input devices.
+
+    devices
+        The device to list. If devices is AllDevices, all enabled and
+        disabled devices are listed. If devices is AllMasterDevices, all
+        enabled and disabled master devices are listed. If devices is a
+        valid DEVICE, only this DEVICE is listed and num_devices is 1.
+    num_devices
+        The number of deviceinfos returned.
+
+Each deviceinfo is detailed as follows:
+
+    deviceid
+        The unique ID of the device. Device IDs may get re-used when a device
+        is removed.
+    use
+        If the device is a master pointer, use is MasterPointer.
+        If the device is a master keyboard, use is MasterKeyboard.
+        If the device is a slave pointer, use is SlavePointer.
+        If the device is a slave keyboard, use is SlaveKeyboard.
+        If the device is a floating slave, use is FloatingSlave.
+    attachment
+        If the device is a master pointer or a master keyboard, attachment
+        specifies the paired master keyboard, or the paired master pointer,
+        respectively.  If the device is a non-floating slave device
+        attachment specifies the master device this device is attached to.
+        If the device is a floating slave, attachment is undefined.
+    enabled
+        Zero if the device is disabled, non-zero otherwise.
+    num_classes
+        Number of classes provided.
+    name_len
+        Length of the name in bytes not including padding.
+    classes
+        Details the available classes provided by the device in an undefined
+        order.
+    name
+        The device's name. padded to a multiple of 4 bytes.
+
+For all classes, type specifies the device class. Clients are required
+to ignore unknown device classes. The length field specifies the length
+of the class in 4 byte units.
+The following classes may occur only once: ButtonClass, KeyClass
+
+    ButtonClass:
+    type
+        Always ButtonClass.
+    length
+        Length in 4 byte units.
+    sourceid
+        The device this class originates from.
+    num_buttons
+        Number of buttons provided by the device.
+    labels
+        List of Atoms specifying the label for each button. An Atom of None
+        specifies an unlabeled button. Buttons are listed in the device-native
+        order regardless of the current button mapping.
+    state
+        The current button mask for this device after button mapping is
+        applied. Each bit representing a button is 1 if this button is
+        logically down, or 0 otherwise. State is a multiple of 4-byte units
+        and always contains at least num_buttons bits.
+
+    KeyClass:
+    type
+        Always KeyClass.
+    length
+        Length in 4 byte units.
+    sourceid
+        The device this class originates from.
+    num_keys
+        Number of keycodes provided by the device.
+    keys
+        List of keycodes provided.
+
+    AxisClass:
+    type
+        Always AxisClass.
+    length
+        Length in 4 byte units.
+    sourceid
+        The device this class originates from.
+    axisnumber
+        Axis number of this axis. The axis number is in device-native
+        order and potential axis mappings are ignored.
+    label
+        Atom specifying the axis name. An Atom of None specifies an unlabeled
+        axis.
+    min
+        Minimum value.
+    max
+        Minimum value.
+    resolution
+        Resolution in counts/meter.
+    mode
+        Relative or Absolute.
+    value
+        Last published axis value (if mode is absolute).
+
+An axis in Relative mode may specify min and max as a hint to the
+client. If no min and max information is available, both must be 0.
+
+    ScrollClass:
+    type
+        Always ScrollClass.
+    axisnumber
+        Axis number that is referred to. This axis number must be listed in
+        the ValuatorClassInfo.
+    scroll_type:
+        Vertical for a vertical scrolling axis, Horizontal for a horizontal
+        scrolling axis.
+    flags:
+        A set of flags that apply to this scroll axis.
+        NoEmulation: no legacy scroll button events are generated for events
+                     on this scrolling axis.
+        Preferred: This axis is the preferred axis for emulating valuator
+                   events from legacy scroll button events.
+    increment:
+        The valuator delta equivalent to one positive unit of scrolling.
+
+A ScrollClass may only exist if the device has at least one ValuatorClass
+and each axisnumber listed in any ScrollClass. Only one ScrollClass may
+exist per ValuatorClass.
+
+    TouchClass:
+    type
+        Always TouchClass.
+    length
+        Length in 4 byte units.
+    sourceid
+        The device this class originates from.
+    mode
+        The device type of the touch device.  This mode may change at runtime.
+    num_touches
+        The maximum number of simultaneous touchpoints the device may send.
+        If num_touches is 0, the number of supported touches is unknown or
+        unlimited.
+
+Devices with a TouchClass emit touch events with the same axes as pointer
+events.
+
+[[requests-selectevents]]
+    ┌───
+        XISelectEvents
+            window:         Window
+            num_masks:      CARD16
+            masks:          LISTofEVENTMASK
+
+    └───
+
+    EVENTMASK { deviceid:          DEVICE,
+                mask_len:          CARD16,
+                mask:              SETofEVENTMASK
+
+    window
+        The window to select the events on.
+    num_masks
+        Number of items in masks.
+    deviceid
+        Numerical deviceid, or AllDevices, or AllMasterDevices.
+    mask_len
+        Length of mask in 4 byte units.
+    mask
+        Event mask. An event mask for an event type T is defined as (1 << T).
+
+XISelectEvents selects for XI2 events on window.
+
+If num_masks is 0, a BadValue error occurs.
+
+Each mask sets the (and overwrites a previous) event mask for the DEVICE
+specified through deviceid. The device AllDevices or
+AllMasterDevices is treated as a separate device by server. A client's
+event mask is the union of AllDevices, AllMasterDevices and the
+per-device event mask.
+The removal of device from the server unsets the event masks for the
+device. If an event mask is set for AllDevices or AllMasterDevices, the
+event mask is not cleared on device removal and affects all future
+devices.
+
+If mask_len is 0, the event mask for the given device is cleared.
+
+The mask for XIHierarchyEvents may only be selected for XIAllDevices.
+Setting it for any other device results in a BadValue error.
+
+A client selecting for any of XI_TouchBegin, XI_TouchUpdate, or XI_TouchEnd
+must select for all three events at the same time, else a BadValue error
+will be generated. A client selecting for XI_TouchOwnership must select for
+all three of the other touch events. If the selection for these touch events
+overlaps a current selection by another client (e.g. selecting for a
+specific device when another client has a selection for XIAllDevices), a
+BadAccess error occurs.
+
+[[requests-getselectedevents]]
+    ┌───
+        XIGetSelectedEvents
+            window:         Window
+            ▶
+            num_masks:      CARD16
+            masks:          LISTofEVENTMASK
+    └───
+
+    window
+        The window to select the events on.
+    num_masks
+        Number of items in masks.
+    masks
+        Selected event masks by this client.
+
+Masks are returned on a per-device basis, with masks for AllDevices and
+AllMasterDevices returned separately. A client can calculate the
+effective mask for a device with a bitwise OR of the AllDevices, the
+AllMasterDevices and the device-specific mask.
+
+If num_masks is 0, no events have been selected by this client on the
+given window.
+
+[[requests-querypointer]]
+    ┌───
+        XIQueryPointer
+            window:         Window
+            deviceid:       DEVICEID
+            ▶
+            root:           Window
+            child:          Window
+            root_x:         FP1616
+            root_y:         FP1616
+            win_x:          FP1616
+            win_y:          FP1616
+            same_screen:    BOOL
+            mods:           MODIFIERINFO
+            group:          GROUPINFO
+            buttons_len:    CARD16
+            buttons:        SETofBUTTONMASK
+    └───
+
+Query a master pointer device for its current position.
+
+    root
+        The root window the pointer is logically on.
+    child
+        The child window of window that contains the pointer or None.
+    root_x
+    root_y
+        Pointer position relative to the root window's origin.
+    win_x
+    win_y
+        Pointer position relative to window or 0 if same_screen is false.
+    same_screen
+        True if window is on the same screen as the pointer.
+    mods
+        XKB modifier state on the paired device.
+    group
+        XKB group state on the paired device.
+    buttons_len
+        The length of buttons in 4 byte units.
+    buttons
+        Button state.
+
+If the device is not a master pointer device or not a floating slave
+pointer, a BadDevice error results.
+
+[[requests-warppointer]]
+    ┌───
+        XIWarpPointer
+            src_win:         Window
+            dst_win:         Window
+            src_x:           FP1616
+            src_y:           FP1616
+            src_width:       INT16
+            src_height:      INT16
+            dst_x:           FP1616
+            dst_y:           FP1616
+            deviceid:        DEVICEID
+    └───
+
+WarpPointer moves the pointer of deviceid as if the user had moved
+the pointer. WarpPointer can only be called for MasterPointer and
+FloatingSlave devices.
+
+    src_win
+       If src_window is not None, the move only takes place if src_window
+       contains the pointer and the pointer is contained in the specified
+       rectangle of src_window.
+    dst_win
+       If dst_win is None, this request moves the pointer by offsets
+       dst_x/dst_y relative to the current position of the pointer. If
+        dst_window is a window, this request moves the pointer to
+       dst_x/dst_y relative to dst_win's origin.
+    src_x
+    src_y
+    src_width
+    src_height
+       Specifies the source window rectangle.
+    dst_x
+    dst_y
+        The relative coordinates to move the pointer if dst_win is None, or
+        the absolute coordinates if dst_win is a window.
+    deviceid
+        The device to warp.
+
+This request cannot be used to move the pointer outside the confine-to
+window of an active pointer grab. An attempt will only move the pointer as
+far as the closest edge of the confine-to window.
+
+This request will generate events just as if the user had instantaneously
+moved the pointer.
+
+[[requests-changecursor]]
+    ┌───
+        XIChangeCursor
+            win:             Window
+            cursor:          Cursor
+            deviceid:        DEVICEID
+    └───
+
+Change a master pointer's cursor on the specified window.
+
+    window
+        The window.
+    cursor
+        The new cursor or None.
+    deviceid
+        The master pointer device.
+
+Whenever device enters a window W, the cursor shape is selected in the
+following order:
+
+- if the current window has a device cursor C(d) defined for device,
+  display this cursor C(d).
+- otherwise, if the current window has a cursor C(w) defined in the core
+  protocol's window attributes, display cursor C(w).
+- repeat on parent window until a cursor has been found.
+
+The device cursor for a given window is reset once the window is destroyed
+or the device is removed, whichever comes earlier.
+
+If deviceid does not specify a master pointer, a BadDevice error
+is returned.
+
+[[requests-changehierarchy]]
+    ┌───
+        XIChangeHierarchy
+            num_changes:     CARD8
+            changes:         LISTofHIERARCHYCHANGES
+    └───
+
+    HIERARCHYCHANGE { ADDMASTER, REMOVEMASTER, ATTACHSLAVE, DETACHSLAVE }
+
+    HIERARCHYCHANGETYPE { AddMaster, RemoveMaster, AttachSlave, DetachSlave }
+
+    CHANGEMODE { Float, Attach }
+
+    ADDMASTER { type:        HIERARCHYCHANGETYPE
+                length:      CARD16
+                name_len:    CARD16
+                send_core:   BOOL
+                enable:      BOOL
+                name:        LISTofCHAR8 }
+
+    REMOVEMASTER { type:            HIERARCHYCHANGETYPE
+                   length:          CARD16
+                   deviceid:        DEVICEID
+                   return_mode:     CHANGEMODE
+                   return_pointer:  DEVICEID
+                   return_keyboard: DEVICEID }
+
+    ATTACHSLAVE   { type:        HIERARCHYCHANGETYPE
+                    length:      CARD16
+                    deviceid:    DEVICEID
+                    master:      DEVICEID }
+
+    DETACHSLAVE { type:       HIERARCHYCHANGETYPE
+                  length:     CARD16
+                  deviceid:   DEVICEID }
+
+XIChangeHierarchy allows a client to modify the
+<<hierarchy,Master/Slave device hierarchy>>.
+
+    num_changes
+        The number of changes to apply to the current hierarchy.
+    changes
+        The list of changes.
+
+The server processes the changes in the order received from the client and
+applies each requested change immediately. If an error occurs, processing
+stops at the current change and returns the number of successfully applied
+changes in the error.
+
+    ADDMASTER creates a pair of master devices.
+    type
+        Always AddMaster.
+    length
+        Length in 4 byte units.
+    name_len
+        Length of name in bytes.
+    send_core
+        True if the device should send core events.
+    enable
+        True if the device is to be enabled immediately.
+    name
+        The name for the new master devices. The master pointer's name is
+        automatically appended with " pointer", the master keyboard's name is
+        automatically appended with " keyboard".
+
+    REMOVEMASTER removes an existing master device.
+    type
+        Always RemoveMaster.
+    length
+        Length in 4 byte units.
+    deviceid
+        The device to remove.
+    return_mode
+        Return mode for attached slave devices.
+        If return_mode is Float, all slave devices are set to floating.
+        If return_mode is Attach, slave pointers are attached to
+        return_pointer and slave keyboards are attached to
+        return_keyboard.
+    return_pointer
+    return_keyboard
+        The master pointer and master keyboard to attach slave devices to, if
+        return_mode is Attach. If return_mode is Float, return_pointer
+        and return_keyboard are undefined.
+
+Removing a master pointer removes the paired master keyboard and vice
+versa.
+
+    ATTACHSLAVE attaches a slave device to a given master device.
+    type
+        Always ChangeAttachment.
+    length
+        Length in 4 byte units.
+    deviceid
+        Deviceid of the slave device.
+    master
+        The new master device to attach this slave device to.
+
+If any clients are selecting for touch events from the slave device, their
+selection will be canceled.
+
+    DETACHSLAVE detaches a slave device from its current master device.
+    type
+        Always ChangeAttachment.
+    length
+        Length in 4 byte units.
+    deviceid
+        Deviceid of the slave device.
+
+[[requests-setclientpointer]]
+    ┌───
+        XISetClientPointer
+            win:             Window
+            deviceid:        DEVICEID
+    └───
+
+Set the ClientPointer for the client owning win to the given device.
+
+    win
+         Window or client ID.
+    deviceid
+         The master pointer or master keyboard that acts as ClientPointer.
+
+Some protocol requests are ambiguous and the server has to choose a device
+to provide data for a request or a reply. By default, the server will
+choose a client's ClientPointer device to provide the data, unless the
+client currently has a grab on another device. See section
+<<clientpointer,The ClientPointer principle>> for more details.
+
+If win is None, the ClientPointer for this client is set to the given
+device. Otherwise, if win is a valid window, the ClientPointer for the
+client owning this window is set to the given device. Otherwise, if win is
+not a valid window but a client with the client mask equal to win exists,
+this client's ClientPointer is set to the given device.
+
+If deviceid does not specify a master pointer or master keyboard, a
+BadDevice error is returned.
+
+If window does not specify a valid window or client ID and is not None, a
+BadWindow error is returned.
+
+[[requests-getclientpointer]]
+    ┌───
+        XIGetClientPointer
+            win:             Window
+            ▶
+            set:             BOOL
+            deviceid:        DEVICEID
+    └───
+
+Query the ClientPointer for the client owning win.
+
+    win
+        The window or client ID.
+    set
+        True if the client has a ClientPointer set.
+    deviceid
+        The master pointer that acts as a ClientPointer if set is True.
+
+No difference is made between a ClientPointer set explicitly through
+XISetClientPointer and a ClientPointer implicitly assigned by the server
+in response to an ambiguous request.
+
+[[requests-setfocus]]
+    ┌───
+        XISetFocus
+            focus:           Window
+            deviceid:        DEVICEID
+            time:            Time
+    └───
+
+Set the focus for the given device to the given window. Future key events
+from this device are sent to this window.
+This request generates FocusIn and FocusOut events.
+
+    focus
+        A viewable window or None.
+    deviceid
+        The device to modify the focus window for.
+    time
+        Specifies the time to change the focus or CurrentTime.
+
+If focus is None, key events from this device are discarded until a new
+focus window is set. If focus is a viewable window, key events from this
+device are sent to this window. If the window becomes unviewable, the
+window's first viewable ancestor automatically becomes the focus window
+and FocusIn and FocusOut events are sent as if a client had changed the
+focus window.
+This is equivalent to RevertToParent in the core XSetInputFocus window.
+
+This request has no effect if the specified time is earlier than the
+current last-focus-change time or is later than the current X server time.
+Otherwise, the last-focus-change time is set to the specified time.
+
+[[requests-getfocus]]
+    ┌───
+        XIGetFocus
+            deviceid:        DEVICEID
+            ▶
+            focus:           Window
+    └───
+
+Return the current focus window for the given device.
+
+[[requests-grabdevice]]
+    ┌───
+        XIGrabDevice
+            deviceid:        DEVICEID
+            grab_window:     Window
+            owner_events:    BOOL
+            grab_mode:       { Synchronous, Asynchronous }
+            paired_device_mode: { Synchronous, Asynchronous }
+            time:            TIMESTAMP or CurrentTime
+            cursor:          Cursor
+            mask_len:        CARD16
+            masks:           SETofEVENTMASK
+            ▶
+            status:          Success, AlreadyGrabbed, Frozen, InvalidTime, NotViewable
+    └───
+
+This request actively grabs control of the specified input device. Further
+input events from this device are reported only to the grabbing client.
+This request overides any previous active grab by this client for this
+device.  This request does not affect the processing of XI 2.2
+touch events.
+
+    deviceid
+        The device to grab.
+    grab_window
+        Events are reported relative to the grab window.
+    owner_events
+        Specifies whether event will be reported normally or relative to the
+        grab window.
+    grab_mode
+        Specifies if this device will be frozen as a result of the grab.
+    paired_device_mode
+        Specifies if the master device paired with this device will be frozen
+        as a result of the grab.
+    time
+        A valid server time or CurrentTime.
+    cursor
+        The cursor to display for the duration of the grab or None.
+    mask_len
+        Length of mask in 4 byte units.
+    mask
+        Event mask. An event mask for an event type T is defined as (1 << T).
+    status
+        Success or the reason why the grab could not be established.
+
+The masks parameter specifies which events the client wishes to receive
+while the device is grabbed.
+
+If owner-events is False, input events generated from this device are
+reported with respect to grab-window, and are only reported if selected by
+being included in the event-list.  If owner-events is True, then if a
+generated event would normally be reported to this client, it is reported
+normally, otherwise the event is reported with respect to the grab-window,
+and is only reported if selected by being included in the event-list. For
+either value of owner-events, unreported events are discarded.
+
+If grab-mode is Asynchronous, device event processing continues normally.
+If the device is currently frozen by this client, then processing of
+device events is resumed. If grab-mode is Synchronous, the state of the
+grabbed device (as seen by means of the protocol) appears to freeze,
+and no further device events are generated by the server until the
+grabbing client issues a releasing XIAllowEvents request or until the
+device grab is released. Actual device input events are not lost while the
+device is frozen; they are simply queued for later processing.
+
+If the device is a slave device, the paired-device-mode is ignored.
+Otherwise, if this device is a master device and paired-device-mode is
+Asynchronous, event processing is unaffected by activation of the grab. If
+this device is a master device and paired-device-mode is Synchronous, the
+state of the master device paired with this device (as seen by means of the
+protocol) appears to freeze, and no further events are generated by the
+server until the grabbing client issues a releasing XIAllowEvents request
+or until the device grab is released. Actual events are not lost while the
+devices are frozen; they are simply queued for later processing.
+
+If the cursor is not None and the device is a master pointer device, the
+cursor will be displayed until the device is ungrabbed.
+
+This request fails and returns:
+
+    AlreadyGrabbed: If the device is actively grabbed by some other client.
+    NotViewable: If grab-window is not viewable.
+    InvalidTime: If the specified time is earlier than the last-grab-time for
+                 the specified device or later than the current X server time.
+                 Otherwise, the last-grab-time for the specified device is set
+                 to the specified time and CurrentTime is replaced by the
+                 current X server time.
+    Frozen: If the device is frozen by an active grab of another client.
+
+To release a grab of a device, use XIUngrabDevice.
+
+[[requests-ungrabdevice]]
+    ┌───
+        XIUngrabDevice
+            deviceid:        DEVICEID
+            time:            TIMESTAMP or CurrentTime
+    └───
+
+This request releases the device if this client has it actively grabbed
+(from either XIGrabDevice or  XIPassiveGrabDevice) and
+releases any queued events. If any devices were frozen by the grab,
+XIUngrabDevice thaws them.
+
+    deviceid
+        The device to grab.
+    time
+        A valid server time or CurrentTime.
+
+The request has no effect if the specified time is earlier than the
+last-device-grab time or is later than the current server time.
+This request generates FocusIn and FocusOut events.
+An XIUngrabDevice is performed automatically if the event window for an
+active device grab becomes not viewable.
+
+[[requests-allowevents]]
+    ┌───
+        XIAllowEvents:
+            deviceid:        DEVICEID
+            time:            TIMESTAMP or CurrentTime
+            event_mode:      { AsyncDevice, SyncDevice,
+                               AsyncPairedDevice, SyncPairedDevice,
+                               ReplayDevice, AsyncPair, SyncPair,
+                               AcceptTouch¹, RejectTouch¹ }
+            touchid¹:        CARD32
+            grab_window¹:    Window
+    └───
+
+    ¹ since XI 2.2
+
+The XIAllowEvents request releases some queued events if the client
+has caused a device to freeze. It also is used to handle touch grab and
+ownership processing.
+
+    deviceid
+        The device to grab.
+    time
+        A valid server time or CurrentTime.
+    event_mode
+        Specifies whether a device is to be thawed and events are to be
+        replayed, or how to handle a grabbed touch sequence.
+    touchid
+        The ID of the touch sequence to accept or reject. The value is undefined
+        for event modes other than AcceptTouch and RejectTouch.
+    grab_window
+        The window on which to accept or reject a touch sequence grab. The value
+        is undefined for event modes other than AcceptTouch and RejectTouch.
+
+The request has no effect if the specified time is earlier than the last-grab
+time of the most recent active grab for the client, or if the specified time is
+later than the current X server time. The time parameter must be CurrentTime for
+requests with event modes of AcceptTouch and RejectTouch.
+
+When event-mode is AcceptTouch, a BadValue error occurs if the touch ID is
+invalid. A BadAccess error occurs if this client is not the current or potential
+owner of the specified touch ID.
+
+The following describes the processing that occurs depending on what constant
+you pass to the event-mode argument:
+
+    AsyncDevice:
+        If the specified device is frozen by the client, event processing for that
+        device continues as usual. If the device is frozen multiple times  by the
+        client on behalf of multiple separate grabs, AsyncDevice thaws for
+        all.
+        AsyncDevice has no effect if the specified device is not frozen by the
+        client, but the device need not be grabbed by the client.
+    SyncDevice:
+        If the specified device is frozen and actively grabbed by the client,
+        event processing for that device continues normally until the next
+        event is reported to the client. At this time, the specified device
+        again appears to freeze. However, if the reported event causes the
+        grab to be released, the specified device does not freeze.
+        SyncDevice has no effect if the specified device is not frozen by the
+        client or is not grabbed by the client.
+     ReplayDevice:
+        If the specified device is actively grabbed by the client and is frozen
+        as the result of an event having been sent to the client (either from
+        the activation of a XIGrabButton or from a previous XIAllowEvents with
+        mode SyncDevice, but not from a Grab), the grab is released and
+        that event is completely reprocessed.  This time, however, the request
+        ignores any passive grabs at or above (towards the root) the
+        grab-window of the grab just released.
+        The request has no effect if the specified device is not grabbed by
+        the client or if it is not frozen as the result of an event.
+     AsyncPairedDevice
+        If the paired master device is frozen by the client, event processing
+        for it continues as usual. If the paired device is frozen multiple
+        times by the client on behalf of multiple separate grabs,
+        AsyncPairedDevice thaws for all.
+        AsyncPairedDevice has no effect if the device is not frozen by the
+        client, but those devices need not be grabbed by the client.
+        AsyncPairedDevice has no effect if deviceid specifies a slave device.
+     SyncPairedDevice
+        If the paired master device is frozen by the client, event processing (for
+        the paired master device) continues normally until the next button or key
+        event is reported to the client for the grabbed device (button event for
+        the grabbed device, key or motion event for the device), at which time
+        the device again appears to freeze. However, if the reported event causes
+        the grab to be released, then the device does not freeze.
+        SyncPairedDevice has no effect if the specified device is not grabbed
+        by the client or if it is no frozen as the result of an event.
+        SyncPairedDevice has no effect if deviceid specifies a slave device.
+     SyncPair
+        If both the device and the paired master device are frozen by the
+        client, event processing (for both devices) continues normally until
+        the next XIButtonPress, XIButtonRelease, XIKeyPress, or XIKeyRelease
+        event is reported to the client for a grabbed device (button event for
+        a pointer, key event for a keyboard), at which time the devices again
+        appear to freeze. However, if the reported event causes the grab to be
+        released, then the devices do not freeze (but if the other device is
+        still grabbed, then a subsequent event for it will still cause both
+        devices to freeze).
+        SyncPair has no effect unless both the device and the paired master
+        device are frozen by the client. If the device or paired master device
+        is frozen twice by the client on behalf of two separate grabs,
+        SyncPair thaws for both (but a subsequent freeze for SyncPair will
+        only freeze each device once).
+        SyncPair has no effect if deviceid specifies a slave device.
+     AsyncPair
+        If the device and the paired master device are frozen by the client,
+        event processing for both devices continues normally. If a device is
+        frozen twice by the client on behalf of two separate grabs, AsyncBoth
+        thaws for both. AsyncPair has no effect unless both the device and the
+        paired master device frozen by the client.
+        AsyncPair has no effect if deviceid specifies a slave device.
+     AcceptTouch
+        The client is deemed to have taken control of the touch sequence once it
+        owns the sequence. TouchEnd events will be sent to all clients listening
+        to the touch sequence that have either grabbed the touch sequence on a
+        child window of the grab_window or have received events for the touch
+        sequence through event selection. These clients will no longer receive
+        any TouchUpdate events.
+     RejectTouch
+        The client is no longer interested in the touch sequence, and will
+        receive a TouchEnd event. If the client is the current owner of the
+        sequence, ownership will be passed on to the next listener.
+
+[[requests-passivegrabdevice]]
+    ┌───
+        XIPassiveGrabDevice
+            deviceid:        DEVICE
+            detail:          CARD32
+            grab_type:       GRABTYPE
+            grab_window:     Window
+            cursor:          Cursor
+            owner_events:    Bool
+            grab_mode:       { Synchronous, Asynchronous, Touch¹ }
+            paired_device_mode: { Synchronous, Asynchronous }
+            num_modifiers:   INT16
+            mask_len:        CARD16
+            masks:           SETofEVENTMASK
+            modifiers:       CARD32 or GrabAnyModifier
+            ▶
+            num_modifiers_return:    INT16
+            modifiers_return:        GRABMODIFIERINFO
+    └───
+
+        GRABTYPE         { GrabtypeButton, GrabtypeKeycode, GrabtypeEnter,
+                           GrabtypeFocusIn, GrabtypeTouchBegin¹ }
+
+        GRABMODIFIERINFO {   status:    Access
+                             modifiers: CARD32 }
+
+    ¹ since XI 2.2
+
+Establish an explicit passive grab for a button or keycode
+on the specified input device.
+
+        cursor
+            The cursor to display for the duration of the grab. If grab_type
+            is not GrabtypeButton, this argument is ignored.
+        deviceid
+            The device to establish the passive grab on or AllDevices or
+            AllMasterDevices.
+        detail
+            The button number, or key symbol to grab for.
+            Must be 0 for GrabtypeEnter, GrabtypeFocusIn, and
+            GrabtypeTouchBegin.
+        grab_type
+            The type of grab to establish.
+        grab_window
+            Events are reported relative to the grab window.
+        grab_mode
+            If grab-mode is Asynchronous, device event processing continues
+            normally.  If the device is currently frozen by this client, then
+            processing of device events is resumed. If grab-mode is
+            Synchronous, the state of the grabbed device (as seen by means of
+            the protocol) appears to freeze, and no further device events are
+            generated by the server until the grabbing client issues a
+            releasing XIAllowEvents request or until the device grab is
+            released. Actual device input events are not lost while the device
+            is frozen; they are simply queued for later processing. If grab_type
+            is GrabtypeTouchBegin, grab_mode must be set to Touch.
+        mask_len
+            Length of mask in 4 byte units.
+        mask
+            Event mask. An event mask for an event type T is defined as (1 << T).
+        modifiers
+            XKB modifier state to activate this passive grab.
+        num_modifiers
+            Number of elements in modifiers.
+        owner_events
+            Specifies whether event will be reported normally or relative to the
+            grab window.
+        num_modifiers_return
+            Number of elements in modifiers_return
+        modifiers_return
+            XKB modifier state that could not be grabbed.
+
+If owner-events is False, input events generated from this device are
+reported with respect to grab-window, and are only reported if
+selected by being included in the event-list.  If owner-events is
+True, then if a generated event would normally be reported to this
+client, it is reported normally, otherwise the event is reported
+with respect to the grab-window, and is only reported if selected
+by being included in the event-list. For either value of
+owner-events, unreported events are discarded.
+
+If deviceid specifies a master pointer, the modifiers of the paired
+master keyboard are used. If deviceid specifies a slave pointer
+the modifiers of the master keyboard paired with the attached master
+pointers are used. If deviceid specifies a slave keyboard, the
+modifiers of the attached master keyboard are used. Note that
+activating a grab on a slave device detaches the device from its
+master. In this case, the modifiers after activation of the grab are
+from the slave device only and may be different to the modifier state
+when the grab was triggered.
+
+In the future, if grab_type is GrabtypeButton or GrabtypeKeyboard, the
+device is actively grabbed if:
+
+        - the device is not grabbed, and
+        - the specified modifier keys are down, and
+        - the grab_type is GrabtypeButton and the button specified in detail
+          is logically pressed or the grab_type is GrabtypeKeycode and the
+          keycode specified in detail is logically pressed, and
+        - the grab_window contains the pointer, and
+        - a passive grab on the same button/keycode + modifier
+          combination does not exist on an ancestor of grab_window.
+
+Otherwise, if grab_type is GrabtypeEnter or GrabtypeFocusIn, the
+device is actively grabbed if:
+
+        - the device is not actively grabbed, and
+        - the specified modifier keys are down, and
+        - the grab_type is GrabtypeEnter and the device's pointer has moved
+          into grab_window or a descendant of grab_window, or the grab_type is
+          GrabtypeFocusIn and the device's focus has been set to the
+          grab_window or a descendant of grab_window, and
+        - a passive grab of the same grab_type + modifier combination does not
+          does not exist on an ancestor of grab_window.
+
+Otherwise, if grab_type is GrabtypeTouchBegin, a touch grab begins if:
+
+        - the device is not actively grabbed, and
+        - the specified modifier keys are down
+        - a touch begins in grab_window or a descendant of grab_window, and
+        - a passive grab of the same grab_type + modifier combination does not
+          does not exist on an ancestor of grab_window.
+
+Ownership of the touch sequence is granted to the grabbing client if:
+
+        - a TouchBegin or pointer grab for an emulated touch sequence of a
+          direct touch device with the same modifier set does not exist on
+          an ancestor of grab_window, or all applicable grabs have released
+          ownership.
+
+A modifier of GrabAnyModifier is equivalent to issuing the request for
+all possible modifier combinations (including no modifiers). A client
+may request a grab for GrabAnyModifier and explicit modifier
+combinations in the same request.
+
+A GrabtypeButton or GrabtypeKeyboard grab is released when all buttons
+or keycode are released, independent of the state of modifier keys.
+A GrabtypeEnter or GrabtypeFocusIn grab is released when the
+pointer or focus leaves the window and all of its descendants,
+independent of the state of modifier keys.
+A GrabtypeTouchBegin grab is released when the touch sequence ends or
+the client uses XIAllowEvents with mode RejectTouch.
+Note that the logical state of a device (as seen by means of the
+protocol) may lag the physical state if device event processing is
+frozen.
+
+This request overrides all previous passive grabs by the same
+client on the same button/key/enter/focus in + modifier combinations
+on the same window.
+
+If some other client already has issued a XIPassiveGrabDevice request
+with the same button or keycode and modifier combination, the
+failed modifier combinations is returned in modifiers_return. If some
+other client already has issued an XIPassiveGrabDevice request of
+grab_type XIGrabtypeEnter, XIGrabtypeFocusIn, or
+XIGrabtypeTouchBegin with the same grab_window and the same
+modifier combination, the failed modifier combinations are returned
+in modifiers_return. If num_modifiers_return is zero, all passive
+grabs have been successful.
+
+If a button grab or enter grab activates, EnterNotify and LeaveNotify
+events with mode Grab are generated as if the pointer were to suddenly
+warp from its current position some position in the grab_window.
+However, the pointer does not warp, and the pointer position is used
+as both the initial and final positions for the events.
+
+If a keycode grab or focus grab activates, FocusIn and FocusOut events
+with mode Grab are generated as if the focus were to change from the
+current window to the grab_window.
+
+If an enter or focus in grab activates, additional EnterNotify events
+with mode XIPassiveGrabNotify are generated as if the pointer or focus
+were to suddenly warp from its current position to some position in
+the grab window.  These events are sent to the grabbing client only
+and only if the grab event mask has selected for it. If such a passive
+grab deactivates, addional LeaveNotify events with mode
+XIPassiveUngrabNotify are generated and sent to the grabbing client
+before the grab deactivates.
+
+For GrabtypeTouchBegin, grab_mode must be Touch or a BadValue error
+is generated.
+
+See section <<multitouch-ownership, Ownership of touch sequences>> for
+additional notes on touch grabs, as they do not behave like traditional
+grabs: in particular, they do not freeze the device, and delivery of touch
+events continues even if the device is frozen due to a grab by another
+client.
+
+[[requests-passiveungrabdevice]]
+    ┌───
+        XIPassiveUngrabDevice
+            deviceid:        DEVICEID
+            detail:          CARD32
+            grab_type:       GRABTYPE
+            grab_window:     Window
+            num_modifiers:   INT16
+            modifiers:       MODIFIERINFO
+    └───
+
+Release an explicit passive grab on the specified input device.
+
+        deviceid
+            The device to establish the passive grab on.
+        detail
+            The button number or key symbol to ungrab.
+            Must be 0 for GrabtypeEnter, GrabtypeFocusIn, and
+            GrabtypeTouchBegin.
+        grab_type
+            The type of grab to establish.
+        grab_window
+            Events are reported relative to the grab window.
+        modifiers
+            XKB modifier state to activate this passive grab.
+        num_modifiers
+            Number of elements in modifiers.
+
+This request has no effect if the client does not have a passive grab
+of the same type, same button or keycode (if applicable) and modifier
+combination on the grab_window.
+
+[[requests-listproperties]]
+    ┌───
+        XIListProperties
+            deviceid:        DEVICEID
+            ▶
+            num_properties:  INT16
+            properties:      LISTofATOM
+    └───
+
+List the properties associated with the given device.
+
+        deviceid
+            The device to list the properties for.
+        num_atoms
+            Number of atoms in the reply
+        atoms
+            All properties on the device.
+
+[[requests-changeproperty]]
+    ┌───
+        XIChangeProperty
+            deviceid:        DEVICEID
+            property:        ATOM
+            type:            ATOM
+            format:          { 8, 16, 32 }
+            mode:            { Append, Prepend, Replace }
+            num_items:       CARD32
+            data:            LISTofINT8, or LISTofINT16, or LISTofINT32
+    └───
+
+Change the given property on the given device.
+
+        deviceid
+            The device to change the property on.
+        property
+            The property to modify.
+        type
+            The property's type.
+        mode
+            One of Append, Prepend, or Replace
+        num_items
+            Number of items following this request.
+        data
+            Property data (nitems * format/8 bytes)
+
+The type is uninterpreted by the server. The format specifies whether
+the data should be viewed as a list of 8-bit, 16-bit, or 32-bit
+quantities so that the server can correctly byte-swap as necessary.
+
+If the mode is Replace, the previous propert y value is discarded.  If
+the mode is Prepend or Append, then the type and format must match the
+existing property value (or a Match error results). If the property is
+undefined, it is treated as defined with the correct type and format
+with zero-length data. For Prepend, the data is tacked on to the
+beginning of the existing data, and for Append, it is tacked on to the
+end of the existing data.
+
+The lifetime of a property is not tied to the storing client. Properties
+remain until explicitly deleted, until the device is removed, or
+until server reset.
+
+A property cannot be deleted by setting nitems to zero. To delete a
+property, use XIDeleteProperty.
+
+This request generates an XIPropertyEvent.
+
+[[requests-deleteproperty]]
+    ┌───
+        XIDeleteProperty
+            deviceid:        DEVICEID
+            property:        ATOM
+    └───
+
+Deletes the given property on the given device.
+
+        deviceid
+            The device to delete the property on.
+        property
+            The property to delete.
+
+If the property is deleted, an XIPropertyEvent is generated on the device.
+If the property does not exist, this request does nothing.
+
+[[requests-getproperty]]
+    ┌───
+        XIGetProperty
+            deviceid:        DEVICEID
+            property:        ATOM
+            type:            Atom or AnyPropertyType
+            offset:          CARD32
+            len:             CARD32
+            delete:          BOOL
+            ▶
+            type:            Atom
+            bytes_after:     CARD32
+            num_items:       CARD32
+            format:          { 8, 16, 32 }
+            data:            LISTofINT8, or LISTofINT16, or LISTofINT32
+    └───
+
+Get the data for the given property on the given device.
+
+        deviceid
+            The device to retrieve the property data from.
+        property
+            The property to retrieve the data from..
+        type
+            The property type to retrieve or AnyPropertyType
+        offset
+            The offset in 4-byte units.
+        len
+            Number of bytes to receive in 4-byte units.
+        delete
+            Delete the property after retrieving the data.
+        bytes_after
+            Number of unread bytes in the stored property
+        num_items
+            Number of items in data
+        format
+            8, 16, or 32
+        data
+            Property data (nitems * format/8 bytes)
+
+If the specified property does not exist for the specified device, then
+the return type is None, the format and bytes-after are zero, and the value is
+empty. The delete argument is ignored in this case. If the specified property
+exists but its type does not match the specified type, then the return
+type is the actual type of the property, the format is the actual format of the
+property (never zero), the bytes-after is the length of the property in bytes
+(even if the format is 16 or 32), and the value is empty. The delete
+argument is ignored in this case. If the specified property exists and
+either AnyPropertyType is specified or the specified type matches the actual
+type of the property, then the return type is the actual type of the property,
+the format is the actual format of the property
+(never zero), and the bytes-after and value are as follows, given:
+         N = actual length of the stored property in bytes
+            (even if the format is 16 or 32)
+         I = 4 * long-offset
+         T = N−I
+         L = MINIMUM(T, 4 * long-length)
+         A = N − (I + L)
+The returned value starts at byte index I in the property (indexing
+from 0), and its length in bytes is L. However, it is a Value error if
+offset is given such that L is negative. The value of bytes_after is A,
+giving the number of trailing unread bytes in the stored property. If
+delete is True and the bytes_after is zero, the property is also
+deleted from the device, and a XIPropertyNotify event is generated on
+the device.  
+     
+[[events]]
+Events
+------
+
+An event specifies its length in 4-byte units after the initial 32 bytes.
+Future versions of the protocol may provide additional information
+in the same event, thus increasing the event size. Clients are required to
+always read the number of bytes specified by the event, not the size of the
+event they may have been compiled against.
+
+
+The following event types are available in XI2.
+
+Version 2.0:
+
+        - HierarchyChanged
+        - DeviceChanged
+        - KeyPress
+        - KeyRelease
+        - ButtonPress
+        - ButtonRelease
+        - Motion
+        - RawKeyPress
+        - RawKeyRelease
+        - RawButtonPress
+        - RawButtonRelease
+        - RawMotion
+        - Enter
+        - Leave
+        - FocusIn
+        - FocusOut
+        - PropertyEvent
+
+Version 2.2:
+
+        - TouchBegin
+        - TouchUpdate
+        - TouchOwnership
+        - TouchEnd
+        - RawTouchBegin
+        - RawTouchUpdate
+        - RawTouchEnd
+
+All events have a set of common fields specified as EVENTHEADER.
+
+
+    EVENTHEADER { type:                       BYTE
+                  extension:                  BYTE
+                  sequenceNumber:             CARD16
+                  length:                     CARD32
+                  evtype:                     CARD16
+                  deviceid:                   DEVICEID
+                  time:                       Time }
+
+    type
+        Always GenericEvent.
+    extension
+        Always the X Input extension offset.
+    sequenceNumber
+        Sequence number of last request processed by the server.
+    length
+        Length in 4-byte units after the initial 32 bytes.
+    evtype
+        XI-specific event type.
+    deviceid
+        Numerical device id for a device.
+    time
+        Time in ms when the event occurred.
+
+
+[[events-xi20]]
+Events introduced in version 2.0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+[[events-hierarchyevent]]
+    ┌───
+        HierarchyEvent:
+            EVENTHEADER
+            flags:                      SETofHIERARCHYMASK
+            num_info:                   CARD16
+            info:                       LISTofHIERARCHYINFO
+    └───
+
+
+    HIERARCHYMASK { MasterAdded, MasterRemoved, SlaveAttached, SlaveDetached,
+                    SlaveAdded, SlaveRemoved, DeviceEnabled, DeviceDisabled }
+
+    HIERARCHYINFO { deviceid:           DEVICEID,
+                    attachment:         DEVICEID,
+                    type:               DEVICEUSE
+                    enabled:            BOOL
+                    flags:              SETofHIERARCHYMASK}
+
+    flags
+        Set of the changes that have occured, causing this event.
+    num_info
+        The number of device info structs following the request.
+    info:
+        The current hierarchy information.
+
+An XIHierarchyEvent is sent whenever the device hierarchy been
+changed. The flags specify all types of hierarchy modifiations that have
+occured.
+For all devices, info details the hierarchy information after the
+modification of the hierarchy has occured. For each device specified with
+deviceid:
+
+- if type is MasterPointer or MasterKeyboard, attachment decribes the
+  pairing of this device.
+- if type is SlavePointer or SlaveKeyboard, attachment describes the
+  master device this device is attached to.
+- if type is FloatingSlave device, attachment is undefined.
+
+    enabled
+         True if the device is enabled and can send events. A disabled master
+         device will not forward events from an attached, enabled slave
+         device.
+
+Note: Multiple devices may be affected in one hierarchy change,
+deviceid in an XIHierarchyEvent is always the first affected
+device. Clients should ignore deviceid and instead use the devices list.
+
+[[events-devicechangedevent]]
+    ┌───
+        DeviceChangedEvent:
+            EVENTHEADER
+            reason:                CHANGEREASON
+            source:                DEVICEID
+            num_classes:           CARD16
+            classes:               LISTofCLASS
+    └───
+
+    CHANGEREASON { SlaveSwitch, DeviceChange }
+
+A DeviceChangeEvent is sent whenever a device changes it's capabilities.
+This can happen either by a new slave device sending events through a
+master device, or by a physical device changing capabilities at runtime.
+
+    reason
+        The reason for generating this event.
+        If reason is SlaveSwitch, the slave device sending events through
+        this device has changed and source specifies the new slave device.
+        A SlaveSwitch reason can only occur on a master device.
+        If reason is DeviceChange, the device itself has changed through
+        other means (e.g. a physical device change) and source is
+        the device itself.
+    source
+        The source of the new classes.
+    num_classes
+        Number of classes provided.
+    classes
+        Details the available classes provided by the device.  The order the
+        classes are provided in is undefined.
+
+For a detailed description of classes, see the XIQueryDevice request.
+
+[[events-deviceevent]]
+    ┌───
+        DeviceEvent:
+            EVENTHEADER
+            detail:                     CARD32
+            root:                       Window
+            event:                      Window
+            child:                      Window
+            root_x:                     FP1616
+            root_y:                     FP1616
+            event_x:                    FP1616
+            event_y:                    FP1616
+            buttons_len:                CARD16
+            valuators_len:              CARD16
+            sourceid:                   DEVICEID
+            mods:                       MODIFIERINFO
+            group:                      GROUPINFO
+            flags:                      DEVICEEEVENTFLAGS
+            buttons:                    SETofBUTTONMASK
+            valuators:                  SETofVALUATORMASK
+            axisvalues:                 LISTofFP3232
+    └───
+
+    BUTTONBIT { (1 << Button1), (1 << Button2), ... , (1 << ButtonN) }
+    VALUATORBIT { (1 << 1), ( 1 << 2), ... ( 1 << n) }
+
+    MODIFIERINFO  { base_mods:           CARD32,
+                    latched_mods:        CARD32,
+                    locked_mods:         CARD32,
+                    effective_mods:      CARD32}
+    GROUPINFO     { base_group:          CARD8,
+                    latched_group:       CARD8,
+                    locked_group:        CARD8,
+                    effective_group:     CARD8}
+
+    DEVICEEVENTFLAGS (all events): none
+    DEVICEEVENTFLAGS (key events only): { KeyRepeat }
+    DEVICEEVENTFLAGS (pointer events only): { PointerEmulated }
+    DEVICEEVENTFLAGS (touch events only): { TouchPendingEnd,
+                                            TouchEmulatingPointer }
+
+An XIDeviceEvent is generated whenever the logical state of a device
+changes in response to a button press, a button release, a motion, a key
+press or a key release. The event type may be one of KeyPress,
+KeyRelease, ButtonPress, ButtonRelease, Motion.
+
+XI 2.2: The event type may also be TouchBegin, TouchUpdate, or TouchEnd.
+
+    detail
+        The button number, key code, touch ID, or 0.
+    root
+    event
+    child
+        The root window, event window or subwindow, respectively. See core
+        protocol specification for more detail.
+    root_x
+    root_y
+        The position of the pointer in screen coordinates (16.16 fixed point).
+    event_x
+    event_y
+        The position of the pointer in screen coordinates relative to the
+        event window (16.16 fixed point).
+
+    buttons_len
+        The length of buttons in 4 byte units.
+    valuators_len
+        The length of valuators in 4 byte units.
+    sourceid
+        The source device that originally generated the event.
+    mods
+        XKB modifier state before the event occured.
+    group
+        XKB group state before the event.
+    buttons
+        Button state before the event.
+    valuators
+        Bitmask of valuators provided in axisvalues.
+    axisvalues
+        Valuator data in device-native resolution.
+    flags
+        Miscellaneous information about this event; the union of the
+        common flag set and either the key or pointer flag set,
+        depending on the event type.
+        KeyRepeat means that this event is for repeating purposes, and
+        the physical state of the key has not changed.  This is only
+        valid for KeyPress events.
+        PointerEmulated signals that the event has been emulated from another
+        XI 2.x event for legacy client support, and that this event should
+        be ignored if the client listens for these events.  This flag is
+        set on scroll ButtonPress and RawButtonPress events (buttons 4, 5, 6
+        and 7) if a smooth-scrolling event on the Rel Vert Scroll or
+        Rel Horiz Scroll axes was also generated. It is also set on Motion,
+        ButtonPress, and ButtonRelease events generated by direct touch devices.
+        TouchPendingEnd (for touch events only) means that the touch
+        has physically ended, however another client still holds a grab, so the
+        touch should be considered alive until all grabbing clients have
+        accepted or passed on ownership.  The touch will not generate any
+        further TouchUpdate events once an event with TouchPendingEnd has been
+        received.
+        TouchEmulatingPointer is set on touch events that emulate pointer
+        events.
+
+Modifier state in mods is detailed as follows:
+
+    base_mods
+        XKB base modifier state.
+    latched_mods
+        XKB latched modifier state.
+    locked_mods
+        XKB locked modifier state.
+
+    Group state in group is detailed as follows:
+    base_group
+        XKB base group state.
+    latched_group
+        XKB latched group state.
+    locked_group
+        XKB locked group state.
+
+In servers supporting XI 2.2, a TouchBegin event is generated whenever a new
+touch sequence initializes.
+A TouchEnd event is generated whenever a touch sequence ceases. A
+TouchUpdate event is generated whenever a valuator value changes, or a flag
+flag (e.g. pending end) has changed for that touch sequence; this may result
+in a TouchUpdate event being sent with zero valuators.
+
+The average finger size is significantly larger than one pixel. The
+selection of the hotspot of a touchpoint is implementation dependent and
+may not be the logical center of the touch.
+
+Touch tracking IDs are provided in the detail field of touch events. Its
+value is always provided in every touch event. Tracking IDs are
+represented as unsigned 32-bit values and increase strictly monotonically in
+value for each new touch, wrapping back to 0 upon reaching the numerical limit
+of IDs. The increment between two touch IDs is indeterminate. Clients may not
+assume that any future touches will have specific touch IDs. IDs are globally
+unique.
+
+The button state in touch events represents the state of the device's
+physical buttons only, even if that sequence is emulating pointer events.
+
+Touch events do not generate enter/leave events.
+
+[[events-rawevent]]
+    ┌───
+        RawEvent
+            EVENTHEADER
+            detail:                    CARD32
+            sourceid¹:                 DEVICEID
+            flags:                     DEVICEEVENTFLAGS
+            valuators_len:             CARD16
+            valuators:                 SETofVALUATORMASK
+            axisvalues:                LISTofFP3232
+            axisvalues_raw:            LISTofFP3232
+    └───
+
+    ¹ since XI 2.1
+
+A RawEvent provides the information provided by the driver to the
+client. RawEvent provides both the raw data as supplied by the driver and
+transformed data as used in the server. Transformations include, but are
+not limited to, axis clipping and acceleration.
+Transformed valuator data may be equivalent to raw data. In this case,
+both raw and transformed valuator data is provided.
+RawEvents are sent exclusively to all root windows.
+Clients supporting XI 2.0 receive raw events when the device is not grabbed,
+or when the device is grabbed by the client but not when the device is
+grabbed by another client.
+Clients supporting XI 2.1 or later receive raw events at all times, even
+when the device is grabbed by another client.
+
+
+    eventtype
+        The type of event that occured on the device.
+    detail
+        The button number, keycode or touch ID¹.
+    sourceid
+        The source device that originally generated the event. The sourceid
+        is undefined for clients not supporting XI 2.1.
+    flags
+        Flags as described in DeviceEvent.
+    valuators_len
+        The length of valuators in 4 byte units.
+    valuators
+        Bitmask of valuators provided in axisvalues and axisvalues_raw.
+    axisvalues
+        Valuator data in device-native resolution.
+    axisvalues_raw
+        Untransformed valuator data in device-native resolution.
+
+    ¹ since XI 2.2
+
+[[events-enterleave]]
+    ┌───
+        Enter or Leave or FocusIn or FocusOut
+            EVENTHEADER
+            root:               Window
+            event:              Window
+            child:              Window
+            sourceid:           DEVICEID
+            root_x:             FP1616
+            root_y:             FP1616
+            event_x             FP1616
+            event_y:            FP1616
+            mode:               NOTIFYMODE
+            detail:             NOTIFYDETAIL
+            same_screen:        BOOL
+            focus:              BOOL
+            mods:               MODIFIERINFO
+            group:              GROUPINFO
+            buttons_len:        CARD16
+            buttons:            SETofBUTTONMASK
+    └───
+
+    NOTIFYMODE { Normal, Grab, Ungrab }
+    NOTIFYDETAIL { Ancestor, Virtual, Inferior, Nonlinear, NonlinearVirtual,
+                   Pointer, PointerRoot, None }
+
+Enter or Leave events are sent whenever a device's pointer enters or
+leaves a window.
+FocusIn or FocusOut events are sent whenever a device's focus is set to or
+away from a window.
+The enter/leave and focus in/out model is described in the core protocol
+specification, Section 11. (EnterNotify, LeaveNotify events).
+
+For enter and leave events, the modifier and group state is the state of
+the paired master device if the device is a master device, or the state of
+the attached master keyboard if the device is an attached slave device, or
+zero if the device is a floating slave device.
+
+For focus in and out events, the button state is the state of the paired
+master device if the device is a master device, or the state of the
+attached master keyboard if the device is an attached slave device, or
+zero if the device is a floating slave device.
+
+    root
+    event
+    child
+        The root window, event window, and child window, respectively. See the
+        core protocol specification for more detail.
+    sourceid
+        The device that caused the pointer to move.
+    root_x
+    root_y
+        The pointer coordinates relative to the root window.
+    event_x
+    event_y
+        The pointer coordinates relative to the event window.
+    mode
+        Normal pointer motion events have mode Normal. Pseudo-motion events
+        when a grab activates have mode Grab, and pseudo-motion events when a
+        grab deactivates have mode Ungrab. Pseudo-motion events caused by the
+        activation or deactivation of a passive enter or focus in grab have mode
+        XIPassiveGrabNotify or XIPassiveUngrabNotify.
+    detail
+        Specifies the relation of the event window to the window the pointer
+        entered or left. See the core protocol spec for details.
+    same_screen
+        True if the event window is on the same screen as the pointer's root
+        window.
+    focus
+        If the event window is the focus window or an inferior of the focus
+        window, then focus is True. Otherwise, focus is False. This field is
+        unspecified for focus in/out events.
+    mods
+        XKB modifier state before the event occured.
+    group
+        XKB group state before the event.
+    buttons_len
+        The length of buttons in 4 byte units.
+    buttons
+        Button state before the event.
+
+[[events-propertyevent]]
+    ┌───
+        XIPropertyEvent
+            EVENTHEADER
+            property:           ATOM
+            what:               { PropertyCreated, PropertyDeleted, PropertyModified }
+    └───
+
+XIPropertyEvents are sent whenever a device property is created, deleted or
+modified by a client.
+
+    property
+        The property that has been created, deleted, or modified
+    what
+        Specifies what has been changed.
+     
+[[events-xi22]]
+Events introduced in version 2.2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+[[events-touchownershipevent]]
+    ┌───
+        TouchOwnershipEvent
+            EVENTHEADER
+            touchid:                    CARD32
+            root:                       Window
+            event:                      Window
+            child:                      Window
+            sourceid:                   DEVICEID
+            flags:                      SETofTOUCHOWNERSHIPFLAGS
+    └───
+
+    TOUCHOWNERSHIPFLAGS:    (none currently defined)
+
+A TouchOwnershipEvent indicates that ownership has changed, and the client
+is now the owner of the touch sequence specified by touchid.
+
+    touchid
+        The identifier of the touch sequence.
+    root
+    event
+    child
+        The root window, event window, and child window, respectively. See the
+        core protocol specification for more detail.
+    sourceid
+        The source device that originally generated the event.
+    flags
+        A bitmask of flags for this event.
+
+
+:numbered!:
+[[xi22-usecases]]
+[appendix]
+XI 2.2 Use-cases
+----------------
+
+All use-cases that include the receiving and processing of touch events
+require the client to announce XI 2.2 support in the XIQueryVersion request.
+
+Client C wants to process touch events from a device D on window W.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* C calls XISelectEvent for XI_Touch{Begin|Update|End} from D on W.
+* C receives TouchBegin whenever a touch sequence starts within W's borders.
+* C receives TouchUpdate events whenever an axis valuator value changes for a
+   touch sequence it received a TouchBegin event for.
+* C receives TouchEnd whenever a touch it received a TouchBegin event for
+   ceases.
+
+While client I wants to pre-process touch events from device D on the parent window  of W.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+* C calls XISelectEvent for XI_Touch{Begin|Update|Ownership|End} from D on W.
+* I calls XIPassiveGrab for XI_Touch{Begin|Update|Ownership|End} from D on a
+   parent window of W.
+* I receives TouchBegin whenever a touch begins within window W, as well as a
+   TouchOwnership event indicating that it currently owns the touch sequence.
+   C receives a TouchBegin event as well, but without TouchOwnership.
+* When an axis valuator changes in this touch sequence, both I and C receive a
+   TouchUpdate event.  I may process the event to determine if it is going to
+   accept or reject the touch, whereas C may perform reversible processing.
+* If I decides it is going to claim the touch sequence for its exclusive
+   processing, it calls XIAllowEvents with an event mode of XIAcceptTouch; at
+   this point, C receives a TouchEnd event, and undoes any processing it has
+   already performed due to the touch sequence.  Further TouchUpdate events are
+   delivered only to I.
+* Alternatively, if I decides it does not want to receive further events
+   from this touch sequence, it calls XIAllowEvents with an event mode of
+   XIRejectTouch; at this point, I receives a TouchEnd event confirming that it
+   has rejected the touch.  C receives a TouchOwnership event confirming that it
+   is now the new owner of the touch, and further TouchUpdate events are
+   delivered only to C.  As C now owns the touch, it is free to perform
+   irreversible processing of the sequence.
+* When the touch physically ceases, a TouchEnd event is sent to C.
+
+While client I wants to process pointer events on window W's parent, window Y.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+* I calls XIPassiveGrab for XI_{ButtonPress,MotionNotify,ButtonRelease} to
+   create a synchronous pointer grab from D on Y.
+* C calls XISelectEvent for XI_Touch{Begin|Update|Ownership|End} from D on W.
+* I receives a ButtonPress event whenever a touch begins within W, and is
+   considered the owner of the event.  C receives a TouchBegin event, but does
+   not receive a TouchOwnership event.
+* When the touchpoint moves, C will receive a TouchUpdate event.  Event
+   delivery to I is subject to the synchronous delivery mechanism. The
+   emulated motion notify event is queued in the server while the device is
+   frozen.
+* I may assert ownership by calling XIAllowEvents on Y with any mode other
+   than ReplayDevice, which will cause all further events to be sent only to I,
+   with a TouchEnd event being sent to C.
+* Alternatively, I may reject the touch sequence by calling XIAllowEvents on
+   Y with mode ReplayDevice, which will cause no further events from that touch
+   to be sent to I, and a TouchOwnership event to be sent to C, with subsequent
+   motion events being sent as TouchUpdate events.
+
+Driver DRV provides touch support from tracked device D:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* DRV initializes a TouchClass for the device.
+* DRV parses D's device protocol and selects one touch sequence to be emulated
+   as pointer event.
+* DRV calls the respective input driver API with the touch sequence data. The
+   touch sequence emulating a pointer has the respective flag set. DRV does not
+   submit pointer data for any touchpoint.
diff --git a/specs/XIproto.txt b/specs/XIproto.txt
new file mode 100644 (file)
index 0000000..1095a26
--- /dev/null
@@ -0,0 +1,2576 @@
+X11 Input Extension Protocol Specification
+==========================================
+
+                      Version 1.0
+                   X Consortium Standard
+                 X Version 11, Release 6.8
+               Mark Patrick, Ardent Computer
+               George Sachs, Hewlett-Packard
+
+                      Version 1.5
+                    Peter Hutterer
+
+   Copyright © 1989, 1990, 1991 by Hewlett-Packard Company and
+   Ardent Computer
+
+   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. Ardent and
+   Hewlett-Packard make no representations about the suitability
+   for any purpose of the information in this document. It is
+   provided "as is" without express or implied warranty. Copyright
+   © 1989, 1990, 1991, 1992 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. X
+   Window System is a trademark of The Open Group.
+
+   Copyright © 2008 by Peter Hutterer
+
+   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.
+
+1. Input Extension Overview
+---------------------------
+
+This document defines an extension to the X11 protocol to
+support input devices other than the core X keyboard and
+pointer. An accompanying document defines a corresponding
+extension to Xlib (similar extensions for languages other than
+C are anticipated). This first section gives an overview of the
+input extension. The next section defines the new protocol
+requests defined by the extension. We conclude with a
+description of the new input events generated by the additional
+input devices.
+
+This document only describes the behaviour of servers supporting
+up to the X Input Extension 1.5. For servers supporting the X
+Input Extensions 2.0, see XI2proto.txt. New clients are discouraged
+from using this protocol specification. Instead, the use of XI 2.x
+is recommended.
+
+1.1 Design Approach
+~~~~~~~~~~~~~~~~~~~
+
+The design approach of the extension is to define requests and
+events analogous to the core requests and events. This allows
+extension input devices to be individually distinguishable from
+each other and from the core input devices. These requests and
+events make use of a device identifier and support the
+reporting of n-dimensional motion data as well as other data
+that is not reportable via the core input events.
+
+1.2 Core Input Devices
+~~~~~~~~~~~~~~~~~~~~~~
+
+The X server core protocol supports two input devices: a
+pointer and a keyboard. The pointer device has two major
+functions. First, it may be used to generate motion information
+that client programs can detect. Second, it may also be used to
+indicate the current location and focus of the X keyboard. To
+accomplish this, the server echoes a cursor at the current
+position of the X pointer. Unless the X keyboard has been
+explicitly focused, this cursor also shows the current location
+and focus of the X keyboard. The X keyboard is used to generate
+input that client programs can detect.
+
+In servers supporting XI 1.4 and above, the core pointer and
+the core keyboard are virtual devices that do not represent a
+physical device connected to the host computer.
+In servers supporting XI 2.0 and above, there may be multiple
+core pointers and keyboards. Refer to XI2proto.txt for more
+information.
+
+The X keyboard and X pointer are referred to in this document
+as the core devices, and the input events they generate
+(KeyPress, KeyRelease, ButtonPress, ButtonRelease, and
+MotionNotify) are known as the core input events. All other
+input devices are referred to as extension input devices and
+the input events they generate are referred to as extension
+input events.
+
+In servers supporting only XI 1.x, this input extension does
+not change the behavior or functionality of the core input
+devices, core events, or core protocol requests, with the
+exception of the core grab requests. These requests may affect
+the synchronization of events from extension devices. See the
+explanation in the section titled "Event Synchronization and
+Core Grabs".
+
+Selection of the physical devices to be initially used by the
+server as the core devices is left implementation-dependent.
+Requests are defined that allow client programs to change which
+physical devices are used as the core devices.
+
+1.3 Extension Input Devices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The input extension v1.x controls access to input devices other
+than the X keyboard and X pointer. It allows client programs to
+select input from these devices independently from each other
+and independently from the core devices.
+
+A client that wishes to access a specific device must first
+determine whether that device is connected to the X server.
+This is done through the ListInputDevices request, which will
+return a list of all devices that can be opened by the X
+server. A client can then open one or more of these devices
+using the OpenDevice request, specify what events they are
+interested in receiving, and receive and process input events
+from extension devices in the same way as events from the X
+keyboard and X pointer. Input events from these devices are of
+extension types ( DeviceKeyPress, DeviceKeyRelease,
+DeviceButtonPress, DeviceButtonRelease, DeviceMotionNotify,
+etc.) and contain a device identifier so that events of the
+same type coming from different input devices can be
+distinguished.
+
+Any kind of input device may be used as an extension input
+device. Extension input devices may have 0 or more keys, 0 or
+more buttons, and may report 0 or more axes of motion. Motion
+may be reported as relative movements from a previous position
+or as an absolute position. All valuators reporting motion
+information for a given extension input device must report the
+same kind of motion information (absolute or relative).
+
+This extension is designed to accommodate new types of input
+devices that may be added in the future. The protocol requests
+that refer to specific characteristics of input devices
+organize that information by input classes. Server implementors
+may add new classes of input devices without changing the
+protocol requests. Input classes are unique numbers registered
+with the X Consortium. Each extension input device may support
+multiple input classes.
+
+In XI 1.x, all extension input devices are treated like the
+core X keyboard in determining their location and focus. The
+server does not track the location of these devices on an
+individual basis, and therefore does not echo a cursor to
+indicate their current location. Instead, their location is
+determined by the location of the core X pointer. Like the core
+X keyboard, some may be explicitly focused. If they are not
+explicitly focused, their focus is determined by the location
+of the core X pointer.
+
+Most input events reported by the server to a client are of
+fixed size (32 bytes). In order to represent the change in
+state of an input device the extension may need to generate a
+sequence of input events. A client side library (such as Xlib)
+will typically take these raw input events and format them into
+a form more convenient to the client.
+
+1.4 Event Classes
+-----------------
+
+In the core protocol a client registers interest in receiving
+certain input events directed to a window by modifying that
+window's event-mask. Most of the bits in the event mask are
+already used to specify interest in core X events. The input
+extension specifies a different mechanism by which a client can
+express interest in events generated by this extension.
+
+When a client opens a extension input device via the OpenDevice
+request, an XDevice structure is returned. Macros are provided
+that extract 32-bit numbers called event classes from that
+structure, that a client can use to register interest in
+extension events via the SelectExtensionEvent request. The
+event class combines the desired event type and device id, and
+may be thought of as the equivalent of core event masks.
+
+1.5 Input Classes
+~~~~~~~~~~~~~~~~~
+
+Some of the input extension requests divide input devices into
+classes based on their functionality. This is intended to allow
+new classes of input devices to be defined at a later time
+without changing the semantics of these requests. The following
+input device classes are currently defined:
+
+   KEY
+          The device reports key events.
+
+   BUTTON
+          The device reports button events.
+
+   VALUATOR
+          The device reports valuator data in motion events.
+
+   PROXIMITY
+          The device reports proximity events.
+
+   FOCUS
+          The device can be focused and reports focus events.
+
+   FEEDBACK
+          The device supports feedbacks.
+
+   OTHER
+          The ChangeDeviceNotify, DeviceMappingNotify, and
+          DeviceStateNotify macros may be invoked passing the
+          XDevice structure returned for this device.
+
+Each extension input device may support multiple input classes.
+Additional classes may be added in the future. Requests that
+support multiple input classes, such as the ListInputDevices
+function that lists all available input devices, organize the
+data they return by input class. Client programs that use these
+requests should not access data unless it matches a class
+defined at the time those clients were compiled. In this way,
+new classes can be added without forcing existing clients that
+use these requests to be recompiled.
+
+2. Requests
+-----------
+
+Extension input devices are accessed by client programs through
+the use of new protocol requests. This section summarizes the
+new requests defined by this extension. The syntax and type
+definitions used below follow the notation used for the X11
+core protocol.
+
+2.1 Getting the Extension Version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The GetExtensionVersion request returns version information
+about the input extension.
+
+                    GetExtensionVersion
+                            name: STRING
+                    =>
+                            present: BOOL
+                            protocol-major-version: CARD16
+                            protocol-minor-version: CARD16
+
+The protocol version numbers returned indicate the version of
+the input extension supported by the target X server. The
+version numbers can be compared to constants defined in the
+header file XI.h. Each version is a superset of the previous
+versions.
+
+The name must be the name of the Input Extension as defined
+in the header file XI.h.
+
+2.2 Listing Available Devices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A client that wishes to access a specific device must first
+determine whether that device is connected to the X server.
+This is done through the ListInputDevices request, which will
+return a list of all devices that can be opened by the X
+server.
+
+                ListInputDevices
+                =>
+                input-devices: ListOfDeviceInfo
+
+where
+
+                DEVICEINFO:
+                        [type: ATOM
+                         id: CARD8
+                         num_classes: CARD8
+                         use: {IsXKeyboard, IsXPointer, IsXExtensionPointer,
+                               IsXExtensionKeyboard, IsExtensionDevice}
+                         info: LISTofINPUTINFO
+                         name: STRING8]
+
+                INPUTINFO: {KEYINFO, BUTTONINFO, VALUATORINFO}
+                KEYINFO:
+                        [class: CARD8
+                         length: CARD8
+                         min-keycode: KEYCODE
+                         max-keycode: KEYCODE
+                         num-keys: CARD16]
+                BUTTONINFO:
+                        [class: CARD8
+                         length: CARD8
+                         num-buttons: CARD16]
+                VALUATORINFO:
+                        [class: CARD8
+                         length: CARD8
+                         num_axes: CARD8
+                         mode: SETofDEVICEMODE
+                         motion_buffer_size: CARD32
+                         axes: LISTofAXISINFO]
+
+                AXISINFO:
+                        [resolution: CARD32
+                         min-val: CARD32
+                         max-val: CARD32]
+                DEVICEMODE: {Absolute, Relative}
+
+   Errors: None
+
+This request returns a list of all devices that can be opened
+by the X server, including the core X keyboard and X pointer.
+Some implementations may open all input devices as part of X
+initialization, while others may not open an input device until
+requested to do so by a client program.
+
+The information returned for each device is as follows:
+
+   type
+          The type field is of type Atom and indicates the nature
+          of the device. Clients may determine device types by
+          invoking the XInternAtom request passing one of the
+          names defined in the header file XI.h. The following
+          names have been defined to date:
+
+                                      MOUSE
+                                      TABLET
+                                      KEYBOARD
+                                      TOUCHSCREEN
+                                      TOUCHPAD
+                                      BUTTONBOX
+                                      BARCODE
+                                      KNOB_BOX
+                                      TRACKBALL
+                                      QUADRATURE
+                                      SPACEBALL
+                                      DATAGLOVE
+                                      EYETRACKER
+                                      CURSORKEYS
+                                      FOOTMOUSE
+                                      ID_MODULE
+                                      ONE_KNOB
+                                      NINE_KNOB
+                                      JOYSTICK
+
+
+   id
+          The id is a small cardinal value in the range 0-128 that
+          uniquely identifies the device. It is assigned to the
+          device when it is initialized by the server. Some
+          implementations may not open an input device until
+          requested by a client program, and may close the device
+          when the last client accessing it requests that it be
+          closed. If a device is opened by a client program via
+          XOpenDevice, then closed via XCloseDevice, then opened
+          again, it is not guaranteed to have the same id after
+          the second open request.
+
+   num_classes
+          The num_classes field is a small cardinal value in the
+          range 0-255 that specifies the number of input classes
+          supported by the device for which information is
+          returned by ListInputDevices. Some input classes, such
+          as class Focus and class Proximity do not have any
+          information to be returned by ListInputDevices.
+
+   use
+          The use field specifies how the device is currently
+          being used. If the value is IsXKeyboard, the device is
+          currently being used as the X keyboard. If the value is
+          IsXPointer, the device is currently being used as the X
+          pointer. If the value is IsXExtensionPointer, the device
+          is available for use as an extension pointer. If the value
+          is IsXExtensionKeyboard, the device is available for use as
+          and extension keyboard.
+          Older versions of XI report all extension devices as
+          IsXExtensionDevice.
+
+   name
+          The name field contains a pointer to a null-terminated
+          string that corresponds to one of the defined device
+          types.
+
+   InputInfo
+          InputInfo is one of: KeyInfo, ButtonInfo or
+          ValuatorInfo. The first two fields are common to all
+          three:
+
+        class
+                The class field is a cardinal value in the range
+                0-255. It uniquely identifies the class of input
+                for which information is returned.
+
+        length
+                The length field is a cardinal value in the range
+                0-255. It specifies the number of bytes of data
+                that are contained in this input class. The length
+                includes the class and length fields.
+
+The remaining information returned for input class
+KEYCLASS is as follows:
+
+        min_keycode
+                min_keycode is of type KEYCODE. It specifies the
+                minimum keycode that the device will report. The
+                minimum keycode will not be smaller than 8.
+
+        max_keycode
+                max_keycode is of type KEYCODE. It specifies the
+                maximum keycode that the device will report. The
+                maximum keycode will not be larger than 255.
+
+        num_keys
+                num_keys is a cardinal value that specifies the
+                number of keys that the device has.
+
+The remaining information returned for input class
+BUTTONCLASS is as follows:
+
+        num_buttons
+                num_buttons is a cardinal value that specifies the
+                number of buttons that the device has.
+
+The remaining information returned for input class
+VALUATORCLASS is as follows:
+
+        mode
+                mode is a constant that has one of the following
+                values: Absolute or Relative. Some devices allow
+                the mode to be changed dynamically via the
+                SetDeviceMode request.
+
+        motion_buffer_size
+                motion_buffer_size is a cardinal number that
+                specifies the number of elements that can be
+                contained in the motion history buffer for the
+                device.
+
+        axes
+                The axes field contains a pointer to an AXISINFO
+                struture.
+
+The information returned for each axis reported by the
+device is:
+
+        resolution
+                The resolution is a cardinal value in
+                counts/meter.
+
+        min_val
+                The min_val field is a cardinal value in that
+                contains the minimum value the device reports for
+                this axis. For devices whose mode is Relative, the
+                min_val field will contain 0.
+
+        max_val
+                The max_val field is a cardinal value in that
+                contains the maximum value the device reports for
+                this axis. For devices whose mode is Relative, the
+                max_val field will contain 0.
+
+2.3 Enabling Devices
+~~~~~~~~~~~~~~~~~~~~
+
+Client programs that wish to access an extension device must
+request that the server open that device. This is done via the
+OpenDevice request.
+
+                OpenDevice
+                        id: CARD8
+                =>
+                DEVICE:
+                        [device_id: XID
+                         num_classes: INT32
+                         classes: LISTofINPUTCLASSINFO]
+                INPUTCLASSINFO:
+                         [input_class: CARD8
+                         event_type_base: CARD8]
+
+   Errors: Device
+
+This request returns the event classes to be used by the client
+to indicate which events the client program wishes to receive.
+Each input class may report several event classes. For example,
+input class Keys reports DeviceKeyPress and DeviceKeyRelease
+event classes. Input classes are unique numbers registered with
+the X Consortium. Input class Other exists to report event
+classes that are not specific to any one input class, such as
+DeviceMappingNotify, ChangeDeviceNotify, and DeviceStateNotify.
+
+The information returned for each device is as follows:
+
+   device_id
+          The device_id is a number that uniquely identifies the
+          device.
+
+   num_classes
+          The num_classes field contains the number of input
+          classes supported by this device.
+
+   For each class of input supported by the device, the
+   InputClassInfo structure contains the following information:
+
+   input_class
+          The input_class is a small cardinal number that
+          identifies the class of input.
+
+   event_type_base
+          The event_type_base is a small cardinal number that
+          specifies the event type of one of the events reported
+          by this input class. This information is not directly
+          used by client programs. Instead, the Device is used by
+          macros that return extension event types and event
+          classes. This is described in the section of this
+          document entitled "Selecting Extension Device Events".
+
+The information in the InputClassInfo reflects the state of
+this device at the time the request was processed.
+
+Before it exits, the client program should explicitly request
+that the server close the device. This is done via the
+CloseDevice request.
+
+A client may open the same extension device more than once.
+Requests after the first successful one return an additional
+XDevice structure with the same information as the first, but
+otherwise have no effect. A single CloseDevice request will
+terminate that client's access to the device.
+
+Closing a device releases any active or passive grabs the
+requesting client has established. If the device is frozen only
+by an active grab of the requesting client, the queued events
+are released when the client terminates.
+
+If a client program terminates without closing a device, the
+server will automatically close that device on behalf of the
+client. This does not affect any other clients that may be
+accessing that device.
+
+                    CloseDevice:
+                            device: DEVICE
+
+   Errors: Device
+
+2.4 Changing The Mode Of A Device
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some devices are capable of reporting either relative or
+absolute motion data. To change the mode of a device from
+relative to absolute, use the SetDeviceMode request. The valid
+values are Absolute or Relative.
+
+This request will fail and return DeviceBusy if another client
+already has the device open with a different mode. It will fail
+and return AlreadyGrabbed if another client has the device
+grabbed. The request will fail with a BadMatch error if the
+device has no valuators and reports no axes of motion. The
+request will fail with a BadMode error if the requested mode
+is not supported by the device.
+
+                    SetDeviceMode
+                            device:DEVICE
+                            mode: {Absolute, Relative}
+                    =>
+                            status: {Success, DeviceBusy, AlreadyGrabbed}
+
+   Errors: Device, Match, Mode
+
+2.5 Initializing Valuators on an Input Device
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some devices that report absolute positional data can be
+initialized to a starting value. Devices that are capable of
+reporting relative motion or absolute positional data may
+require that their valuators be initialized to a starting value
+after the mode of the device is changed to Absolute. To
+initialize the valuators on such a device, use the
+SetDeviceValuators request.
+
+                SetDeviceValuators
+                        device: DEVICE
+                        first_valuator: CARD8
+                        num_valuators: CARD8
+                        valuators: LISTOFINT32
+                =>
+                        status: {Success, AlreadyGrabbed}
+
+   Errors: Length, Device, Match, Value
+
+This request initializes the specified valuators on the
+specified extension input device. Valuators are numbered
+beginning with zero. Only the valuators in the range specified
+by first_valuator and num_valuators are set. If the number of
+valuators supported by the device is less than the expression
+first_valuator + num_valuators, a Value error will result.
+
+If the request succeeds, Success is returned. If the specifed
+device is grabbed by some other client, the request will fail
+and a status of AlreadyGrabbed will be returned.
+
+2.6 Getting Input Device Controls
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+                GetDeviceControl
+                        device: DEVICE
+                        control: XID
+                =>
+                controlState: {DeviceState}
+
+where
+
+                DeviceState: DeviceResolutionState
+
+   Errors: Length, Device, Match, Value
+
+This request returns the current state of the specified device
+control. The device control must be supported by the target
+server and device or an error will result.
+
+If the request is successful, a pointer to a generic
+DeviceState structure will be returned. The information
+returned varies according to the specified control and is
+mapped by a structure appropriate for that control.
+
+GetDeviceControl will fail with a BadValue error if the server
+does not support the specified control. It will fail with a
+BadMatch error if the device does not support the specified
+control.
+
+Supported device controls and the information returned for them
+include:
+
+                DEVICE_RESOLUTION:
+                    [control: CARD16
+                    length: CARD16
+                    num_valuators: CARD8
+                    resolutions: LISTofCARD32
+                    min_resolutions: LISTofCARD32
+                    max_resolutions: LISTofCARD32]
+
+This device control returns a list of valuators and the range
+of valid resolutions allowed for each. Valuators are numbered
+beginning with 0. Resolutions for all valuators on the device
+are returned. For each valuator i on the device, resolutions[i]
+returns the current setting of the resolution,
+min_resolutions[i] returns the minimum valid setting, and
+max_resolutions[i] returns the maximum valid setting.
+
+When this control is specified, XGetDeviceControl will fail
+with a BadMatch error if the specified device has no valuators.
+
+                ChangeDeviceControl:
+                        device: DEVICE
+                        XID: controlId
+                        control: DeviceControl
+
+where
+
+                DeviceControl: DeviceResolutionControl
+                =>
+                        status: {Success, DeviceBusy, AlreadyGrabbed}
+
+   Errors: Length, Device, Match, Value
+
+ChangeDeviceControl changes the specifed device control
+according to the values specified in the DeviceControl
+structure. The device control must be supported by the target
+server and device or an error will result.
+
+The information passed with this request varies according to
+the specified control and is mapped by a structure appropriate
+for that control.
+
+ChangeDeviceControl will fail with a BadValue error if the
+server does not support the specified control. It will fail
+with a BadMatch error if the server supports the specified
+control, but the requested device does not. The request will
+fail and return a status of DeviceBusy if another client
+already has the device open with a device control state that
+conflicts with the one specified in the request. It will fail
+with a status of AlreadyGrabbed if some other client has
+grabbed the specified device. If the request succeeds, Success
+is returned. If it fails, the device control is left unchanged.
+
+Supported device controls and the information specified for
+them include:
+
+                DEVICE_RESOLUTION:
+                        [control: CARD16
+                         length: CARD16
+                         first_valuator: CARD8
+                         num_valuators: CARD8
+                         resolutions: LISTofCARD32]
+
+This device control changes the resolution of the specified
+valuators on the specified extension input device. Valuators
+are numbered beginning with zero. Only the valuators in the
+range specified by first_valuator and num_valuators are set. A
+value of -1 in the resolutions list indicates that the
+resolution for this valuator is not to be changed.
+num_valuators specifies the number of valuators in the
+resolutions list.
+
+When this control is specified, XChangeDeviceControl will fail
+with a BadMatch error if the specified device has no valuators.
+If a resolution is specified that is not within the range of
+valid values (as returned by XGetDeviceControl) the request
+will fail with a BadValue error. If the number of valuators
+supported by the device is less than the expression
+first_valuator + num_valuators, a BadValue error will result.
+
+If the request fails for any reason, none of the valuator
+resolutions will be changed.
+
+ChangeDeviceControl causes the server to send a DevicePresence
+event to interested clients.
+
+2.7 Selecting Extension Device Events
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Extension input events are selected using the
+SelectExtensionEvent request.
+
+                SelectExtensionEvent
+                        interest: LISTofEVENTCLASS
+                        window: WINDOW
+
+   Errors: Window, Class, Access
+
+This request specifies to the server the events within the
+specified window which are of interest to the client. As with
+the core XSelectInput function, multiple clients can select
+input on the same window.
+
+XSelectExtensionEvent requires a list of event classes. An
+event class is a 32-bit number that combines an event type and
+device id, and is used to indicate which event a client wishes
+to receive and from which device it wishes to receive it.
+Macros are provided to obtain event classes from the data
+returned by the XOpenDevice request. The names of these macros
+correspond to the desired events, i.e. the DeviceKeyPress is
+used to obtain the event class for DeviceKeyPress events. The
+syntax of the macro invocation is:
+
+                 DeviceKeyPress (device, event_type, event_class);
+                     device: DEVICE
+                     event_type: INT
+                     event_class: INT
+
+The value returned in event_type is the value that will be
+contained in the event type field of the XDeviceKeyPressEvent
+when it is received by the client. The value returned in
+event_class is the value that should be passed in making an
+XSelectExtensionEvent request to receive DeviceKeyPress events.
+
+For DeviceButtonPress events, the client may specify whether or
+not an implicit passive grab should be done when the button is
+pressed. If the client wants to guarantee that it will receive
+a DeviceButtonRelease event for each DeviceButtonPress event it
+receives, it should specify the DeviceButtonPressGrab event
+class as well as the DeviceButtonPress event class. This
+restricts the client in that only one client at a time may
+request DeviceButtonPress events from the same device and
+window if any client specifies this class.
+
+If any client has specified the DeviceButtonPressGrab class,
+any requests by any other client that specify the same device
+and window and specify DeviceButtonPress or
+DeviceButtonPressGrab will cause an Access error to be
+generated.
+
+If only the DeviceButtonPress class is specified, no implicit
+passive grab will be done when a button is pressed on the
+device. Multiple clients may use this class to specify the same
+device and window combination.
+
+A client may also specify the DeviceOwnerGrabButton class. If
+it has specified both the DeviceButtonPressGrab and the
+DeviceOwnerGrabButton classes, implicit passive grabs will
+activate with owner_events set to True. If only the
+DeviceButtonPressGrab class is specified, implicit passive
+grabs will activate with owner_events set to False.
+
+The client may select DeviceMotion events only when a button is
+down. It does this by specifying the event classes
+Button1Motion through Button5Motion, or ButtonMotion. An input
+device will only support as many button motion classes as it
+has buttons.
+
+2.8 Determining Selected Events
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To determine which extension events are currently selected from
+a given window, use GetSelectedExtensionEvents.
+
+                GetSelectedExtensionEvents
+                        window: WINDOW
+                =>
+                        this-client: LISTofEVENTCLASS
+                        all-clients: LISTofEVENTCLASS
+
+   Errors: Window
+
+This request returns two lists specifying the events selected
+on the specified window. One list gives the extension events
+selected by this client from the specified window. The other
+list gives the extension events selected by all clients from
+the specified window. This information is equivalent to that
+returned by your-event-mask and all-event-masks in a
+GetWindowAttributes request.
+
+2.9 Controlling Event Propagation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Extension events propagate up the window hierarchy in the same
+manner as core events. If a window is not interested in an
+extension event, it usually propagates to the closest ancestor
+that is interested, unless the dont_propagate list prohibits
+it. Grabs of extension devices may alter the set of windows
+that receive a particular extension event.
+
+Client programs may control extension event propagation through
+the use of the following two requests.
+
+XChangeDeviceDontPropagateList adds an event to or deletes an
+event from the do_not_propagate list of extension events for
+the specified window. This list is maintained for the life of
+the window, and is not altered if the client terminates.
+
+                ChangeDeviceDontPropagateList
+                        window: WINDOW
+                        eventclass: LISTofEVENTCLASS
+                        mode: {AddToList, DeleteFromList}
+
+   Errors: Window, Class, Mode
+
+This function modifies the list specifying the events that are
+not propagated to the ancestors of the specified window. You
+may use the modes AddToList or DeleteFromList.
+
+                GetDeviceDontPropagateList
+                        window: WINDOW
+                =>
+                        dont-propagate-list: LISTofEVENTCLASS
+
+   Errors: Window
+
+This function returns a list specifying the events that are not
+propagated to the ancestors of the specified window.
+
+2.10 Sending Extension Events
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One client program may send an event to another via the
+XSendExtensionEvent function.
+
+The event in the XEvent structure must be one of the events
+defined by the input extension, so that the X server can
+correctly byte swap the contents as necessary. The contents of
+the event are otherwise unaltered and unchecked by the X server
+except to force send_event to True in the forwarded event and
+to set the sequence number in the event correctly.
+
+XSendExtensionEvent returns zero if the conversion-to-wire
+protocol failed, otherwise it returns nonzero.
+
+                SendExtensionEvent
+                        device: DEVICE
+                        destination: WINDOW
+                        propagate: BOOL
+                        eventclass: LISTofEVENTCLASS
+                        event: XEVENT
+
+   Errors: Device, Value, Class, Window
+
+2.11 Getting Motion History
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+                GetDeviceMotionEvents
+                        device: DEVICE
+                        start, stop: TIMESTAMP or CurrentTime
+                =>
+                        nevents_return: CARD32
+                        mode_return: {Absolute, Relative}
+                        axis_count_return: CARD8
+                        events: LISTofDEVICETIMECOORD
+
+where
+
+                DEVICETIMECOORD:
+                        [data: LISTofINT32
+                         time: TIMESTAMP]
+
+   Errors: Device, Match
+
+This request returns all positions in the device's motion
+history buffer that fall between the specified start and stop
+times inclusive. If the start time is in the future, or is
+later than the stop time, no positions are returned.
+
+The data field of the DEVICETIMECOORD structure is a sequence
+of data items. Each item is of type INT32, and there is one
+data item per axis of motion reported by the device. The number
+of axes reported by the device is returned in the axis_count
+variable.
+
+The value of the data items depends on the mode of the device,
+which is returned in the mode variable. If the mode is
+Absolute, the data items are the raw values generated by the
+device. These may be scaled by the client program using the
+maximum values that the device can generate for each axis of
+motion that it reports. The maximum and minimum values for each
+axis are reported by the ListInputDevices request.
+
+If the mode is Relative, the data items are the relative values
+generated by the device. The client program must choose an
+initial position for the device and maintain a current position
+by accumulating these relative values.
+
+2.12 Changing The Core Devices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These requests are provided to change which physical device is
+used as the X pointer or X keyboard. These requests are
+deprecated in servers supporting XI 1.4 and above, and will
+always return a a BadDevice error.
+
+Using these requests may change the characteristics of the core
+devices. The new pointer device may have a different number of
+buttons than the old one did, or the new keyboard device may
+have a different number of keys or report a different range of
+keycodes. Client programs may be running that depend on those
+characteristics. For example, a client program could allocate
+an array based on the number of buttons on the pointer device,
+and then use the button numbers received in button events as
+indicies into that array. Changing the core devices could cause
+such client programs to behave improperly or abnormally
+terminate.
+
+These requests change the X keyboard or X pointer device and
+generate an ChangeDeviceNotify event and a MappingNotify event.
+The ChangeDeviceNotify event is sent only to those clients that
+have expressed an interest in receiving that event via the
+XSelectExtensionEvent request. The specified device becomes the
+new X keyboard or X pointer device. The location of the core
+device does not change as a result of this request.
+
+These requests fail and return AlreadyGrabbed if either the
+specified device or the core device it would replace are
+grabbed by some other client. They fail and return GrabFrozen
+if either device is frozen by the active grab of another
+client.
+
+These requests fail with a BadDevice error if the specified
+device is invalid, or has not previously been opened via
+OpenDevice. To change the X keyboard device, use the
+ChangeKeyboardDevice request. The specified device must support
+input class Keys (as reported in the ListInputDevices request)
+or the request will fail with a BadMatch error. Once the device
+has successfully replaced one of the core devices, it is
+treated as a core device until it is in turn replaced by
+another ChangeDevice request, or until the server terminates.
+The termination of the client that changed the device will not
+cause it to change back. Attempts to use the CloseDevice
+request to close the new core device will fail with a BadDevice
+error.
+
+The focus state of the new keyboard is the same as the focus
+state of the old X keyboard. If the new keyboard was not
+initialized with a FocusRec, one is added by the
+ChangeKeyboardDevice request. The X keyboard is assumed to have
+a KbdFeedbackClassRec. If the device was initialized without a
+KbdFeedbackClassRec, one will be added by this request. The
+KbdFeedbackClassRec will specify a null routine as the control
+procedure and the bell procedure.
+
+                ChangeKeyboardDevice
+                        device: DEVICE
+                =>
+                        status: Success, AlreadyGrabbed, Frozen
+
+   Errors: Device, Match
+
+To change the X pointer device, use the ChangePointerDevice
+request. The specified device must support input class
+Valuators (as reported in the ListInputDevices request) or the
+request will fail with a BadMatch error. The valuators to be
+used as the x- and y-axes of the pointer device must be
+specified. Data from other valuators on the device will be
+ignored.
+
+The X pointer device does not contain a FocusRec. If the new
+pointer was initialized with a FocusRec, it is freed by the
+ChangePointerDevice request. The X pointer is assumed to have a
+ButtonClassRec and a PtrFeedbackClassRec. If the device was
+initialized without a ButtonClassRec or a PtrFeedbackClassRec,
+one will be added by this request. The ButtonClassRec added
+will have no buttons, and the PtrFeedbackClassRec will specify
+a null routine as the control procedure.
+
+If the specified device reports absolute positional
+information, and the server implementation does not allow such
+a device to be used as the X pointer, the request will fail
+with a BadDevice error.
+
+Once the device has successfully replaced one of the core
+devices, it is treated as a core device until it is in turn
+replaced by another ChangeDevice request, or until the server
+terminates. The termination of the client that changed the
+device will not cause it to change back. Attempts to use the
+CloseDevice request to close the new core device will fail with
+a BadDevice error.
+
+                ChangePointerDevice
+                        device: DEVICE
+                        xaxis: CARD8
+                        yaxis: CARD8
+                =>
+                     status: Success, AlreadyGrabbed, Frozen
+
+   Errors: Device, Match
+
+2.12 Event Synchronization And Core Grabs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Implementation of the input extension requires an extension of
+the meaning of event synchronization for the core grab
+requests. This is necessary in order to allow window managers
+to freeze all input devices with a single request.
+
+The core grab requests require a pointer_mode and keyboard_mode
+argument. The meaning of these modes is changed by the input
+extension. For the XGrabPointer and XGrabButton requests,
+pointer_mode controls synchronization of the pointer device,
+and keyboard_mode controls the synchronization of all other
+input devices. For the XGrabKeyboard and XGrabKey requests,
+pointer_mode controls the synchronization of all input devices
+except the X keyboard, while keyboard_mode controls the
+synchronization of the keyboard. When using one of the core
+grab requests, the synchronization of extension devices is
+controlled by the mode specified for the device not being
+grabbed.
+
+2.13 Extension Active Grabs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Active grabs of extension devices are supported via the
+GrabDevice request in the same way that core devices are
+grabbed using the core GrabKeyboard request, except that a
+Device is passed as a function parameter. A list of events that
+the client wishes to receive is also passed. The UngrabDevice
+request allows a previous active grab for an extension device
+to be released.
+
+To grab an extension device, use the GrabDevice request. The
+device must have previously been opened using the OpenDevice
+request.
+
+                GrabDevice
+                        device: DEVICE
+                        grab-window: WINDOW
+                        owner-events: BOOL
+                        event-list: LISTofEVENTCLASS
+                        this-device-mode: {Synchronous, Asynchronous}
+                        other-device-mode: {Synchronous, Asynchronous}
+                        time:TIMESTAMP or CurrentTime
+                =>
+                        status: Success, AlreadyGrabbed, Frozen,
+                                InvalidTime, NotViewable
+
+   Errors: Device, Window, Value
+
+This request actively grabs control of the specified input
+device. Further input events from this device are reported only
+to the grabbing client. This request overrides any previous
+active grab by this client for this device.
+
+The event-list parameter is a pointer to a list of event
+classes. These are used to indicate which events the client
+wishes to receive while the device is grabbed. Only event
+classes obtained from the grabbed device are valid.
+
+If owner-events is False, input events generated from this
+device are reported with respect to grab-window, and are only
+reported if selected by being included in the event-list. If
+owner-events is True, then if a generated event would normally
+be reported to this client, it is reported normally, otherwise
+the event is reported with respect to the grab-window, and is
+only reported if selected by being included in the event-list.
+For either value of owner-events, unreported events are
+discarded.
+
+If this-device-mode is Asynchronous, device event processing
+continues normally. If the device is currently frozen by this
+client, then processing of device events is resumed. If
+this-device-mode is Synchronous, the state of the grabbed
+device (as seen by means of the protocol) appears to freeze,
+and no further device events are generated by the server until
+the grabbing client issues a releasing AllowDeviceEvents
+request or until the device grab is released. Actual device
+input events are not lost while the device is frozen; they are
+simply queued for later processing.
+
+If other-device-mode is Asynchronous, event processing is
+unaffected by activation of the grab. If other-device-mode is
+Synchronous, the state of all input devices except the grabbed
+one (as seen by means of the protocol) appears to freeze, and
+no further events are generated by the server until the
+grabbing client issues a releasing AllowDeviceEvents request or
+until the device grab is released. Actual events are not lost
+while the devices are frozen; they are simply queued for later
+processing.
+
+This request generates DeviceFocusIn and DeviceFocusOut events.
+
+This request fails and returns:
+
+   AlreadyGrabbed
+          If the device is actively grabbed by some other client.
+
+   NotViewable
+          If grab-window is not viewable.
+
+   InvalidTime
+          If the specified time is earlier than the last-grab-time
+          for the specified device or later than the current X
+          server time. Otherwise, the last-grab-time for the
+          specified device is set to the specified time and
+          CurrentTime is replaced by the current X server time.
+
+   Frozen
+          If the device is frozen by an active grab of another
+          client.
+
+If a grabbed device is closed by a client while an active grab
+by that client is in effect, that active grab will be released.
+Any passive grabs established by that client will be released.
+If the device is frozen only by an active grab of the
+requesting client, it is thawed.
+
+To release a grab of an extension device, use UngrabDevice.
+
+               UngrabDevice
+                       device: DEVICE
+                       time: TIMESTAMP or CurrentTime
+
+   Errors: Device
+
+This request releases the device if this client has it actively
+grabbed (from either GrabDevice or GrabDeviceKey) and releases
+any queued events. If any devices were frozen by the grab,
+UngrabDevice thaws them. The request has no effect if the
+specified time is earlier than the last-device-grab time or is
+later than the current server time.
+
+This request generates DeviceFocusIn and DeviceFocusOut events.
+
+An UngrabDevice is performed automatically if the event window
+for an active device grab becomes not viewable.
+
+2.14 Passively Grabbing A Key
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Passive grabs of buttons and keys on extension devices are
+supported via the GrabDeviceButton and GrabDeviceKey requests.
+These passive grabs are released via the UngrabDeviceKey and
+UngrabDeviceButton requests.
+
+To passively grab a single key on an extension device, use
+GrabDeviceKey. That device must have previously been opened
+using the OpenDevice request.
+
+            GrabDeviceKey
+                    device: DEVICE
+                    keycode: KEYCODE or AnyKey
+                    modifiers: SETofKEYMASK or AnyModifier
+                    modifier-device: DEVICE or NULL
+                    grab-window: WINDOW
+                    owner-events: BOOL
+                    event-list: LISTofEVENTCLASS
+                    this-device-mode: {Synchronous, Asynchronous}
+                    other-device-mode: {Synchronous, Asynchronous}
+
+   Errors: Device, Match, Access, Window, Value
+
+This request is analogous to the core GrabKey request. It
+establishes a passive grab on a device. Consequently, in the
+future:
+
+     * IF the device is not grabbed and the specified key, which
+       itself can be a modifier key, is logically pressed when the
+       specified modifier keys logically are down on the specified
+       modifier device (and no other keys are down),
+     * AND no other modifier keys logically are down,
+     * AND EITHER the grab window is an ancestor of (or is) the
+       focus window OR the grab window is a descendent of the
+       focus window and contains the pointer,
+     * AND a passive grab on the same device and key combination
+       does not exist on any ancestor of the grab window,
+     * THEN the device is actively grabbed, as for GrabDevice, the
+       last-device-grab time is set to the time at which the key
+       was pressed (as transmitted in the DeviceKeyPress event),
+       and the DeviceKeyPress event is reported.
+
+The interpretation of the remaining arguments is as for
+GrabDevice. The active grab is terminated automatically when
+logical state of the device has the specified key released
+(independent of the logical state of the modifier keys).
+
+Note that the logical state of a device (as seen by means of
+the X protocol) may lag the physical state if device event
+processing is frozen.
+
+A modifier of AnyModifier is equivalent to issuing the request
+for all possible modifier combinations (including the
+combination of no modifiers). It is not required that all
+modifiers specified have currently assigned keycodes. A key of
+AnyKey is equivalent to issuing the request for all possible
+keycodes. Otherwise, the key must be in the range specified by
+min-keycode and max-keycode in the ListInputDevices request. If
+it is not within that range, GrabDeviceKey generates a Value
+error.
+
+NULL may be passed for the modifier_device. If the
+modifier_device is NULL, the core X keyboard is used as the
+modifier_device.
+
+An Access error is generated if some other client has issued a
+GrabDeviceKey with the same device and key combination on the
+same window. When using AnyModifier or AnyKey, the request
+fails completely and the X server generates a Access error and
+no grabs are established if there is a conflicting grab for any
+combination.
+
+This request cannot be used to grab a key on the X keyboard
+device. The core GrabKey request should be used for that
+purpose.
+
+To release a passive grab of a single key on an extension
+device, use UngrabDeviceKey.
+
+           UngrabDeviceKey
+                   device: DEVICE
+                   keycode: KEYCODE or AnyKey
+                   modifiers: SETofKEYMASK or AnyModifier
+                   modifier-device: DEVICE or NULL
+                   grab-window: WINDOW
+
+   Errors: Device, Match, Window, Value, Alloc
+
+This request is analogous to the core UngrabKey request. It
+releases the key combination on the specified window if it was
+grabbed by this client. A modifier of AnyModifier is equivalent
+to issuing the request for all possible modifier combinations
+(including the combination of no modifiers). A key of AnyKey is
+equivalent to issuing the request for all possible keycodes.
+This request has no effect on an active grab.
+
+NULL may be passed for the modifier_device. If the
+modifier_device is NULL, the core X keyboard is used as the
+modifier_device.
+
+2.15 Passively Grabbing A Button
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To establish a passive grab for a single button on an extension
+device, use GrabDeviceButton.
+
+                GrabDeviceButton
+                        device: DEVICE
+                        button: BUTTON or AnyButton
+                        modifiers: SETofKEYMASK or AnyModifier
+                        modifier-device: DEVICE or NULL
+                        grab-window: WINDOW
+                        owner-events: BOOL
+                        event-list: LISTofEVENTCLASS
+                        this-device-mode: {Synchronous, Asynchronous}
+                        other-device-mode: {Synchronous, Asynchronous}
+
+   Errors: Device, Match, Window, Access, Value
+
+This request is analogous to the core GrabButton request. It
+establishes an explicit passive grab for a button on an
+extension input device. Since the server does not track
+extension devices, no cursor is specified with this request.
+For the same reason, there is no confine-to parameter. The
+device must have previously been opened using the OpenDevice
+request.
+
+The GrabDeviceButton request establishes a passive grab on a
+device. Consequently, in the future,
+
+   * IF the device is not grabbed and the specified button is
+     logically pressed when the specified modifier keys
+     logically are down (and no other buttons or modifier
+     keys are down),
+
+   * AND the grab window contains the device,
+
+   * AND a passive grab on the same device and button/ key
+     combination does not exist on any ancestor of the grab
+     window,
+
+   * THEN the device is actively grabbed, as for GrabDevice,
+     the last-grab time is set to the time at which the
+     button was pressed (as transmitted in the
+     DeviceButtonPress event), and the DeviceButtonPress
+     event is reported.
+
+The interpretation of the remaining arguments is as for
+GrabDevice. The active grab is terminated automatically when
+logical state of the device has all buttons released
+(independent of the logical state of the modifier keys).
+
+Note that the logical state of a device (as seen by means of
+the X protocol) may lag the physical state if device event
+processing is frozen.
+
+A modifier of AnyModifier is equivalent to issuing the request
+for all possible modifier combinations (including the
+combination of no modifiers). It is not required that all
+modifiers specified have currently assigned keycodes. A button
+of AnyButton is equivalent to issuing the request for all
+possible buttons. It is not required that the specified button
+be assigned to a physical button.
+
+NULL may be passed for the modifier_device. If the
+modifier_device is NULL, the core X keyboard is used as the
+modifier_device.
+
+An Access error is generated if some other client has issued a
+GrabDeviceButton with the same device and button combination on
+the same window. When using AnyModifier or AnyButton, the
+request fails completely and the X server generates a Access
+error and no grabs are established if there is a conflicting
+grab for any combination. The request has no effect on an
+active grab.
+
+This request cannot be used to grab a button on the X pointer
+device. The core GrabButton request should be used for that
+purpose.
+
+To release a passive grab of a button on an extension device,
+use UngrabDeviceButton.
+
+                UngrabDeviceButton
+                        device: DEVICE
+                        button: BUTTON or AnyButton
+                        modifiers: SETofKEYMASK or AnyModifier
+                        modifier-device: DEVICE or NULL
+                        grab-window: WINDOW
+
+   Errors: Device, Match, Window, Value, Alloc
+
+This request is analogous to the core UngrabButton request. It
+releases the passive button/key combination on the specified
+window if it was grabbed by the client. A modifiers of
+AnyModifier is equivalent to issuing the request for all
+possible modifier combinations (including the combination of no
+modifiers). A button of AnyButton is equivalent to issuing the
+request for all possible buttons. This request has no effect on
+an active grab. The device must have previously been opened
+using the OpenDevice request otherwise a Device error will be
+generated.
+
+NULL may be passed for the modifier_device. If the
+modifier_device is NULL, the core X keyboard is used as the
+modifier_device.
+
+This request cannot be used to ungrab a button on the X pointer
+device. The core UngrabButton request should be used for that
+purpose.
+
+2.16 Thawing A Device
+~~~~~~~~~~~~~~~~~~~~~
+
+To allow further events to be processed when a device has been
+frozen, use AllowDeviceEvents.
+
+                AllowDeviceEvents
+                        device: DEVICE
+                        event-mode: {AsyncThisDevice, SyncThisDevice, AsyncOtherDevices,
+                        ReplayThisdevice, AsyncAll, or SyncAll}
+                        time:TIMESTAMP or CurrentTime
+
+   Errors: Device, Value
+
+The AllowDeviceEvents request releases some queued events if
+the client has caused a device to freeze. The request has no
+effect if the specified time is earlier than the last-grab time
+of the most recent active grab for the client, or if the
+specified time is later than the current X server time.
+
+The following describes the processing that occurs depending on
+what constant you pass to the event-mode argument:
+
+   * If the specified device is frozen by the client, event
+     processing for that device continues as usual. If the
+     device is frozen multiple times by the client on behalf
+     of multiple separate grabs, AsyncThisDevice thaws for
+     all. AsyncThisDevice has no effect if the specified
+     device is not frozen by the client, but the device need
+     not be grabbed by the client.
+
+   * If the specified device is frozen and actively grabbed
+     by the client, event processing for that device
+     continues normally until the next button or key event is
+     reported to the client. At this time, the specified
+     device again appears to freeze. However, if the reported
+     event causes the grab to be released, the specified
+     device does not freeze. SyncThisDevice has no effect if
+     the specified device is not frozen by the client or is
+     not grabbed by the client.
+
+   * If the specified device is actively grabbed by the
+     client and is frozen as the result of an event having
+     been sent to the client (either from the activation of a
+     GrabDeviceButton or from a previous AllowDeviceEvents
+     with mode SyncThisDevice, but not from a Grab), the grab
+     is released and that event is completely reprocessed.
+     This time, however, the request ignores any passive
+     grabs at or above (towards the root) the grab-window of
+     the grab just released. The request has no effect if the
+     specified device is not grabbed by the client or if it
+     is not frozen as the result of an event.
+
+   * If the remaining devices are frozen by the client, event
+     processing for them continues as usual. If the other
+     devices are frozen multiple times by the client on
+     behalf of multiple separate grabs, AsyncOtherDevices
+     “thaws” for all. AsyncOtherDevices has no effect if the
+     devices are not frozen by the client, but those devices
+     need not be grabbed by the client.
+
+   * If all devices are frozen by the client, event
+     processing (for all devices) continues normally until
+     the next button or key event is reported to the client
+     for a grabbed device (button event for the grabbed
+     device, key or motion event for the device), at which
+     time the devices again appear to freeze. However, if the
+     reported event causes the grab to be released, then the
+     devices do not freeze (but if any device is still
+     grabbed, then a subsequent event for it will still cause
+     all devices to freeze). SyncAll has no effect unless all
+     devices are frozen by the client. If any device is
+     frozen twice by the client on behalf of two separate
+     grabs, SyncAll "thaws" for both (but a subsequent freeze
+     for SyncAll will only freeze each device once).
+
+   * If all devices are frozen by the client, event
+     processing (for all devices) continues normally. If any
+     device is frozen multiple times by the client on behalf
+     of multiple separate grabs, AsyncAll "thaws" for all.
+     AsyncAll has no effect unless all devices are frozen by
+     the client.
+
+AsyncThisDevice, SyncThisDevice, and ReplayThisDevice
+have no effect on the processing of events from the
+remaining devices. AsyncOtherDevices has no effect on
+the processing of events from the specified device. When
+the event_mode is SyncAll or AsyncAll, the device
+parameter is ignored.
+
+It is possible for several grabs of different devices
+(by the same or different clients) to be active
+simultaneously. If a device is frozen on behalf of any
+grab, no event processing is performed for the device.
+It is possible for a single device to be frozen because
+of several grabs. In this case, the freeze must be
+released on behalf of each grab before events can again
+be processed.
+
+2.17 Controlling Device Focus
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The current focus window for an extension input device can be
+determined using the GetDeviceFocus request. Extension devices
+are focused using the SetDeviceFocus request in the same way
+that the keyboard is focused using the SetInputFocus request,
+except that a device is specified as part of the request. One
+additional focus state, FollowKeyboard, is provided for
+extension devices.
+
+To get the current focus state, revert state, and focus time of
+an extension device, use GetDeviceFocus.
+
+                GetDeviceFocus
+                        device: DEVICE
+                =>
+                        focus: WINDOW, PointerRoot, FollowKeyboard, or None
+                        revert-to: Parent, PointerRoot, FollowKeyboard, or None
+                        focus-time: TIMESTAMP
+
+   Errors: Device, Match
+
+This request returns the current focus state, revert-to state,
+and last-focus-time of an extension device.
+
+To set the focus of an extension device, use SetDeviceFocus.
+
+                SetDeviceFocus
+                        device: DEVICE
+                        focus: WINDOW, PointerRoot, FollowKeyboard, or None
+                        revert-to: Parent, PointerRoot, FollowKeyboard, or None
+                        focus-time: TIMESTAMP
+
+   Errors: Device, Window, Value, Match
+
+This request changes the focus for an extension input device
+and the last-focus-change-time. The request has no effect if
+the specified time is earlier than the last-focus-change-time
+or is later than the current X server time. Otherwise, the
+last-focus-change-time is set to the specified time, with
+CurrentTime replaced by the current server time.
+
+The action taken by the server when this request is requested
+depends on the value of the focus argument:
+
+   * If the focus argument is None, all input events from
+     this device will be discarded until a new focus window
+     is set. In this case, the revert-to argument is ignored.
+
+   * If a window ID is assigned to the focus argument, it
+     becomes the focus window of the device. If an input
+     event from the device would normally be reported to this
+     window or to one of its inferiors, the event is reported
+     normally. Otherwise, the event is reported relative to
+     the focus window.
+
+   * If you assign PointerRoot to the focus argument, the
+     focus window is dynamically taken to be the root window
+     of whatever screen the pointer is on at each input
+     event. In this case, the revert-to argument is ignored.
+
+   * If you assign FollowKeyboard to the focus argument, the
+     focus window is dynamically taken to be the same as the
+     focus of the X keyboard at each input event.
+     The specified focus window must be viewable at the time
+     of the request (else a Match error). If the focus window
+     later becomes not viewable, the X server evaluates the
+     revert-to argument to determine the new focus window.
+
+   * If you assign RevertToParent to the revert-to argument,
+     the focus reverts to the parent (or the closest viewable
+     ancestor), and the new revert-to value is taken to be
+     RevertToNone.
+
+   * If you assign RevertToPointerRoot,
+     RevertToFollowKeyboard, or RevertToNone to the revert-to
+     argument, the focus reverts to that value.
+
+When the focus reverts, the X server generates DeviceFocusIn
+and DeviceFocusOut events, but the last-focus-change time is
+not affected.
+
+This request causes the X server to generate DeviceFocusIn and
+DeviceFocusOut events.
+
+2.18 Controlling Device Feedback
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To get the settings of feedbacks on an extension device, use
+GetFeedbackControl. This request provides functionality
+equivalent to the core GetKeyboardControl and GetPointerControl
+functions. It also provides a way to control displays
+associated with an input device that are capable of displaying
+an integer or string.
+
+                GetFeedbackControl
+                        device: DEVICE
+                =>
+                        num_feedbacks_return: CARD16
+                        return_value: LISTofFEEDBACKSTATE
+
+where
+
+                    FEEDBACKSTATE: {KbdFeedbackState, PtrFeedbackState,
+                                    IntegerFeedbackState, StringFeedbackState,
+                                    BellFeedbackState, LedFeedbackState}
+
+Feedbacks are reported by class. Those feedbacks that are
+reported for the core keyboard device are in class KbdFeedback,
+and are returned in the KbdFeedbackState structure. The members
+of that structure are as follows:
+
+                CLASS Kbd:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         key_click_percent: CARD8
+                         bell_percent: CARD8
+                         bell_pitch: CARD16
+                         bell_duration: CARD16
+                         led_value: BITMASK
+                         global_auto_repeat: {AutoRepeatModeOn, AutoRepeatModeOff}
+                         auto_repeats: LISTofCARD8]
+
+Those feedbacks that are equivalent to those reported for the
+core pointer are in feedback class PtrFeedback and are reported
+in the PtrFeedbackState structure. The members of that
+structure are:
+
+                CLASS Ptr:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         accelNumerator: CARD16
+                         accelDenominator: CARD16
+                         threshold: CARD16]
+
+Some input devices provide a means of displaying an integer.
+Those devices will support feedback class IntegerFeedback,
+which is reported in the IntegerFeedbackState structure. The
+members of that structure are:
+
+                  CLASS Integer:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         resolution: CARD32
+                         min-val: INT32
+                         max-val: INT32]
+
+Some input devices provide a means of displaying a string.
+Those devices will support feedback class StringFeedback, which
+is reported in the StringFeedbackState structure. The members
+of that structure are:
+
+                  CLASS String:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         max_symbols: CARD16
+                         num_keysyms_supported: CARD16
+                         keysyms_supported: LISTofKEYSYM]
+
+Some input devices contain a bell. Those devices will support
+feedback class BellFeedback, which is reported in the
+BellFeedbackState structure. The members of that structure are:
+
+                  CLASS Bell:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         percent: CARD8
+                         pitch: CARD16
+                         duration: CARD16]
+
+The percent sets the base volume for the bell between 0 (off)
+and 100 (loud) inclusive, if possible. Setting to -1 restores
+the default. Other negative values generate a Value error.
+
+The pitch sets the pitch (specified in Hz) of the bell, if
+possible. Setting to -1 restores the default. Other negative
+values generate a Value error.
+
+The duration sets the duration (specified in milliseconds) of
+the bell, if possible. Setting to -1 restores the default.
+Other negative values generate a Value error.
+
+A bell generator connected with the console but not directly on
+the device is treated as if it were part of the device. Some
+input devices contain LEDs. Those devices will support feedback
+class Led, which is reported in the LedFeedbackState structure.
+The members of that structure are:
+
+                  CLASS Led:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         led_mask: BITMASK
+                         led_value: BITMASK]
+
+Each bit in led_mask indicates that the corresponding led is
+supported by the feedback. At most 32 LEDs per feedback are
+supported. No standard interpretation of LEDs is defined.
+
+This function will fail with a BadMatch error if the device
+specified in the request does not support feedbacks.
+
+   Errors: Device, Match
+
+To change the settings of a feedback on an extension device,
+use ChangeFeedbackControl.
+
+                ChangeFeedbackControl
+                        device: DEVICE
+                        feedbackid: CARD8
+                        value-mask: BITMASK
+                        value: FEEDBACKCONTROL
+                        FEEDBACKCONTROL: {KBDFEEDBACKCONTROL,
+                                          PTRFEEDBACKCONTROL,
+                                          INTEGERFEEDBACKCONTROL,
+                                          STRINGFEEDBACKCONTROL,
+                                          BELLFEEDBACKCONTROL,
+                                          LEDFEEDBACKCONTROL}
+
+   Errors: Device, Match, Value
+
+Feedback controls are grouped by class. Those feedbacks that
+are equivalent to those supported by the core keyboard are
+controlled by feedback class KbdFeedbackClass using the
+KbdFeedbackControl structure. The members of that structure
+are:
+
+                KBDFEEDBACKCTL
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         key_click_percent: INT8
+                         bell_percent: INT8
+                         bell_pitch: INT16
+                         bell_duration: INT16
+                         led_mask: INT32
+                         led_value: INT32
+                         key: KEYCODE
+                         auto_repeat_mode: {AutoRepeatModeOn, AutoRepeatModeOff,
+                                            AutoRepeatModeDefault}]
+
+The key_click_percent sets the volume for key clicks between 0
+(off) and 100 (loud) inclusive, if possible. Setting to -1
+restores the default. Other negative values generate a Value
+error.
+
+If both auto_repeat_mode and key are specified, then the
+auto_repeat_mode of that key is changed, if possible. If only
+auto_repeat_mode is specified, then the global auto-repeat mode
+for the entire keyboard is changed, if possible, without
+affecting the per-key settings. It is a Match error if a key is
+specified without an auto_repeat_mode.
+
+The order in which controls are verified and altered is
+server-dependent. If an error is generated, a subset of the
+controls may have been altered.
+
+Those feedback controls equivalent to those of the core pointer
+are controlled by feedback class PtrFeedbackClass using the
+PtrFeedbackControl structure. The members of that structure are
+as follows:
+
+                PTRFEEDBACKCTL:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         accelNumerator: INT16
+                         accelDenominator: INT16
+                         threshold: INT16]
+
+The acceleration, expressed as a fraction, is a multiplier for
+movement. For example, specifying 3/1 means the device moves
+three times as fast as normal. The fraction may be rounded
+arbitrarily by the X server. Acceleration only takes effect if
+the device moves more than threshold pixels at once and only
+applies to the amount beyond the value in the threshold
+argument. Setting a value to -1 restores the default. The
+values of the do-accel and do-threshold arguments must be
+nonzero for the device values to be set. Otherwise, the
+parameters will be unchanged. Negative values generate a Value
+error, as does a zero value for the accel-denominator argument.
+
+Some devices are capable of displaying an integer. This is done
+using feedback class IntegerFeedbackClass using the
+IntegerFeedbackControl structure. The members of that structure
+are as follows:
+
+                INTEGERCTL:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         int_to_display: INT32]
+
+Some devices are capable of displaying a string. This is done
+using feedback class StringFeedbackClass using the
+StringFeedbackCtl structure. The members of that structure are
+as follows:
+
+                STRINGCTL:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         syms_to_display: LISTofKEYSYMS]
+
+Some devices contain a bell. This is done using feedback class
+BellFeedbackClass using the BellFeedbackControl structure. The
+members of that structure are as follows:
+
+                BELLCTL:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         percent: INT8
+                         pitch: INT16
+                         duration: INT16]
+
+Some devices contain leds. These can be turned on and off using
+the LedFeedbackControl structure. The members of that structure
+are as follows:
+
+                LEDCTL:
+                        [class: CARD8
+                         length: CARD16
+                         feedback id: CARD8
+                         led_mask: BITMASK
+                         led_value: BITMASK]
+
+   Errors: Device, Match, Value
+
+2.20 Ringing a Bell on an Input Device
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To ring a bell on an extension input device, use DeviceBell.
+
+                DeviceBell:
+                        device: DEVICE
+                        feedbackclass: CARD8
+                        feedbackid: CARD8
+                        percent: INT8
+
+   Errors: Device, Value
+
+This request is analogous to the core Bell request. It rings
+the specified bell on the specified input device feedback,
+using the specified volume. The specified volume is relative to
+the base volume for the feedback. If the value for the percent
+argument is not in the range -100 to 100 inclusive, a Value
+error results. The volume at which the bell rings when the
+percent argument is nonnegative is:
+
+                base - [(base * percent) / 100] + percent
+
+The volume at which the bell rings when the percent argument is
+negative is:
+
+                base + [(base * percent) / 100]
+
+To change the base volume of the bell, use
+ChangeFeedbackControl request.
+
+Controlling Device Encoding
+
+To get the keyboard mapping of an extension device that has
+keys, use GetDeviceKeyMapping.
+
+                GetDeviceKeyMapping
+                        device: DEVICE
+                        first-keycode: KEYCODE
+                        count: CARD8
+                =>
+                        keysyms-per-keycode: CARD8
+                        keysyms: LISTofKEYSYM
+
+   Errors: Device, Match, Value
+
+This request returns the symbols for the specified number of
+keycodes for the specified extension device, starting with the
+specified keycode. The first-keycode must be greater than or
+equal to min-keycode as returned in the connection setup (else
+a Value error), and
+
+                first-keycode + count - 1
+
+must be less than or equal to max-keycode as returned in the
+connection setup (else a Value error). The number of elements
+in the keysyms list is
+
+                count * keysyms-per-keycode
+
+and KEYSYM number N (counting from zero) for keycode K has an
+index (counting from zero) of
+
+                (K - first-keycode) * keysyms-per-keycode + N
+
+in keysyms. The keysyms-per-keycode value is chosen arbitrarily
+by the server to be large enough to report all requested
+symbols. A special KEYSYM value of NoSymbol is used to fill in
+unused elements for individual keycodes.
+
+If the specified device has not first been opened by this
+client via OpenDevice, or if that device does not support input
+class Keys, this request will fail with a Device error.
+
+To change the keyboard mapping of an extension device that has
+keys, use ChangeDeviceKeyMapping.
+
+                ChangeDeviceKeyMapping
+                        device: DEVICE
+                        first-keycode: KEYCODE
+                        keysyms-per-keycode: CARD8
+                        keysyms: LISTofKEYSYM
+                        num_codes: CARD8
+
+   Errors: Device, Match, Value, Alloc
+
+This request is analogous to the core ChangeKeyMapping request.
+It defines the symbols for the specified number of keycodes for
+the specified extension device. If the specified device has not
+first been opened by this client via OpenDevice, or if that
+device does not support input class Keys, this request will
+fail with a Device error.
+
+The number of elements in the keysyms list must be a multiple
+of keysyms_per_keycode. Otherwise, ChangeDeviceKeyMapping
+generates a Length error. The specified first_keycode must be
+greater than or equal to the min_keycode value returned by the
+ListInputDevices request, or this request will fail with a
+Value error. In addition, if the following expression is not
+less than the max_keycode value returned by the
+ListInputDevices request, the request will fail with a Value
+error:
+
+                first_keycode + (num_codes / keysyms_per_keycode) - 1
+
+To obtain the keycodes that are used as modifiers on an
+extension device that has keys, use GetDeviceModifierMapping.
+
+                GetDeviceModifierMapping
+                        device: DEVICE
+                =>
+                        keycodes-per-modifier: CARD8
+                        keycodes: LISTofKEYCODE
+
+   Errors: Device, Match
+
+This request is analogous to the core GetModifierMapping
+request. This request returns the keycodes of the keys being
+used as modifiers. The number of keycodes in the list is
+8*keycodes-per-modifier. The keycodes are divided into eight
+sets, with each set containing keycodes-per-modifier elements.
+The sets are assigned in order to the modifiers Shift, Lock,
+Control, Mod1, Mod2, Mod3, Mod4, and Mod5. The
+keycodes-per-modifier value is chosen arbitrarily by the
+server; zeroes are used to fill in unused elements within each
+set. If only zero values are given in a set, the use of the
+corresponding modifier has been disabled. The order of keycodes
+within each set is chosen arbitrarily by the server.
+
+To set which keycodes that are to be used as modifiers for an
+extension device, use SetDeviceModifierMapping.
+
+                SetDeviceModifierMapping
+                        device: DEVICE
+                        keycodes-per-modifier: CARD8
+                        keycodes: LISTofKEYCODE
+                =>
+                        status: {Success, Busy, Failed}
+
+   Errors: Device, Match, Value, Alloc
+
+This request is analogous to the core SetModifierMapping
+request. This request specifies the keycodes (if any) of the
+keys to be used as modifiers. The number of keycodes in the
+list must be 8*keycodes-per-modifier (else a Length error). The
+keycodes are divided into eight sets, with the sets, with each
+set containing keycodes-per-modifier elements. The sets are
+assigned in order to the modifiers Shift, Lock, Control, Mod1,
+Mod2, Mod3, Mod4, and Mod5. Only non-zero keycode values are
+used within each set; zero values are ignored. All of the
+non-zero keycodes must be in the range specified by min-keycode
+and max-keycode in the ListInputDevices request (else a Value
+error). The order of keycodes within a set does not matter. If
+no non-zero values are specified in a set, the use of the
+corresponding modifier is disabled, and the modifier bit will
+always be zero. Otherwise, the modifier bit will be one
+whenever at least one of the keys in the corresponding set is
+in the down position.
+
+A server can impose restrictions on how modifiers can be
+changed (for example, if certain keys do not generate up
+transitions in hardware or if multiple keys per modifier are
+not supported). If some such restriction is violated, the status
+reply is MappingFailed, and none of the modifiers are changed.
+
+If the new keycodes specified for a modifier differ from those
+currently defined and any (current or new) keys for that
+modifier are in the logically down state, the status reply is
+MappingBusy, and none of the modifiers are changed.
+
+This request generates a DeviceMappingNotify event on a Success
+status. The DeviceMappingNotify event will be sent only to
+those clients that have expressed an interest in receiving that
+event via the XSelectExtensionEvent request.
+
+2.20 Controlling Button Mapping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These requests are analogous to the core GetPointerMapping and
+ChangePointerMapping requests. They allow a client to determine
+the current mapping of buttons on an extension device, and to
+change that mapping.
+
+To get the current button mapping for an extension device, use
+GetDeviceButtonMapping.
+
+                GetDeviceButtonMapping
+                        device: DEVICE
+                        nmap: CARD8
+                =>
+                        map_return: LISTofCARD8
+
+   Errors: Device, Match
+
+The GetDeviceButtonMapping function returns the current mapping
+of the buttons on the specified device. Elements of the list
+are indexed starting from one. The length of the list indicates
+the number of physical buttons. The nominal mapping is the
+identity mapping map[i]=i.
+
+nmap indicates the number of elements in the map_return array.
+Only the first nmap entries will be copied by the library into
+the map_return array.
+
+To set the button mapping for an extension device, use
+SetDeviceButtonMapping.
+
+                SetDeviceButtonMapping
+                        device: DEVICE
+                        map: LISTofCARD8
+                        nmap: CARD8
+                =>
+                        status: CARD8
+
+   Errors: Device, Match, Value
+
+The SetDeviceButtonMapping function sets the mapping of the
+specified device and causes the X server to generate a
+DeviceMappingNotify event on a status of MappingSuccess.
+Elements of the list are indexed starting from one. The length
+of the list, specified in nmap, must be the same as
+GetDeviceButtonMapping would return. Otherwise,
+SetDeviceButtonMapping generates a Value error. A zero element
+disables a button, and elements are not restricted in value by
+the number of physical buttons. If any of the buttons to be
+altered are in the down state, the status reply is MappingBusy
+and the mapping is not changed.
+
+In servers supporting XI 1.x, no two elements can have the same
+nonzero value. Otherwise, this function generates a Value
+error.
+
+2.21 Obtaining The State Of A Device
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To obtain vectors that describe the state of the keys, buttons
+and valuators of an extension device, use QueryDeviceState.
+
+                QueryDeviceState
+                        device: DEVICE
+                =>
+                        device-id: CARD8
+                        data: LISTofINPUTCLASS
+
+where
+
+                INPUTCLASS: {VALUATOR, BUTTON, KEY}
+                CLASS VALUATOR:
+                            [class: CARD8
+                             num_valuators: CARD8
+                             mode: CARD8
+                             #x01 device mode (0 = Relative, 1 = Absolute)
+                             #x02 proximity state (0 = InProximity, 1 = OutOfProximity)
+                             valuators: LISTofINT32]
+                CLASS BUTTON:
+                            [class: CARD8
+                             num_buttons: CARD8
+                             buttons: LISTofCARD8]
+                CLASS KEY:
+                            [class: CARD8
+                             num_keys: CARD8
+                             keys: LISTofCARD8]
+
+   Errors: Device
+
+The QueryDeviceState request returns the current logical state
+of the buttons, keys, and valuators on the specified input
+device. The buttons and keys arrays, byte N (from 0) contains
+the bits for key or button 8N to 8N+7 with the least
+significant bit in the byte representing key or button 8N.
+
+If the device has valuators, a bit in the mode field indicates
+whether the device is reporting Absolute or Relative data. If
+it is reporting Absolute data, the valuators array will contain
+the current value of the valuators. If it is reporting Relative
+data, the valuators array will contain undefined data.
+
+If the device reports proximity information, a bit in the mode
+field indicates whether the device is InProximity or
+OutOfProximity.
+
+2.22 Listing Device Properties
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduced with XI 1.5
+
+            ListDeviceProperties
+                     deviceid: CARD8
+            =>
+                     nAtoms: CARD16
+                     Atoms: LISTofATOM
+
+   Errors: Device
+
+Each device can store an arbitrary number of properties. These
+properties can be allocated by either the client or the driver.
+The client can change device properties and the server
+guarantees that the device driver is notified about a change of
+the device's properties.
+
+ListDeviceProperties returns all properties of a device. The
+client is expected to retrieve details about the properties it
+is interested in separately.
+
+2.23 Getting a Device Property
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduced with XI 1.5
+
+            GetDeviceProperty:
+                     property: ATOM
+                     type: ATOM
+                     longOffset: CARD32
+                     longLength: CARD32
+                     deviceid: CARD8
+                     delete: BOOL
+            =>
+                     propertyType: ATOM
+                     bytesAfter: CARD32
+                     nItems: CARD32
+                     format: CARD8
+                     deviceid: CARD8
+                     data: [LISTofCARD8]
+
+   Errors: Atom, Device, Value, Access
+
+Retrieve the value for a property. If the property does not
+exist, propertyType is None and all other fields are undefined.
+
+If type is not AnyPropertyType and does not match the
+property's actual type, the propertyType, bytesAfter, and
+format are returned but not the actual data.
+
+longOffset and longLength specify the offset and length
+respectively in 32-bit multiples of the data to retrieve.
+
+If delete is True, the property is deleted after querying its
+data. If the property cannot be deleted, a BadAccess error is
+returned.
+
+propertyType returns the atom identifier that defines the
+actual type of the property.
+
+If bytesAfter is non-zero, it specifies the number of data
+4-byte units after the retrieved chunk of data.
+
+format specifies whether the data should be viewed as a list of
+8-bit, 16-bit, or 32-bit quantities. Possible values are 8, 16,
+and 32. This information allows the X server to correctly
+perform byte-swap operations as necessary.
+
+nItem specifies the number of 8-bit, 16-bit, or 32-bit items
+returned after the request.
+
+2.24 Changing a Device Property
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduced with XI 1.5
+
+            ChangeDeviceProperty:
+                     property: ATOM
+                     type: ATOM
+                     deviceid: CARD8
+                     format: CARD8
+                     mode: CARD8
+                     nUnits: CARD32
+
+   Errors: Atom, Device, Value, Match, Access
+
+Changes the value of a specified property.
+
+The type specifies the atom identifier that defines the type of
+the property. If mode is not PropModeReplace, the type must
+match the current type of the property or a BadMatch error is
+returned.
+
+format specifies whether the data should be viewed as a list of
+8-bit, 16-bit, or 32-bit quantities. Possible values are 8, 16,
+and 32. This information allows the X server to correctly
+perform byte-swap operations as necessary.
+
+If mode is PropModeReplace, a preexising value for this
+property is replaced with the new value. If mode is
+PropModePrepend or PropModeAppend, the value is prepended or
+appended, respectively, to the current value of the property.
+
+nUnits specifies the number of 8-bit, 16-bit, or 32-bit items
+supplied after the reply.
+
+Changing a device property results in a
+DevicePropertyNotifyEvent being sent to all clients.
+
+2.25 Deleting a Device Property
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduced with XI 1.5
+
+            DeleteDeviceProperty:
+                     property: ATOM
+                     deviceid: CARD8
+
+   Errors: Atom, Device, Match, Access.
+
+Deletes the specified property. If the property cannot be
+deleted by the client, a BadAccess error is returned.
+
+3. Events
+---------
+
+The input extension creates input events analogous to the core
+input events. These extension input events are generated by
+manipulating one of the extension input devices.
+
+3.1 Button, Key, and Motion Events
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+            DeviceKeyPress
+            DeviceKeyRelease
+            DeviceButtonPress,
+            DeviceButtonRelease
+            DeviceMotionNotify
+                    device: CARD8
+                    root, event: WINDOW
+                    child: Window or None
+                    same-screen: BOOL
+                    root-x, root-y, event-x, event-y: INT16
+                    detail: <see below>
+                    state: SETofKEYBUTMASK
+                    time: TIMESTAMP
+
+These events are generated when a key, button, or valuator
+logically changes state. The generation of these logical
+changes may lag the physical changes, if device event
+processing is frozen. Note that DeviceKeyPress and
+DeviceKeyRelease are generated for all keys, even those mapped
+to modifier bits. The “source” of the event is the window the
+pointer is in. The window with respect to which the event is
+normally reported is found by looking up the hierarchy
+(starting with the source window) for the first window on which
+any client has selected interest in the event. The actual
+window used for reporting can be modified by active grabs and
+by the focus window.The window the event is reported with
+respect to is called the “event” window.
+
+The root is the root window of the “source” window, and root-x
+and root-y are the pointer coordinates relative to root's
+origin at the time of the event. Event is the “event” window.
+If the event window is on the same screen as root, then event-x
+and event-y are the pointer coordinates relative to the event
+window's origin. Otherwise, event-x and event-y are zero. If
+the source window is an inferior of the event window, then
+child is set to the child of the event window that is an
+ancestor of (or is) the source window. Otherwise, it is set to
+None.
+
+The state component gives the logical state of the buttons on
+the X pointer and modifier keys on the core X keyboard just
+before the event.
+
+The detail component type varies with the event type:
+Event               Component
+DeviceKeyPress      KEYCODE
+DeviceKeyRelease    KEYCODE
+DeviceButtonPress   BUTTON
+DeviceButtonRelease BUTTON
+DeviceMotionNotify  { Normal , Hint }
+
+The granularity of motion events is not guaranteed, but a
+client selecting for motion events is guaranteed to get at
+least one event when a valuator changes. If DeviceMotionHint is
+selected, the server is free to send only one
+DeviceMotionNotify event (with detail Hint) to the client for
+the event window, until either a key or button changes state,
+the pointer leaves the event window, or the client issues a
+QueryDeviceState or GetDeviceMotionEvents request.
+
+3.2 DeviceValuator Event
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+                DeviceValuator
+                        device: CARD8
+                        device_state: SETofKEYBUTMASK
+                        num_valuators: CARD8
+                        first_valuator: CARD8
+                        valuators: LISTofINT32
+
+DeviceValuator events are generated to contain valuator
+information for which there is insufficient space in DeviceKey,
+DeviceButton, DeviceMotion, and Proximity wire events. For
+events of these types, a second event of type DeviceValuator
+follows immediately. The library combines these events into a
+single event that a client can receive via XNextEvent.
+DeviceValuator events are not selected for by clients, they
+only exist to contain information that will not fit into some
+event selected by clients.
+
+The device_state component gives the state of the buttons and
+modifiers on the device generating the event.
+
+Extension motion devices may report motion data for a variable
+number of axes. The valuators array contains the values of all
+axes reported by the device. If more than 6 axes are reported,
+more than one DeviceValuator event will be sent by the server,
+and more than one DeviceKey, DeviceButton, DeviceMotion, or
+Proximity event will be reported by the library. Clients should
+examine the corresponding fields of the event reported by the
+library to determine the total number of axes reported, and the
+first axis reported in the current event. Axes are numbered
+beginning with zero.
+
+For Button, Key and Motion events on a device reporting
+absolute motion data the current value of the device's
+valuators is reported. For devices that report relative data,
+Button and Key events may be followed by a DeviceValuator event
+that contains 0s in the num_valuators field. In this case, only
+the device_state component will have meaning.
+
+3.3 Device Focus Events
+~~~~~~~~~~~~~~~~~~~~~~~
+
+                DeviceFocusIn
+                DeviceFocusOut
+                        device: CARD8
+                        time: TIMESTAMP
+                        event: WINDOW
+                        mode: { Normal, WhileGrabbed, Grab, Ungrab}
+                        detail: { Ancestor, Virtual, Inferior, Nonlinear,
+                                  NonlinearVirtual, Pointer, PointerRoot, None}
+
+These events are generated when the input focus changes and are
+reported to clients selecting DeviceFocusChange for the
+specified device and window. Events generated by SetDeviceFocus
+when the device is not grabbed have mode Normal. Events
+generated by SetDeviceFocus when the device is grabbed have
+mode WhileGrabbed. Events generated when a device grab activates
+have mode Grab, and events generated when a device grab
+deactivates have mode Ungrab.
+
+All DeviceFocusOut events caused by a window unmap are
+generated after any UnmapNotify event, but the ordering of
+DeviceFocusOut with respect to generated EnterNotify,
+LeaveNotify, VisibilityNotify and Expose events is not
+constrained.
+
+DeviceFocusIn and DeviceFocusOut events are generated for focus
+changes of extension devices in the same manner as focus events
+for the core devices are generated.
+
+3.4 Device State Notify Event
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+                DeviceStateNotify
+                time: TIMESTAMP
+                device: CARD8
+                num_keys: CARD8
+                num_buttons: CARD8
+                num_valuators: CARD8
+                classes_reported: CARD8 {SetOfDeviceMode | SetOfInputClass}
+                    SetOfDeviceMode:
+                        #x80 ProximityState 0 = InProxmity, 1 = OutOfProximity
+                        #x40 Device Mode (0 = Relative, 1 = Absolute)
+                    SetOfInputClass: #x04 reporting valuators
+                        #x02 reporting buttons
+                        #x01 reporting keys
+                buttons: LISTofCARD8
+                keys: LISTofCARD8
+                valuators: LISTofCARD32
+
+This event reports the state of the device just as in the
+QueryDeviceState request. This event is reported to clients
+selecting DeviceStateNotify for the device and window and is
+generated immediately after every EnterNotify and
+DeviceFocusIn. If the device has no more than 32 buttons, no
+more than 32 keys, and no more than 3 valuators, This event can
+report the state of the device. If the device has more than 32
+buttons, the event will be immediately followed by a
+DeviceButtonStateNotify event. If the device has more than 32
+keys, the event will be followed by a DeviceKeyStateNotify
+event. If the device has more than 3 valuators, the event will
+be followed by one or more DeviceValuator events.
+
+3.5 Device KeyState and ButtonState Notify Events
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+                DeviceKeyStateNotify
+                        device: CARD8
+                        keys: LISTofCARD8
+                DeviceButtonStateNotify
+                        device: CARD8
+                        buttons: LISTofCARD8
+
+These events contain information about the state of keys and
+buttons on a device that will not fit into the
+DeviceStateNotify wire event. These events are not selected by
+clients, rather they may immediately follow a DeviceStateNotify
+wire event and be combined with it into a single
+DeviceStateNotify client event that a client may receive via
+XNextEvent.
+
+3.6 DeviceMappingNotify Event
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+                DeviceMappingNotify
+                        time: TIMESTAMP
+                        device: CARD8
+                        request: CARD8
+                        first_keycode: CARD8
+                        count: CARD8
+
+This event reports a change in the mapping of keys, modifiers,
+or buttons on an extension device. This event is reported to
+clients selecting DeviceMappingNotify for the device and window
+and is generated after every client SetDeviceButtonMapping,
+ChangeDeviceKeyMapping, or ChangeDeviceModifierMapping request.
+
+3.7 ChangeDeviceNotify Event
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+                ChangeDeviceNotify
+                        device: CARD8
+                        time: TIMESTAMP
+                        request: CARD8
+
+This event reports a change in the physical device being used
+as the core X keyboard or X pointer device. ChangeDeviceNotify
+events are reported to clients selecting ChangeDeviceNotify for
+the device and window and is generated after every client
+ChangeKeyboardDevice or ChangePointerDevice request.
+
+3.7 Proximity Events
+~~~~~~~~~~~~~~~~~~~~
+
+                ProximityIn
+                ProximityOut
+                        device: CARD8
+                        root, event: WINDOW
+                        child: Window or None
+                        same-screen: BOOL
+                        root-x, root-y, event-x, event-y: INT16
+                        state: SETofKEYBUTMASK
+                        time: TIMESTAMP
+                        device-state: SETofKEYBUTMASK
+                        axis-count: CARD8
+                        first-axis: CARD8
+                        axis-data: LISTofINT32
+
+These events are generated by some devices (such as graphics
+tablets or touchscreens) to indicate that a stylus has moved
+into or out of contact with a positional sensing surface.
+
+The “source” of the event is the window the pointer is in. The
+window with respect to which the event is normally reported is
+found by looking up the hierarchy (starting with the source
+window) for the first window on which any client has selected
+interest in the event. The actual window used for reporting can
+be modified by active grabs and by the focus window.The window
+the event is reported with respect to is called the “event”
+window.
+
+The root is the root window of the “source” window, and root-x
+and root-y are the pointer coordinates relative to root's
+origin at the time of the event. Event is the “event” window.
+If the event window is on the same screen as root, then event-x
+and event-y are the pointer coordinates relative to the event
+window's origin. Otherwise, event-x and event-y are zero. If
+the source window is an inferior of the event window, then
+child is set to the child of the event window that is an
+ancestor of (or is) the source window. Otherwise, it is set to
+None. The state component gives the logical state of the
+buttons on the core X pointer and modifier keys on the core X
+keyboard just before the event. The device-state component
+gives the state of the buttons and modifiers on the device
+generating the event.
+
+3.8 DevicePresenceEvents
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduced with XI 1.4.
+
+                DevicePresence
+                        time: TIMESTAMP
+                        devchange: BYTE
+                            #x00: DeviceAdded
+                            #x01: DeviceRemoved
+                            #x02: DeviceEnabled
+                            #x03: DeviceDisabled
+                            #x04: DeviceUnrecoverable
+                            #x05: DeviceControlChanged
+                        deviceid: BYTE
+                        control: CARD16
+
+DevicePresence events are sent when the server adds or removes,
+or enables or disables an input device. The client is expected
+to query the server for the list of input devices using the
+ListInputDevices request to obtain the updated list of input
+devices. DevicePresence events are also sent when a control on
+the device has been changed.
+
+The devchange field specifies the type of operation. In case of
+DeviceAdded, a new device has been added to the server, but
+this device does not yet send events. If devchange is set to
+DeviceEnabled, the device is enabled and will generate events.
+If the field is DeviceDisabled or DeviceRemoved, the given
+device is disabled and stops sending events or was removed from
+the server, respectively. If the field is DeviceUnrecoverable,
+an IO-error has occured on the device and the device is
+forcibly disabled and removed by the server. If devchange is
+DeviceControlChanged, control specifies the type of control
+that has been changed.
+
+3.9 DevicePropertyNotifyEvent
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduced with XI 1.5.
+
+                DevicePropertyNotifyEvent
+                        deviceid: CARD8
+                        state: CARD8
+                        time: TIMESTAMP
+                        atom: ATOM
+
+A DevicePropertyNotifyEvent is sent to all clients when a
+property on the device is created, deleted, or changes value.
+
+The deviceid specifies the device which's property has been
+modified.
+
+The atom specifies the named identifier of the property that
+has been altered.
+
+If state is PropertyNewValue, the given property has a new
+value or has been newly created. If state is PropertyDeleted,
+the given property has been deleted.