summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2008-05-10 16:26:46 +0930
committerPeter Hutterer <peter@cs.unisa.edu.au>2008-05-11 23:22:13 +0930
commit023bac145790e87a2400bc6ad2fdf684f12a1098 (patch)
treebabd97a68afa4636ff9a26c750eb8eebd43938c6
parent2327364cf7d2b71455a5b4f5aa3600516533e376 (diff)
Xi specs: Doclifted protocol.xml.
-rw-r--r--specs/Xi/protocol.xml2999
1 files changed, 2999 insertions, 0 deletions
diff --git a/specs/Xi/protocol.xml b/specs/Xi/protocol.xml
new file mode 100644
index 0000000..bf8361b
--- /dev/null
+++ b/specs/Xi/protocol.xml
@@ -0,0 +1,2999 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+<!-- lifted from troff+ms by doclifter -->
+<article id='protocolms'>
+<!-- .EH '''' -->
+<!-- .OH '''' -->
+<!-- .EF '''' -->
+<!-- .OF '''' -->
+<!-- .ps 11 -->
+&numsp;
+<!-- .ce 500 -->
+<!-- .ps 20 -->
+<emphasis remap='B'>X11 Input Extension Protocol Specification
+<!-- .ps 12 -->
+Version 1.0
+X Consortium Standard
+X Version 11, Release 6.8
+<!-- .ps 15 -->
+Mark Patrick&numsp;&numsp;&numsp;&numsp;Ardent Computer
+George Sachs&numsp;&numsp;&numsp;&numsp;Hewlett-Packard
+<!-- .ps 12 -->
+<!-- .ce 0 -->
+<!-- .bp -->
+&numsp;
+<para>Copyright &copy; 1989, 1990, 1991 by Hewlett-Packard Company and Ardent Computer</emphasis></para>
+<para>Permission to use, copy, modify, and distribute this documentation for
+any purpose and without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+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 &copy; 1989, 1990, 1991, 1992 X Consortium</para>
+<para>Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the &ldquo;Software&rdquo;), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:</para>
+<para>The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.</para>
+<para>THE SOFTWARE IS PROVIDED &ldquo;AS IS&rdquo;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</para>
+<para>Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+<emphasis remap='I'>X Window System</emphasis> is a trademark of The Open Group.</para>
+<!-- .ps -->
+<!-- .vs -->
+<!-- .bp 1 -->
+<!-- .EH '\fBX Input Extension Protocol Specification\fP''\fBX11, Release 6.8\fP' -->
+<!-- .OH '\fBX Input Extension Protocol Specification\fP''\fBX11, Release 6.8\fP' -->
+<!-- .EF ''\fB\\n(PN\fP'' -->
+<!-- .OF ''\fB\\n(PN\fP'' -->
+<!-- Force the heading counter for level 1 to one -->
+<!-- Print table of contents to level 4 headings -->
+<!-- Page eject for each level 1 heading -->
+<!-- Define Ch to contain the chapter string. -->
+<!-- Pull in the layout macro package. -->
+<sect2 id='input_extension_overview'><title>Input Extension Overview</title>
+<!-- .XS -->
+<para>\*(SN Input Extension Overview</para>
+<!-- .XE -->
+<para>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.</para>
+</sect2>
+<sect2 id='design_approach'><title>Design Approach</title>
+<!-- .XS -->
+<para>\*(SN Design Approach</para>
+<!-- .XE -->
+<para>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.</para>
+</sect2>
+<sect2 id='core_input_devices'><title>Core Input Devices</title>
+<!-- .XS -->
+<para>\*(SN Core Input Devices</para>
+<!-- .XE -->
+<para>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.</para>
+<para>The X keyboard is used to generate input that client programs can detect.</para>
+<para>The X keyboard and X pointer are referred to in this document as
+the <emphasis remap='I'>core devices</emphasis>, and the input
+events they generate (<emphasis remap='B'>KeyPress</emphasis>, <emphasis remap='B'>KeyRelease</emphasis>, <emphasis remap='B'>ButtonPress</emphasis>,
+<emphasis remap='B'>ButtonRelease</emphasis>, and
+<emphasis remap='B'>MotionNotify</emphasis>) are known as the <emphasis remap='I'>core input events</emphasis>. All other
+input devices are referred to as <emphasis remap='I'>extension input devices</emphasis> and the
+input events they generate are referred to as <emphasis remap='I'>extension input events</emphasis>.</para>
+<para>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".</para>
+<para>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.</para>
+</sect2>
+<sect2 id='extension_input_devices'><title>Extension Input Devices</title>
+<!-- .XS -->
+<para>\*(SN Extension Input Devices</para>
+<!-- .XE -->
+<para>The input extension 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.</para>
+<para>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
+<emphasis remap='B'>ListInputDevices</emphasis> 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 <emphasis remap='B'>OpenDevice</emphasis> 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 (<emphasis remap='B'>DeviceKeyPress</emphasis>,
+<emphasis remap='B'>DeviceKeyRelease</emphasis>, <emphasis remap='B'>DeviceButtonPress</emphasis>, <emphasis remap='B'>DeviceButtonRelease</emphasis>,
+<emphasis remap='B'>DeviceMotionNotify</emphasis>, etc.) and contain a device identifier so that events
+of the same type coming from different input devices can be distinguished.</para>
+<para>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).</para>
+<para>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 <emphasis remap='B'>input classes</emphasis>. 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.</para>
+<para>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.</para>
+<para>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.</para>
+<sect3 id='event_classes'><title>Event Classes</title>
+<!-- .XS -->
+<para>\*(SN Event Classes</para>
+<!-- .XE -->
+<para>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.</para>
+<para>When a client opens a extension input device via the <emphasis remap='B'>OpenDevice</emphasis> request,
+an <emphasis remap='B'>XDevice</emphasis> structure is returned. Macros are provided that extract
+32-bit numbers called <emphasis remap='B'>event classes</emphasis> from that structure, that a client
+can use to register interest in extension events via the
+<emphasis remap='B'>SelectExtensionEvent</emphasis> request. The event class combines the desired
+event type and device id, and may be thought of as the equivalent of core
+event masks.</para>
+</sect3>
+<sect3 id='input_classes'><title>Input Classes</title>
+<!-- .XS -->
+<para>\*(SN Input Classes</para>
+<!-- .XE -->
+<para>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:</para>
+<!-- .RS -->
+<!-- .in +5n -->
+<variablelist remap='IP'>
+ <varlistentry>
+ <term><emphasis remap='B'>KEY</emphasis></term>
+ <listitem>
+<para>The device reports key events.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>BUTTON</emphasis></term>
+ <listitem>
+<para>The device reports button events.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>VALUATOR</emphasis></term>
+ <listitem>
+<para>The device reports valuator data in motion events.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>PROXIMITY</emphasis></term>
+ <listitem>
+<para>The device reports proximity events.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>FOCUS</emphasis></term>
+ <listitem>
+<para>The device can be focused and reports focus events.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>FEEDBACK</emphasis></term>
+ <listitem>
+<para>The device supports feedbacks.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>OTHER</emphasis></term>
+ <listitem>
+<para>The <emphasis remap='B'>ChangeDeviceNotify</emphasis>, <emphasis remap='B'>DeviceMappingNotify</emphasis>, and
+<emphasis remap='B'>DeviceStateNotify</emphasis> macros may be invoked passing the <emphasis remap='B'>XDevice</emphasis>
+structure returned for this device.</para>
+<!-- .in \-5n -->
+<!-- .RE -->
+<para>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
+<emphasis remap='B'>ListInputDevices</emphasis> 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.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+</sect2>
+</sect1>
+<sect1 id='requests'><title>Requests</title>
+<!-- .XS -->
+<para>\*(SN Requests</para>
+<!-- .XE -->
+<para>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.</para>
+<sect2 id='getting_the_extension_version'><title>Getting the Extension Version</title>
+<!-- .XS -->
+<para>\*(SN Getting the Extension Version</para>
+<!-- .XE -->
+<para>The <emphasis remap='B'>GetExtensionVersion</emphasis> request returns version information about
+the input extension.
+GetExtensionVersion
+<!-- .in +.5i -->
+name: STRING
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+<!-- .br -->
+present: BOOL
+<!-- .br -->
+protocol-major-version: CARD16
+<!-- .br -->
+protocol-minor-version: CARD16
+<!-- .br -->
+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 <filename>XI.h</filename>. Each version is
+a superset of the previous versions.</para>
+</sect2>
+<sect2 id='listing_available_devices'><title>Listing Available Devices</title>
+<!-- .XS -->
+<para>\*(SN Listing Available Devices</para>
+<!-- .XE -->
+<para>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
+<emphasis remap='B'>ListInputDevices</emphasis> request, which will return a list of all devices that
+can be opened by the X server.
+ListInputDevices
+<!-- .br -->
+=&gt;
+<!-- .in +.5i -->
+<!-- .br -->
+input-devices: LISTofDEVICEINFO
+<!-- .br -->
+<!-- .in \-.5i -->
+where</para>
+<!-- .in +.5i -->
+<!-- .br -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>DEVICEINFO:</entry>
+ <entry align='left'><para>[type: ATOM
+<!-- .br -->
+&nbsp;id: CARD8
+<!-- .br -->
+&nbsp;num_classes: CARD8
+<!-- .br -->
+&nbsp;use: {IsXKeyboard, IsXPointer, IsExtensionDevice}
+<!-- .br -->
+&nbsp;info: LISTofINPUTINFO
+<!-- .br -->
+&nbsp;name: STRING8]</para></entry>
+ </row>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>INPUTINFO:</entry>
+ <entry align='left'>{KEYINFO, BUTTONINFO, VALUATORINFO}</entry>
+ </row>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>KEYINFO:</entry>
+ <entry align='left'>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD8
+<!-- .br -->
+&nbsp;min-keycode: KEYCODE
+<!-- .br -->
+&nbsp;max-keycode: KEYCODE
+<!-- .br -->
+&nbsp;num-keys: CARD16]</entry>
+ </row>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>BUTTONINFO:</entry>
+ <entry align='left'><!-- .br -->
+[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD8
+<!-- .br -->
+&nbsp;num-buttons: CARD16]</entry>
+ </row>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>VALUATORINFO:</entry>
+ <entry align='left'>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD8
+<!-- .br -->
+&nbsp;num_axes: CARD8
+<!-- .br -->
+&nbsp;mode: SETofDEVICEMODE
+<!-- .br -->
+&nbsp;motion_buffer_size: CARD32
+<!-- .br -->
+&nbsp;axes: LISTofAXISINFO]</entry>
+ </row>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>AXISINFO:</entry>
+ <entry align='left'>[resolution: CARD32
+<!-- .br -->
+&nbsp;min-val: CARD32
+<!-- .br -->
+&nbsp;max-val: CARD32]</entry>
+ </row>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>DEVICEMODE:</entry>
+ <entry align='left'>{Absolute, Relative}</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .br -->
+<para>Errors: None
+<!-- .in \-.5i -->
+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.</para>
+<variablelist remap='IP'>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>The information returned for each device is as follows:</para>
+<para>The <emphasis remap='B'>type</emphasis> field is of type <emphasis remap='B'>Atom</emphasis> and indicates the nature of the
+device. Clients may determine device types by invoking the <emphasis remap='B'>XInternAtom</emphasis>
+request passing one of the names defined in the header file <filename>XI.h</filename>. The
+following names have been defined to date:</para>
+<literallayout remap='DS'>
+<emphasis remap='B'>MOUSE</emphasis>
+<emphasis remap='B'>TABLET</emphasis>
+<emphasis remap='B'>KEYBOARD</emphasis>
+<emphasis remap='B'>TOUCHSCREEN</emphasis>
+<emphasis remap='B'>TOUCHPAD</emphasis>
+<emphasis remap='B'>BUTTONBOX</emphasis>
+<emphasis remap='B'>BARCODE</emphasis>
+<emphasis remap='B'>KNOB_BOX</emphasis>
+<emphasis remap='B'>TRACKBALL</emphasis>
+<emphasis remap='B'>QUADRATURE</emphasis>
+<emphasis remap='B'>SPACEBALL</emphasis>
+<emphasis remap='B'>DATAGLOVE</emphasis>
+<emphasis remap='B'>EYETRACKER</emphasis>
+<emphasis remap='B'>CURSORKEYS</emphasis>
+<emphasis remap='B'>FOOTMOUSE</emphasis>
+<emphasis remap='B'>ID_MODULE</emphasis>
+<emphasis remap='B'>ONE_KNOB</emphasis>
+<emphasis remap='B'>NINE_KNOB</emphasis>
+</literallayout> <!-- remap='DE' -->
+<para>The <emphasis remap='B'>id</emphasis> 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 <emphasis remap='B'>XOpenDevice</emphasis>,
+then closed via <emphasis remap='B'>XCloseDevice</emphasis>, then opened again, it is not guaranteed
+to have the same id after the second open request.</para>
+<para>The <emphasis remap='B'>num_classes</emphasis> 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 <emphasis remap='B'>ListInputDevices</emphasis>. Some input classes,
+such as class <emphasis remap='B'>Focus</emphasis> and class <emphasis remap='B'>Proximity</emphasis> do not have any information
+to be returned by <emphasis remap='B'>ListInputDevices</emphasis>.</para>
+<para>The <emphasis remap='B'>use</emphasis> field specifies how the device is currently being used. If the
+value is <emphasis remap='B'>IsXKeyboard</emphasis>, the device is currently being used as the
+X keyboard. If the value is <emphasis remap='B'>IsXPointer</emphasis>, the device is currently
+being used as the X pointer. If the value is <emphasis remap='B'>IsXExtensionDevice</emphasis>,
+the device is available for use as an extension device.</para>
+<para>The <emphasis remap='B'>name</emphasis> field contains a pointer to a null-terminated string that
+corresponds to one of the defined device types.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para><emphasis remap='B'>InputInfo</emphasis> is one of: <emphasis remap='B'>KeyInfo</emphasis>, <emphasis remap='B'>ButtonInfo</emphasis> or
+<emphasis remap='B'>ValuatorInfo</emphasis>. The first two fields are common to all three:</para>
+<para>The <emphasis remap='B'>class</emphasis> field is a cardinal value in the range 0-255. It uniquely
+identifies the class of input for which information is returned.</para>
+<para>The <emphasis remap='B'>length</emphasis> 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.</para>
+<para>The remaining information returned for input class <emphasis remap='B'>KEYCLASS</emphasis> is as follows:</para>
+<para><emphasis remap='B'>min_keycode</emphasis> is of type KEYCODE. It specifies the minimum keycode that
+the device will report. The minimum keycode will not be smaller than 8.</para>
+<para><emphasis remap='B'>max_keycode</emphasis> is of type KEYCODE. It specifies the maximum keycode that
+the device will report. The maximum keycode will not be larger than 255.</para>
+<para><emphasis remap='B'>num_keys</emphasis> is a cardinal value that specifies the number of keys that the
+device has.</para>
+<para>The remaining information returned for input class <emphasis remap='B'>BUTTONCLASS</emphasis> is as
+follows:</para>
+<para><emphasis remap='B'>num_buttons</emphasis> is a cardinal value that specifies the number of buttons
+that the device has.</para>
+<para>The remaining information returned for input class <emphasis remap='B'>VALUATORCLASS</emphasis> is as
+follows:</para>
+<para><emphasis remap='B'>mode</emphasis> is a constant that has one of the following values: <emphasis remap='B'>Absolute</emphasis>
+or <emphasis remap='B'>Relative</emphasis>. Some devices allow the mode to be changed dynamically
+via the <emphasis remap='B'>SetDeviceMode</emphasis> request.</para>
+<para><emphasis remap='B'>motion_buffer_size</emphasis> is a cardinal number that specifies the number of
+elements that can be contained in the motion history buffer for the device.</para>
+<para>The <emphasis remap='B'>axes</emphasis> field contains a pointer to an AXISINFO struture.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>The information returned for each axis reported by the device is:</para>
+<para>The <emphasis remap='B'>resolution</emphasis> is a cardinal value in counts/meter.</para>
+<para>The <emphasis remap='B'>min_val</emphasis> field is a cardinal value in that contains the minimum
+value the device reports for this axis. For devices whose mode is
+<emphasis remap='B'>Relative</emphasis>, the min_val field will contain 0.</para>
+<para>The <emphasis remap='B'>max_val</emphasis> field is a cardinal value in that contains the maximum
+value the device reports for this axis. For devices whose mode is
+<emphasis remap='B'>Relative</emphasis>, the max_val field will contain 0.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect2>
+<sect2 id='enabling_devices'><title>Enabling Devices</title>
+<!-- .XS -->
+<para>\*(SN Enabling Devices</para>
+<!-- .XE -->
+<para>Client programs that wish to access an extension device must request that
+the server open that device. This is done via the <emphasis remap='B'>OpenDevice</emphasis>
+request.
+OpenDevice
+<!-- .in +.5i -->
+id: CARD8
+<!-- .in \-.5i -->
+=&gt;</para>
+<!-- .in +.5i -->
+<!-- .br -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>DEVICE:</entry>
+ <entry align='left'><para>[device_id: XID
+<!-- .br -->
+&nbsp;num_classes: INT32
+<!-- .br -->
+&nbsp;classes: LISTofINPUTCLASSINFO]</para></entry>
+ </row>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>INPUTCLASSINFO:</entry>
+ <entry align='left'>[input_class: CARD8
+<!-- .br -->
+&nbsp;event_type_base: CARD8]</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<para>Errors: Device</para>
+<!-- .in \-.5i -->
+<para>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 <emphasis remap='B'>Keys</emphasis> reports
+<emphasis remap='B'>DeviceKeyPress</emphasis> and <emphasis remap='B'>DeviceKeyRelease</emphasis> event classes. Input classes
+are unique numbers registered with the X Consortium. Input class
+<emphasis remap='B'>Other</emphasis> exists
+to report event classes that are not specific to any one input class,
+such as <emphasis remap='B'>DeviceMappingNotify</emphasis>, <emphasis remap='B'>ChangeDeviceNotify</emphasis>, and
+<emphasis remap='B'>DeviceStateNotify</emphasis>.</para>
+<variablelist remap='IP'>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>The information returned for each device is as follows:</para>
+<para>The <emphasis remap='B'>device_id</emphasis> is a number that uniquely identifies the device.</para>
+<para>The <emphasis remap='B'>num_classes</emphasis> field contains the number of input classes supported
+by this device.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>For each class of input supported by the device,
+the <emphasis remap='B'>InputClassInfo</emphasis> structure contains the following information:</para>
+<para>The <emphasis remap='B'>input_class</emphasis> is a small cardinal number that identifies the class
+of input.</para>
+<para>The <emphasis remap='B'>event_type_base</emphasis> 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 <emphasis remap='B'>Device</emphasis> 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".</para>
+<para>Before it exits,
+the client program should explicitly request that the server close
+the device. This is done via the <emphasis remap='B'>CloseDevice</emphasis> request.</para>
+<para>A client may open the same extension device more than once. Requests
+after the first successful one return an additional <emphasis remap='B'>XDevice</emphasis> structure
+with the same information as the first, but otherwise have no effect.
+A single <emphasis remap='B'>CloseDevice</emphasis> request will terminate that client's access to
+the device.</para>
+<para>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.</para>
+<para>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.</para>
+<para>CloseDevice
+<!-- .in +.5i -->
+device: DEVICE
+<!-- .br -->
+Errors: Device</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect2>
+<sect2 id='changing_the_mode_of_a_device'><title>Changing The Mode Of A Device</title>
+<!-- .XS -->
+<para>\*(SN Changing The Mode Of A Device</para>
+<!-- .XE -->
+<para>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
+<emphasis remap='B'>SetDeviceMode</emphasis> request. The valid values are <emphasis remap='B'>Absolute</emphasis> or
+<emphasis remap='B'>Relative</emphasis>.</para>
+<para>This request will fail and return <emphasis remap='B'>DeviceBusy</emphasis> if another client already
+has the device open with a different mode. It will fail and return
+<emphasis remap='B'>AlreadyGrabbed</emphasis> if another client has the device grabbed.
+The request will fail with
+a <emphasis remap='B'>BadMatch</emphasis> error if the requested mode is not supported by the device.
+SetDeviceMode
+<!-- .in +.5i -->
+device: DEVICE
+<!-- .br -->
+mode: {Absolute, Relative}
+<!-- .br -->
+Errors: Device, Match, Mode
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+status: {Success, DeviceBusy, AlreadyGrabbed}</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+</sect2>
+<sect2 id='initializing_valuators_on_an_input_devic'><title>Initializing Valuators on an Input Device</title>
+<!-- .XS -->
+<para>\*(SN Initializing Valuators on an Input Device</para>
+<!-- .XE -->
+<para>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 <emphasis remap='B'>Absolute</emphasis>.
+To initialize the valuators on such a device, use the <emphasis remap='B'>SetDeviceValuators</emphasis>
+request.
+SetDeviceValuators
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+first_valuator: CARD8
+<!-- .br -->
+num_valuators: CARD8
+<!-- .br -->
+valuators: LISTOFINT32
+<!-- .br -->
+Errors: Length, Device, Match, Value
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+status: {Success, AlreadyGrabbed}</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>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 <emphasis remap='B'>Value</emphasis> error will result.</para>
+<para>If the request succeeds, <emphasis remap='B'>Success</emphasis> is returned. If the specifed device is
+grabbed by some other client, the request will fail and a status of
+<emphasis remap='B'>AlreadyGrabbed</emphasis> will be returned.</para>
+</sect2>
+<sect2 id='getting_input_device_controls'><title>Getting Input Device Controls</title>
+<!-- .XS -->
+<para>\*(SN Getting Input Device Controls</para>
+<!-- .XE -->
+<para>GetDeviceControl
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+control: XID
+<!-- .br -->
+Errors: Length, Device, Match, Value
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+controlState: {DeviceState}</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>where</para>
+<!-- .in +.5i -->
+<!-- .br -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>DeviceState:</entry>
+ <entry align='left'>DeviceResolutionState</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<!-- .br -->
+<para>Errors: Length, Device, Match, Value</para>
+<para>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.</para>
+<para>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.</para>
+<para>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.</para>
+<para>Supported device controls and the information returned for them include:</para>
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>DEVICE_RESOLUTION:</entry>
+ <entry align='left'><para>[control: CARD16
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;num_valuators: CARD8
+<!-- .br -->
+&nbsp;resolutions: LISTofCARD32
+<!-- .br -->
+&nbsp;min_resolutions: LISTofCARD32
+<!-- .br -->
+&nbsp;max_resolutions: LISTofCARD32]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<para>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.</para>
+<para>When this control is specified, XGetDeviceControl will fail with a BadMatch
+error if the specified device has no valuators.
+ChangeDeviceControl
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+XID: controlId
+<!-- .br -->
+control: DeviceControl</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>where</para>
+<!-- .in +.5i -->
+<!-- .br -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>DeviceControl:</entry>
+ <entry align='left'>DeviceResolutionControl</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<!-- .br -->
+<para>Errors: Length, Device, Match, Value
+<!-- .br -->
+=&gt;
+<!-- .in +.5i -->
+status: {Success, DeviceBusy, AlreadyGrabbed}</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>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.</para>
+<para>The information passed with this request varies according to the specified
+control and is mapped by a structure appropriate for that control.</para>
+<para>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.</para>
+<para>Supported device controls and the information specified for them include:</para>
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>DEVICE_RESOLUTION:</entry>
+ <entry align='left'><para>[control: CARD16
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;first_valuator: CARD8
+<!-- .br -->
+&nbsp;num_valuators: CARD8
+<!-- .br -->
+&nbsp;resolutions: LISTofCARD32]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<para>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.</para>
+<para>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.</para>
+<para>If the request fails for any reason, none of the valuator resolutions will be
+changed.</para>
+</sect2>
+<sect2 id='selecting_extension_device_events'><title>Selecting Extension Device Events</title>
+<!-- .XS -->
+<para>\*(SN Selecting Extension Device Events</para>
+<!-- .XE -->
+<para>Extension input events are selected using the <emphasis remap='B'>SelectExtensionEvent</emphasis>
+request.
+SelectExtensionEvent
+<!-- .in .5i -->
+window: WINDOW
+<!-- .br -->
+interest: LISTofEVENTCLASS
+<!-- .br -->
+Errors: Window, Class, Access</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This request specifies to the server the events within the specified window
+which are of interest to the client. As with the core <emphasis remap='B'>XSelectInput</emphasis>
+function, multiple clients can select input on the same window.</para>
+<para><emphasis remap='B'>XSelectExtensionEvent</emphasis> requires a list of <emphasis remap='I'>event classes</emphasis>.
+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 <emphasis remap='B'>XOpenDevice</emphasis> request. The names of these macros correspond
+to the desired events, i.e. the <emphasis remap='B'>DeviceKeyPress</emphasis> is used to
+obtain the event class for <emphasis remap='B'>DeviceKeyPress</emphasis> events. The syntax
+of the macro invocation is:
+DeviceKeyPress (device, event_type, event_class);
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+event_type: INT
+<!-- .br -->
+event_class: INT</para>
+<!-- .in \-.5i -->
+<!-- .br -->
+<para>The value returned in <emphasis remap='B'>event_type</emphasis> is the value that will be contained in
+the event type field of the <emphasis remap='B'>XDeviceKeyPressEvent</emphasis> when it is received by
+the client. The value returned in <emphasis remap='B'>event_class</emphasis> is the value that should
+be passed in making an <emphasis remap='B'>XSelectExtensionEvent</emphasis> request to receive
+<emphasis remap='B'>DeviceKeyPress</emphasis> events.</para>
+<para>For <emphasis remap='B'>DeviceButtonPress</emphasis> 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 <emphasis remap='B'>DeviceButtonRelease</emphasis> event for each <emphasis remap='B'>DeviceButtonPress</emphasis>
+event it receives, it should specify the <emphasis remap='B'>DeviceButtonPressGrab</emphasis>
+event class as well as the <emphasis remap='B'>DeviceButtonPress</emphasis> event class.
+This restricts the client in that only one client at a time
+may request <emphasis remap='B'>DeviceButtonPress</emphasis> events from the same device and
+window if any client specifies this class.</para>
+<para>If any client has specified the <emphasis remap='B'>DeviceButtonPressGrab</emphasis> class, any requests
+by any other client that specify the same device and window and specify
+<emphasis remap='B'>DeviceButtonPress</emphasis> or <emphasis remap='B'>DeviceButtonPressGrab</emphasis> will
+cause an <emphasis remap='B'>Access</emphasis> error to be generated.</para>
+<para>If only the <emphasis remap='B'>DeviceButtonPress</emphasis> 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.</para>
+<para>A client may also specify the <emphasis remap='B'>DeviceOwnerGrabButton</emphasis> class. If it has
+specified both the <emphasis remap='B'>DeviceButtonPressGrab</emphasis> and the
+<emphasis remap='B'>DeviceOwnerGrabButton</emphasis> classes, implicit passive grabs will activate
+with owner_events set to <emphasis remap='B'>True</emphasis>. If only the
+<emphasis remap='B'>DeviceButtonPressGrab</emphasis> class is specified, implicit passive grabs will
+activate with owner_events set to <emphasis remap='B'>False</emphasis>.</para>
+<para>The client may select <emphasis remap='B'>DeviceMotion</emphasis> events only when a
+button is down. It does this by specifying the event classes
+<emphasis remap='B'>Button1Motion</emphasis> through <emphasis remap='B'>Button5Motion</emphasis>, or <emphasis remap='B'>ButtonMotion</emphasis>.
+An input device will only support
+as many button motion classes as it has buttons.</para>
+</sect2>
+<sect2 id='determining_selected_events'><title>Determining Selected Events</title>
+<!-- .XS -->
+<para>\*(SN Determining Selected Events</para>
+<!-- .XE -->
+<para>To determine which extension events are currently selected from a given
+window, use <emphasis remap='B'>GetSelectedExtensionEvents</emphasis>.
+GetSelectedExtensionEvents
+<!-- .in .5i -->
+window: WINDOW
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+<!-- .br -->
+this-client: LISTofEVENTCLASS
+<!-- .br -->
+all-clients: LISTofEVENTCLASS
+<!-- .br -->
+Errors: Window</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>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
+<emphasis remap='B'>GetWindowAttributes</emphasis> request.</para>
+</sect2>
+<sect2 id='controlling_event_propagation'><title>Controlling Event Propagation</title>
+<!-- .XS -->
+<para>\*(SN Controlling Event Propagation</para>
+<!-- .XE -->
+<para>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.</para>
+<para>Client programs may control extension event propagation through the use
+of the following two requests.</para>
+<para><emphasis remap='B'>XChangeDeviceDontPropagateList</emphasis> 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.</para>
+<para>ChangeDeviceDontPropagateList
+<!-- .in .5i -->
+window: WINDOW
+<!-- .br -->
+eventclass: LISTofEVENTCLASS
+<!-- .br -->
+mode: {AddToList, DeleteFromList}
+<!-- .br -->
+Errors: Window, Class, Mode</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This function modifies the list specifying the events that are not propagated
+to the ancestors of the specified window. You may use the modes <emphasis remap='B'>AddToList</emphasis>
+or <emphasis remap='B'>DeleteFromList</emphasis>.
+GetDeviceDontPropagateList
+<!-- .in .5i -->
+window: WINDOW
+<!-- .br -->
+Errors: Window
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+dont-propagate-list: LISTofEVENTCLASS</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This function returns a list specifying the events that are not propagated
+to the ancestors of the specified window.</para>
+</sect2>
+<sect2 id='sending_extension_events'><title>Sending Extension Events</title>
+<!-- .XS -->
+<para>\*(SN Sending Extension Events</para>
+<!-- .XE -->
+<para>One client program may send an event to another via the
+<emphasis remap='B'>XSendExtensionEvent</emphasis> function.</para>
+<para>The event in the <emphasis remap='B'>XEvent</emphasis> 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 <emphasis remap='B'>True</emphasis>
+in the forwarded event and to set the sequence number in the event correctly.</para>
+<para>XSendExtensionEvent returns zero if the conversion-to-wire protocol
+failed, otherwise it returns nonzero.
+SendExtensionEvent
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+destination: WINDOW
+<!-- .br -->
+propagate: BOOL
+<!-- .br -->
+eventclass: LISTofEVENTCLASS
+<!-- .br -->
+event: XEVENT
+<!-- .in \-.5i -->
+<!-- .br -->
+Errors: Device, Value, Class, Window</para>
+</sect2>
+<sect2 id='getting_motion_history'><title>Getting Motion History</title>
+<!-- .XS -->
+<para>\*(SN Getting Motion History</para>
+<!-- .XE -->
+<para>GetDeviceMotionEvents
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+start, stop: TIMESTAMP or CurrentTime
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .br -->
+<!-- .in +.5i -->
+nevents_return: CARD32
+<!-- .br -->
+mode_return: {Absolute, Relative}
+<!-- .br -->
+axis_count_return: CARD8
+<!-- .br -->
+events: LISTofDEVICETIMECOORD
+<!-- .br -->
+<!-- .in \-.5i -->
+where</para>
+<!-- .br -->
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>DEVICETIMECOORD:</entry>
+ <entry align='left'><para>[data:LISTofINT32
+&nbsp;time:TIMESTAMP]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<para>Errors: Device, Match</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>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.</para>
+<para>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.</para>
+<para>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 <emphasis remap='B'>ListInputDevices</emphasis> request.</para>
+<para>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.</para>
+</sect2>
+<sect2 id='changing_the_core_devices'><title>Changing The Core Devices</title>
+<!-- .XS -->
+<para>\*(SN Changing The Core Devices</para>
+<!-- .XE -->
+<para>These requests are provided to change which physical device is used
+as the X pointer or X keyboard.</para>
+<para>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.</para>
+<para>These requests change the X keyboard or X pointer device and generate
+an <emphasis remap='B'>ChangeDeviceNotify</emphasis> event and a <emphasis remap='B'>MappingNotify</emphasis> event.
+The <emphasis remap='B'>ChangeDeviceNotify</emphasis> event is sent only to those clients that have
+expressed an interest in receiving that event via the
+<emphasis remap='B'>XSelectExtensionEvent</emphasis> 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.</para>
+<para>These requests fail and return <emphasis remap='B'>AlreadyGrabbed</emphasis> if either the specified
+device or the core device it would replace are grabbed by some other
+client. They fail and return <emphasis remap='B'>GrabFrozen</emphasis> if either device is frozen
+by the active grab of another client.</para>
+<para>These requests fail with a <emphasis remap='B'>BadDevice</emphasis> error if the specified device is
+invalid, or has not previously been opened via <emphasis remap='B'>OpenDevice</emphasis>.
+To change the X keyboard device, use the <emphasis remap='B'>ChangeKeyboardDevice</emphasis> request.
+The specified device must support input class Keys (as reported in the
+ListInputDevices request) or the request will fail with a <emphasis remap='B'>BadMatch</emphasis> 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.</para>
+<para>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 <emphasis remap='B'>FocusRec</emphasis>,
+one is added by the <emphasis remap='B'>ChangeKeyboardDevice</emphasis> request. The X keyboard is
+assumed to have a <emphasis remap='B'>KbdFeedbackClassRec</emphasis>. If the device was initialized
+without a <emphasis remap='B'>KbdFeedbackClassRec</emphasis>, one will be added by this request.
+The <emphasis remap='B'>KbdFeedbackClassRec</emphasis> will specify a null routine as the control
+procedure and the bell procedure.
+ChangeKeyboardDevice
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+Errors: Device, Match
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .br -->
+<!-- .in +.5i -->
+status: Success, AlreadyGrabbed, Frozen</para>
+<!-- .br -->
+<para>To change the X pointer device, use the <emphasis remap='B'>ChangePointerDevice</emphasis> 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.</para>
+<para>The X pointer device does not contain a <emphasis remap='B'>FocusRec</emphasis>. If the new
+pointer was initialized with a <emphasis remap='B'>FocusRec</emphasis>, it is freed by the
+<emphasis remap='B'>ChangePointerDevice</emphasis> request. The X pointer is assumed to have a
+<emphasis remap='B'>ButtonClassRec</emphasis> and a <emphasis remap='B'>PtrFeedbackClassRec</emphasis>. If the device
+was initialized without a <emphasis remap='B'>ButtonClassRec</emphasis> or a <emphasis remap='B'>PtrFeedbackClassRec</emphasis>,
+one will be added by this request. The <emphasis remap='B'>ButtonClassRec</emphasis> added will
+have no buttons, and the <emphasis remap='B'>PtrFeedbackClassRec</emphasis> will specify a null
+routine as the control procedure.</para>
+<para>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 <emphasis remap='B'>BadDevice</emphasis> error.</para>
+<para>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
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+xaxis: CARD8
+<!-- .br -->
+yaxis: CARD8
+Errors: Device, Match
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .br -->
+<!-- .in +.5i -->
+status: Success, AlreadyGrabbed, Frozen</para>
+<!-- .br -->
+</sect2>
+<sect2 id='event_synchronization_and_core_grabs'><title>Event Synchronization And Core Grabs</title>
+<!-- .XS -->
+<para>\*(SN Event Synchronization And Core Grabs</para>
+<!-- .XE -->
+<para>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.</para>
+<para>The core grab requests require a <emphasis remap='B'>pointer_mode</emphasis> and <emphasis remap='B'>keyboard_mode</emphasis>
+argument. The meaning of these modes is changed by the input extension.
+For the <emphasis remap='B'>XGrabPointer</emphasis> and <emphasis remap='B'>XGrabButton</emphasis> requests, <emphasis remap='B'>pointer_mode</emphasis>
+controls synchronization of the pointer device, and <emphasis remap='B'>keyboard_mode</emphasis>
+controls the synchronization of all other input devices.
+For the <emphasis remap='B'>XGrabKeyboard</emphasis>
+and <emphasis remap='B'>XGrabKey</emphasis> requests, <emphasis remap='B'>pointer_mode</emphasis> controls the synchronization
+of all input devices except the X keyboard, while <emphasis remap='B'>keyboard_mode</emphasis> 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.</para>
+</sect2>
+<sect2 id='extension_active_grabs'><title>Extension Active Grabs</title>
+<!-- .XS -->
+<para>\*(SN Extension Active Grabs</para>
+<!-- .XE -->
+<para>Active grabs of extension devices are supported via the <emphasis remap='B'>GrabDevice</emphasis>
+request in the same way that core devices are grabbed using the core
+GrabKeyboard request, except that a <emphasis remap='I'>Device</emphasis> is passed as
+a function parameter. A list of events that the client wishes to
+receive is also passed. The <emphasis remap='B'>UngrabDevice</emphasis> request allows a
+previous active grab for an extension device to be released.</para>
+<para>To grab an extension device, use the <emphasis remap='B'>GrabDevice</emphasis> request.
+The device must have previously been opened using the <emphasis remap='B'>OpenDevice</emphasis>
+request.
+GrabDevice
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+grab-window: WINDOW
+<!-- .br -->
+owner-events: BOOL
+<!-- .br -->
+event-list: LISTofEVENTCLASS
+<!-- .br -->
+this-device-mode: {Synchronous, Asynchronous}
+<!-- .br -->
+other-device-mode: {Synchronous, Asynchronous}
+<!-- .br -->
+time:TIMESTAMP or CurrentTime
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .br -->
+<!-- .in +.5i -->
+status: Success, AlreadyGrabbed, Frozen, InvalidTime, NotViewable
+<!-- .br -->
+Errors: Device, Window, Value</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>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.</para>
+<para>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.</para>
+<para>If owner-events is <emphasis remap='B'>False</emphasis>, 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
+<emphasis remap='B'>True</emphasis>, 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.</para>
+<para>If this-device-mode is <emphasis remap='B'>Asynchronous</emphasis>, 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 <emphasis remap='B'>Synchronous</emphasis>,
+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 <emphasis remap='B'>AllowDeviceEvents</emphasis> 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.</para>
+<para>If other-device-mode is <emphasis remap='B'>Asynchronous</emphasis>, event processing is
+unaffected by activation of the grab. If other-device-mode is
+<emphasis remap='B'>Synchronous</emphasis>, 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 <emphasis remap='B'>AllowDeviceEvents</emphasis> 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.</para>
+<para>This request generates <emphasis remap='B'>DeviceFocusIn</emphasis> and <emphasis remap='B'>DeviceFocusOut</emphasis> events.</para>
+<para>This request fails and returns:</para>
+<variablelist remap='IP'>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para><emphasis remap='B'>AlreadyGrabbed</emphasis>
+If the device is actively grabbed by some other client.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para><emphasis remap='B'>NotViewable</emphasis>
+If grab-window is not viewable.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para><emphasis remap='B'>InvalidTime</emphasis>
+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
+<emphasis remap='B'>CurrentTime</emphasis>
+is replaced by the current X server time.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para><emphasis remap='B'>Frozen</emphasis>
+If the device is frozen by an active grab of another client.</para>
+<para>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.</para>
+<para>To release a grab of an extension device, use <emphasis remap='B'>UngrabDevice</emphasis>.
+UngrabDevice
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+time: TIMESTAMP or CurrentTime
+<!-- .br -->
+Errors: Device</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This request releases the device if this client has it actively grabbed
+(from either <emphasis remap='B'>GrabDevice</emphasis> or <emphasis remap='B'>GrabDeviceKey</emphasis>) and releases
+any queued events. If any devices were frozen by the grab,
+<emphasis remap='B'>UngrabDevice</emphasis> 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.</para>
+<para>This request generates <emphasis remap='B'>DeviceFocusIn</emphasis> and <emphasis remap='B'>DeviceFocusOut</emphasis> events.</para>
+<para>An <emphasis remap='B'>UngrabDevice</emphasis> is performed automatically if the event window for an
+active device grab becomes not viewable.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect2>
+<sect2 id='passively_grabbing_a_key'><title>Passively Grabbing A Key</title>
+<!-- .XS -->
+<para>\*(SN Passively Grabbing A Key</para>
+<!-- .XE -->
+<para>Passive grabs of buttons and keys on extension devices are supported
+via the <emphasis remap='B'>GrabDeviceButton</emphasis> and <emphasis remap='B'>GrabDeviceKey</emphasis> requests.
+These passive grabs are released via the <emphasis remap='B'>UngrabDeviceKey</emphasis> and
+<emphasis remap='B'>UngrabDeviceButton</emphasis> requests.</para>
+<para>To passively grab a single key on an extension device, use <emphasis remap='B'>GrabDeviceKey</emphasis>.
+That device must have previously been opened using the <emphasis remap='B'>OpenDevice</emphasis>
+request.
+GrabDeviceKey</para>
+<!-- .br -->
+<!-- .in .5i -->
+<para>device: DEVICE
+<!-- .br -->
+keycode: KEYCODE or AnyKey
+<!-- .br -->
+modifiers: SETofKEYMASK or AnyModifier
+<!-- .br -->
+modifier-device: DEVICE or NULL
+<!-- .br -->
+grab-window: WINDOW
+<!-- .br -->
+owner-events: BOOL
+<!-- .br -->
+event-list: LISTofEVENTCLASS
+<!-- .br -->
+this-device-mode: {Synchronous, Asynchronous}
+<!-- .br -->
+other-device-mode: {Synchronous, Asynchronous}
+<!-- .br -->
+Errors: Device, Match, Access, Window, Value</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This request is analogous to the core <emphasis remap='B'>GrabKey</emphasis> request. It establishes a
+passive grab on a device. Consequently, In the future:</para>
+<variablelist remap='IP'>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>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),</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>AND no other modifier keys logically are down,</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>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,</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>AND a passive grab on the same device and key combination does not exist on any
+ancestor of the grab window,</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>THEN the device is actively grabbed, as for <emphasis remap='B'>GrabDevice</emphasis>,
+the last-device-grab time is set to the time at which the key was pressed
+(as transmitted in the <emphasis remap='B'>DeviceKeyPress</emphasis> event), and the
+<emphasis remap='B'>DeviceKeyPress</emphasis> event is reported.</para>
+<para>The interpretation of the remaining arguments is as for <emphasis remap='B'>GrabDevice</emphasis>.
+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).</para>
+<para>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.</para>
+<para>A modifier of <emphasis remap='B'>AnyModifier</emphasis> 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 <emphasis remap='B'>AnyKey</emphasis> 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 <emphasis remap='B'>ListInputDevices</emphasis>
+request. If it is not within that range, <emphasis remap='B'>GrabDeviceKey</emphasis> generates a
+<emphasis remap='B'>Value</emphasis> error.</para>
+<para><emphasis remap='B'>NULL</emphasis> may be passed for the modifier_device. If the modifier_device is
+<emphasis remap='B'>NULL</emphasis>, the core X keyboard is used as the modifier_device.</para>
+<para>An <emphasis remap='B'>Access</emphasis> error is generated if some other client has issued a
+<emphasis remap='B'>GrabDeviceKey</emphasis> with the same device and key combination on the
+same window. When using <emphasis remap='B'>AnyModifier</emphasis> or <emphasis remap='B'>AnyKey</emphasis>,
+the request fails completely and the X server generates a <emphasis remap='B'>Access</emphasis>
+error and no grabs are established if there is a conflicting grab for any
+combination.</para>
+<para>This request cannot be used to grab a key on the X keyboard device.
+The core <emphasis remap='B'>GrabKey</emphasis> request should be used for that purpose.</para>
+<para>To release a passive grab of a single key on an extension device,
+use <emphasis remap='B'>UngrabDeviceKey</emphasis>.
+UngrabDeviceKey</para>
+<!-- .in .5i -->
+<para>device: DEVICE
+<!-- .br -->
+keycode: KEYCODE or AnyKey
+<!-- .br -->
+modifiers: SETofKEYMASK or AnyModifier
+<!-- .br -->
+modifier-device: DEVICE or NULL
+<!-- .br -->
+grab-window: WINDOW
+<!-- .br -->
+Errors: Device, Match, Window, Value, Alloc</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This request is analogous to the core <emphasis remap='B'>UngrabKey</emphasis> request. It releases
+the key combination on the specified window if it was grabbed by this
+client. A modifier of <emphasis remap='B'>AnyModifier</emphasis> is equivalent to issuing the
+request for all possible modifier combinations (including the combination
+of no modifiers). A key of <emphasis remap='B'>AnyKey</emphasis> is equivalent to issuing the
+request for all possible keycodes. This request has no effect on an
+active grab.</para>
+<para><emphasis remap='B'>NULL</emphasis> may be passed for the modifier_device. If the modifier_device is
+<emphasis remap='B'>NULL</emphasis>, the core X keyboard is used as the modifier_device.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect2>
+<sect2 id='passively_grabbing_a_button'><title>Passively Grabbing A Button</title>
+<!-- .XS -->
+<para>\*(SN Passively Grabbing A Button</para>
+<!-- .XE -->
+<para>To establish a passive grab for a single button on an extension device,
+use <emphasis remap='B'>GrabDeviceButton</emphasis>.
+GrabDeviceButton</para>
+<!-- .in .5i -->
+<para>device: DEVICE
+<!-- .br -->
+button: BUTTON or AnyButton
+<!-- .br -->
+modifiers: SETofKEYMASK or AnyModifier
+<!-- .br -->
+modifier-device: DEVICE or NULL
+<!-- .br -->
+grab-window: WINDOW
+<!-- .br -->
+owner-events: BOOL
+<!-- .br -->
+event-list: LISTofEVENTCLASS
+<!-- .br -->
+this-device-mode: {Synchronous, Asynchronous}
+<!-- .br -->
+other-device-mode: {Synchronous, Asynchronous}
+<!-- .br -->
+Errors: Device, Match, Window, Access, Value</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This request is analogous to the core <emphasis remap='B'>GrabButton</emphasis> 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
+<emphasis remap='B'>OpenDevice</emphasis> request.</para>
+<para>The <emphasis remap='B'>GrabDeviceButton</emphasis> request establishes a passive grab on a device.
+Consequently, in the future,</para>
+<variablelist remap='IP'>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>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),</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>AND the grab window contains the device,</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>AND a passive grab on the same device and button/ key combination does not
+exist on any ancestor of the grab window,</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>THEN the device is actively grabbed, as for <emphasis remap='B'>GrabDevice</emphasis>,
+the last-grab time is set to the time at which the button was pressed
+(as transmitted in the <emphasis remap='B'>DeviceButtonPress</emphasis> event), and the
+<emphasis remap='B'>DeviceButtonPress</emphasis> event is reported.</para>
+<para>The interpretation of the remaining arguments is as for
+<emphasis remap='B'>GrabDevice</emphasis>.
+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).</para>
+<para>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.</para>
+<para>A modifier of <emphasis remap='B'>AnyModifier</emphasis> 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 <emphasis remap='B'>AnyButton</emphasis> is equivalent to issuing the request
+for all possible buttons. It is not required that the
+specified button be assigned to a physical button.</para>
+<para><emphasis remap='B'>NULL</emphasis> may be passed for the modifier_device. If the modifier_device is
+<emphasis remap='B'>NULL</emphasis>, the core X keyboard is used as the modifier_device.</para>
+<para>An <emphasis remap='B'>Access</emphasis> error is generated if some other client has issued a
+<emphasis remap='B'>GrabDeviceButton</emphasis> with the same device and button combination on the
+same window. When using <emphasis remap='B'>AnyModifier</emphasis> or <emphasis remap='B'>AnyButton</emphasis>, the request
+fails completely and the X server generates a <emphasis remap='B'>Access</emphasis>
+error and no grabs are established if there is a conflicting grab for any
+combination. The request has no effect on an active grab.</para>
+<para>This request cannot be used to grab a button on the X pointer
+device. The core <emphasis remap='B'>GrabButton</emphasis> request should be used for that
+purpose.</para>
+<para>To release a passive grab of a button on an extension device, use
+<emphasis remap='B'>UngrabDeviceButton</emphasis>.
+UngrabDeviceButton</para>
+<!-- .br -->
+<!-- .in .5i -->
+<para>device: DEVICE
+<!-- .br -->
+button: BUTTON or AnyButton
+<!-- .br -->
+modifiers: SETofKEYMASK or AnyModifier
+<!-- .br -->
+modifier-device: DEVICE or NULL
+<!-- .br -->
+grab-window: WINDOW
+<!-- .br -->
+<!-- .br -->
+Errors: Device, Match, Window, Value, Alloc</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>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 <emphasis remap='B'>AnyModifier</emphasis> is equivalent to issuing the
+request for all possible modifier combinations (including the combination
+of no modifiers). A button of <emphasis remap='B'>AnyButton</emphasis> 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
+<emphasis remap='B'>OpenDevice</emphasis> request otherwise a <emphasis remap='B'>Device</emphasis> error will be
+generated.</para>
+<para><emphasis remap='B'>NULL</emphasis> may be passed for the modifier_device. If the modifier_device is
+<emphasis remap='B'>NULL</emphasis>, the core X keyboard is used as the modifier_device.</para>
+<para>This request cannot be used to ungrab a button on the X pointer
+device. The core <emphasis remap='B'>UngrabButton</emphasis> request should be used for that
+purpose.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect2>
+<sect2 id='thawing_a_device'><title>Thawing A Device</title>
+<!-- .XS -->
+<para>\*(SN Thawing A Device</para>
+<!-- .XE -->
+<para>To allow further events to be processed when a device has been frozen,
+use <emphasis remap='B'>AllowDeviceEvents</emphasis>.
+AllowDeviceEvents
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+event-mode: {AsyncThisDevice, SyncThisDevice, AsyncOtherDevices,
+ReplayThisdevice, AsyncAll, or SyncAll}
+<!-- .br -->
+time:TIMESTAMP or CurrentTime
+<!-- .br -->
+Errors: Device, Value</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>The <emphasis remap='B'>AllowDeviceEvents</emphasis> 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.</para>
+<para>The following describes the processing that occurs depending on what constant
+you pass to the event-mode argument:</para>
+<variablelist remap='IP'>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>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.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>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.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>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.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>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 &ldquo;thaws&rdquo; 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.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>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).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>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.</para>
+<para>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.</para>
+<para>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.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect2>
+<sect2 id='controlling_device_focus'><title>Controlling Device Focus</title>
+<!-- .XS -->
+<para>\*(SN Controlling Device Focus</para>
+<!-- .XE -->
+<para>The current focus window for an extension input device can be
+determined using the <emphasis remap='B'>GetDeviceFocus</emphasis> request.
+Extension devices are focused using the <emphasis remap='B'>SetDeviceFocus</emphasis>
+request in the same way that the keyboard is focused using
+the <emphasis remap='B'>SetInputFocus</emphasis> request, except that a device is specified as
+part of the request. One additional focus state, <emphasis remap='B'>FollowKeyboard</emphasis>,
+is provided for extension devices.</para>
+<para>To get the current focus state, revert state, and focus time of an extension device,
+use <emphasis remap='B'>GetDeviceFocus</emphasis>.
+GetDeviceFocus</para>
+<!-- .br -->
+<!-- .in .5i -->
+<para>device: DEVICE
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+focus: WINDOW, PointerRoot, FollowKeyboard, or None
+<!-- .br -->
+revert-to: Parent, PointerRoot, FollowKeyboard, or None
+<!-- .br -->
+focus-time: TIMESTAMP
+<!-- .br -->
+Errors: Device, Match</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This request returns the current focus state, revert-to state,
+and last-focus-time of an extension device.</para>
+<para>To set the focus of an extension device, use <emphasis remap='B'>SetDeviceFocus</emphasis>.
+SetDeviceFocus
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+focus: WINDOW, PointerRoot, FollowKeyboard, or None
+<!-- .br -->
+revert-to: Parent, PointerRoot, FollowKeyboard, or None
+<!-- .br -->
+focus-time: TIMESTAMP
+<!-- .br -->
+Errors: Device, Window, Value, Match</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>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.</para>
+<para>The action taken by the server when this request is requested depends
+on the value of the focus argument:</para>
+<variablelist remap='IP'>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>If the focus argument is <emphasis remap='B'>None</emphasis>, 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.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>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.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>If you assign <emphasis remap='B'>PointerRoot</emphasis> 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.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>If you assign <emphasis remap='B'>FollowKeyboard</emphasis> 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.</para>
+<para>The specified focus window must be viewable at the time of the request
+(else a <emphasis remap='B'>Match</emphasis> error). If the focus window later becomes not viewable,
+the X server evaluates the revert-to argument
+to determine the new focus window.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>If you assign <emphasis remap='B'>RevertToParent</emphasis>
+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 <emphasis remap='B'>RevertToNone</emphasis>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&bull;</term>
+ <listitem>
+<para>If you assign <emphasis remap='B'>RevertToPointerRoot</emphasis>, <emphasis remap='B'>RevertToFollowKeyboard</emphasis>, or <emphasis remap='B'>RevertToNone</emphasis>
+to the revert-to argument, the focus reverts to that value.</para>
+<para>When the focus reverts,
+the X server generates <emphasis remap='B'>DeviceFocusIn</emphasis>
+and <emphasis remap='B'>DeviceFocusOut</emphasis>
+events, but the last-focus-change time is not affected.</para>
+<para>This request causes the X server to generate <emphasis remap='B'>DeviceFocusIn</emphasis> and
+<emphasis remap='B'>DeviceFocusOut</emphasis> events.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect2>
+<sect2 id='controlling_device_feedback'><title>Controlling Device Feedback</title>
+<!-- .XS -->
+<para>\*(SN Controlling Device Feedback</para>
+<!-- .XE -->
+<para>To get the settings of feedbacks on an extension device, use
+<emphasis remap='B'>GetFeedbackControl</emphasis>. This request provides functionality equivalent to
+the core <emphasis remap='B'>GetKeyboardControl</emphasis> and <emphasis remap='B'>GetPointerControl</emphasis> functions. It
+also provides a way to control displays associated with an input device that
+are capable of displaying an integer or string.
+GetFeedbackControl
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+num_feedbacks_return: CARD16
+<!-- .br -->
+return_value: LISTofFEEDBACKSTATE
+<!-- .br -->
+where</para>
+<!-- .br -->
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>FEEDBACKSTATE:</entry>
+ <entry align='left'>{KbdFeedbackState, PtrFeedbackState, IntegerFeedbackState, StringFeedbackState, BellFeedbackState, LedFeedbackState}</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-1.0i -->
+<para>Feedbacks are reported by class. Those
+feedbacks that are reported for the core keyboard device are in class
+<emphasis remap='B'>KbdFeedback</emphasis>, and are returned in the
+<emphasis remap='B'>KbdFeedbackState</emphasis> structure. The members of that structure are as follows:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>CLASS Kbd:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;key_click_percent: CARD8
+<!-- .br -->
+&nbsp;bell_percent: CARD8
+<!-- .br -->
+&nbsp;bell_pitch: CARD16
+<!-- .br -->
+&nbsp;bell_duration: CARD16
+<!-- .br -->
+&nbsp;led_value: BITMASK
+<!-- .br -->
+&nbsp;global_auto_repeat: {AutoRepeatModeOn, AutoRepeatModeOff}
+<!-- .br -->
+&nbsp;auto_repeats: LISTofCARD8]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<para>Those feedbacks that are equivalent to those reported for the core pointer
+are in feedback class <emphasis remap='B'>PtrFeedback</emphasis> and are reported in the
+<emphasis remap='B'>PtrFeedbackState</emphasis> structure. The members of that structure are:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>CLASS Ptr:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;accelNumerator: CARD16
+<!-- .br -->
+&nbsp;accelDenominator: CARD16
+<!-- .br -->
+&nbsp;threshold: CARD16]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<para>Some input devices provide a means of displaying an integer. Those devices
+will support feedback class <emphasis remap='B'>IntegerFeedback</emphasis>, which is reported in the
+<emphasis remap='B'>IntegerFeedbackState</emphasis> structure. The members of that structure are:</para>
+<!-- .br -->
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>CLASS Integer:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;resolution: CARD32
+<!-- .br -->
+&nbsp;min-val: INT32
+<!-- .br -->
+&nbsp;max-val: INT32]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<!-- .br -->
+<para>Some input devices provide a means of displaying a string. Those devices
+will support feedback class <emphasis remap='B'>StringFeedback</emphasis>, which is reported in the
+<emphasis remap='B'>StringFeedbackState</emphasis> structure. The members of that structure are:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>CLASS String:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;max_symbols: CARD16
+<!-- .br -->
+&nbsp;num_keysyms_supported: CARD16
+<!-- .br -->
+&nbsp;keysyms_supported: LISTofKEYSYM]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<!-- .br -->
+<para>Some input devices contain a bell. Those devices
+will support feedback class <emphasis remap='B'>BellFeedback</emphasis>, which is reported in the
+<emphasis remap='B'>BellFeedbackState</emphasis> structure. The members of that structure are:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>CLASS Bell:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;percent: CARD8
+<!-- .br -->
+&nbsp;pitch: CARD16
+<!-- .br -->
+&nbsp;duration: CARD16]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<!-- .br -->
+<para>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 <emphasis remap='B'>Value</emphasis> error.</para>
+<para>The pitch sets the pitch (specified in Hz) of the bell, if possible.
+Setting to -1 restores the default. Other negative values generate a
+<emphasis remap='B'>Value</emphasis> error.</para>
+<para>The duration sets the duration (specified in milliseconds) of the
+bell, if possible. Setting to -1 restores the default.
+Other negative values generate a <emphasis remap='B'>Value</emphasis> error.</para>
+<para>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 <emphasis remap='B'>Led</emphasis>, which is reported in the
+<emphasis remap='B'>LedFeedbackState</emphasis> structure. The members of that structure are:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>CLASS Led:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;led_mask: BITMASK
+<!-- .br -->
+&nbsp;led_value: BITMASK]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<!-- .br -->
+<para>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.</para>
+<para>This function will fail with a <emphasis remap='B'>BadMatch</emphasis> error if the device specified
+in the request does not support feedbacks.</para>
+<para>Errors: Device, Match</para>
+<para>To change the settings of a feedback on an extension device, use
+<emphasis remap='B'>ChangeFeedbackControl</emphasis>.
+ChangeFeedbackControl
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+feedbackid: CARD8
+<!-- .br -->
+value-mask: BITMASK
+<!-- .br -->
+value: FEEDBACKCONTROL
+<!-- .br -->
+Errors: Device, Match, Value</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>FEEDBACKCONTROL:</entry>
+ <entry align='left'><para>{KBDFEEDBACKCONTROL, PTRFEEDBACKCONTROL, INTEGERFEEDBACKCONTROL,
+STRINGFEEDBACKCONTROL, BELLFEEDBACKCONTROL, LEDFEEDBACKCONTROL}</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .br -->
+<para>Feedback controls are grouped by class. Those feedbacks that are
+equivalent to those supported by the core keyboard are controlled
+by feedback class <emphasis remap='B'>KbdFeedbackClass</emphasis> using the <emphasis remap='B'>KbdFeedbackControl</emphasis>
+structure. The members of that structure are:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>KBDFEEDBACKCTL:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;key_click_percent: INT8
+<!-- .br -->
+&nbsp;bell_percent: INT8
+<!-- .br -->
+&nbsp;bell_pitch: INT16
+<!-- .br -->
+&nbsp;bell_duration: INT16
+<!-- .br -->
+&nbsp;led_mask: INT32
+<!-- .br -->
+&nbsp;led_value: INT32
+<!-- .br -->
+&nbsp;key: KEYCODE
+<!-- .br -->
+&nbsp;auto_repeat_mode: {AutoRepeatModeOn,
+<!-- .br -->
+&nbsp;&nbsp;AutoRepeatModeOff, AutoRepeatModeDefault}]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<para>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 <emphasis remap='B'>Value</emphasis> error.</para>
+<para>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 <emphasis remap='B'>Match</emphasis>
+error if a key is specified without an auto_repeat_mode.</para>
+<para>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.</para>
+<para>Those feedback controls equivalent to those of the core pointer are
+controlled by feedback class <emphasis remap='B'>PtrFeedbackClass</emphasis> using the
+<emphasis remap='B'>PtrFeedbackControl</emphasis>
+structure. The members of that structure are as follows:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>PTRFEEDBACKCTL:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;accelNumerator: INT16
+<!-- .br -->
+&nbsp;accelDenominator: INT16
+<!-- .br -->
+&nbsp;threshold: INT16]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<para>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 <emphasis remap='B'>Value</emphasis> error, as does a zero value
+for the accel-denominator argument.</para>
+<para>Some devices are capable of displaying an integer. This is done using
+feedback class <emphasis remap='B'>IntegerFeedbackClass</emphasis> using the <emphasis remap='B'>IntegerFeedbackControl</emphasis>
+structure. The members of that structure are as follows:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>INTEGERCTL:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;int_to_display: INT32]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<para>Some devices are capable of displaying an string. This is done using
+feedback class <emphasis remap='B'>StringFeedbackClass</emphasis> using the <emphasis remap='B'>StringFeedbackCtl</emphasis>
+structure. The members of that structure are as follows:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>STRINGCTL:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;syms_to_display: LISTofKEYSYMS]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<para>Some devices contain a bell. This is done using
+feedback class <emphasis remap='B'>BellFeedbackClass</emphasis> using the <emphasis remap='B'>BellFeedbackControl</emphasis>
+structure. The members of that structure are as follows:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>BELLCTL:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;percent: INT8
+<!-- .br -->
+&nbsp;pitch: INT16
+<!-- .br -->
+&nbsp;duration: INT16]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<para>Some devices contain leds. These can be turned on and off using
+the <emphasis remap='B'>LedFeedbackControl</emphasis>
+structure. The members of that structure are as follows:</para>
+<!-- .in +.5i -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>LEDCTL:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;length: CARD16
+<!-- .br -->
+&nbsp;feedback id: CARD8
+<!-- .br -->
+&nbsp;led_mask: BITMASK
+<!-- .br -->
+&nbsp;led_value: BITMASK]</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .in \-.5i -->
+<para>Errors: Device, Match, Value</para>
+</sect2>
+<sect2 id='ringing_a_bell_on_an_input_device'><title>Ringing a Bell on an Input Device</title>
+<!-- .XS -->
+<para>\*(SN Ringing a Bell on an Input Device</para>
+<!-- .XE -->
+<para>To ring a bell on an extension input device, use <emphasis remap='B'>DeviceBell</emphasis>.
+DeviceBell</para>
+<!-- .br -->
+<!-- .in .5i -->
+<para>device: DEVICE
+<!-- .br -->
+feedbackclass: CARD8
+<!-- .br -->
+feedbackid: CARD8
+<!-- .br -->
+percent: INT8
+<!-- .br -->
+Errors: Device, Value</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This request is analogous to the core <emphasis remap='B'>Bell</emphasis> 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 <emphasis remap='B'>Value</emphasis> error results.
+The volume at which the bell rings when the percent argument is nonnegative is:</para>
+<literallayout remap='DS'>
+ base - [(base * percent) / 100] + percent
+</literallayout> <!-- remap='DE' -->
+<para>The volume at which the bell rings
+when the percent argument is negative is:</para>
+<literallayout remap='DS'>
+ base + [(base * percent) / 100]
+</literallayout> <!-- remap='DE' -->
+<para>To change the base volume of the bell, use <emphasis remap='B'>ChangeFeedbackControl</emphasis> request.</para>
+</sect2>
+<sect2 id='controlling_device_encoding'><title>Controlling Device Encoding</title>
+<!-- .XS -->
+<para>\*(SN Controlling Device Encoding</para>
+<!-- .XE -->
+<para>To get the keyboard mapping of an extension device that has keys, use
+<emphasis remap='B'>GetDeviceKeyMapping</emphasis>.
+GetDeviceKeyMapping</para>
+<!-- .br -->
+<!-- .in .5i -->
+<para>device: DEVICE
+<!-- .br -->
+first-keycode: KEYCODE
+<!-- .br -->
+count: CARD8
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+keysyms-per-keycode: CARD8
+<!-- .br -->
+keysyms: LISTofKEYSYM
+<!-- .br -->
+Errors: Device, Match, Value</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>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 <emphasis remap='B'>Value</emphasis> error),
+and</para>
+<literallayout remap='DS'>
+first-keycode + count - 1
+</literallayout> <!-- remap='DE' -->
+<para>must be less than or equal to max-keycode as returned in the connection setup
+(else a <emphasis remap='B'>Value</emphasis> error).
+The number of elements in the keysyms list is</para>
+<literallayout remap='DS'>
+count * keysyms-per-keycode
+</literallayout> <!-- remap='DE' -->
+<para>and KEYSYM number N (counting from zero) for keycode K has an index
+(counting from zero) of</para>
+<literallayout remap='DS'>
+(K - first-keycode) * keysyms-per-keycode + N
+</literallayout> <!-- remap='DE' -->
+<para>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
+<emphasis remap='B'>NoSymbol</emphasis>
+is used to fill in unused elements for individual keycodes.</para>
+<para>If the specified device has not first been opened by this client via
+<emphasis remap='B'>OpenDevice</emphasis>, or if that device does not support input class Keys,
+this request will fail with a <emphasis remap='B'>Device</emphasis> error.</para>
+<para>To change the keyboard mapping of an extension device that has keys, use
+<emphasis remap='B'>ChangeDeviceKeyMapping</emphasis>.
+ChangeDeviceKeyMapping
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+first-keycode: KEYCODE
+<!-- .br -->
+keysyms-per-keycode: CARD8
+<!-- .br -->
+keysyms: LISTofKEYSYM
+<!-- .br -->
+num_codes: CARD8
+<!-- .br -->
+Errors: Device, Match, Value, Alloc</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This request is analogous to the core <emphasis remap='B'>ChangeKeyMapping</emphasis> 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
+<emphasis remap='B'>OpenDevice</emphasis>, or if that device does not support input class Keys,
+this request will fail with a <emphasis remap='B'>Device</emphasis> error.</para>
+<para>The number of elements in the keysyms list must be a multiple of
+keysyms_per_keycode. Otherwise, <emphasis remap='B'>ChangeDeviceKeyMapping</emphasis> generates
+a <emphasis remap='B'>Length</emphasis> error. The specified first_keycode must be greater
+than or equal to the min_keycode value returned by the <emphasis remap='B'>ListInputDevices</emphasis>
+request, or this request will fail with a <emphasis remap='B'>Value</emphasis> error. In addition,
+if the following expression is not less than the max_keycode value returned by
+the <emphasis remap='B'>ListInputDevices</emphasis> request, the request will fail with a <emphasis remap='B'>Value</emphasis>
+error:</para>
+<literallayout remap='DS'>
+ first_keycode + (num_codes / keysyms_per_keycode) - 1
+</literallayout> <!-- remap='DE' -->
+<para>To obtain the keycodes that are used as modifiers on an
+extension device that has keys, use <emphasis remap='B'>GetDeviceModifierMapping</emphasis>.
+GetDeviceModifierMapping
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .br -->
+<!-- .in +.5i -->
+keycodes-per-modifier: CARD8
+<!-- .br -->
+keycodes: LISTofKEYCODE
+<!-- .br -->
+Errors: Device, Match</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This request is analogous to the core <emphasis remap='B'>GetModifierMapping</emphasis> 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 <emphasis remap='B'>Shift</emphasis>, <emphasis remap='B'>Lock</emphasis>, <emphasis remap='B'>Control</emphasis>, <emphasis remap='B'>Mod1</emphasis>, <emphasis remap='B'>Mod2</emphasis>,
+<emphasis remap='B'>Mod3</emphasis>, <emphasis remap='B'>Mod4</emphasis>, and <emphasis remap='B'>Mod5</emphasis>. 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.</para>
+<para>To set which keycodes that are to be used as modifiers for an extension
+device, use <emphasis remap='B'>SetDeviceModifierMapping</emphasis>.
+SetDeviceModifierMapping</para>
+<!-- .br -->
+<!-- .in .5i -->
+<para>device: DEVICE
+<!-- .br -->
+keycodes-per-modifier: CARD8
+<!-- .br -->
+keycodes: LISTofKEYCODE
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .br -->
+<!-- .in +.5i -->
+status: {Success, Busy, Failed}
+<!-- .br -->
+Errors: Device, Match, Value, Alloc</para>
+<!-- .in \-.5i -->
+<para>This request is analogous to the core <emphasis remap='B'>SetModifierMapping</emphasis> 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 <emphasis remap='B'>Length</emphasis> 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 <emphasis remap='B'>Shift</emphasis>, <emphasis remap='B'>Lock</emphasis>, <emphasis remap='B'>Control</emphasis>, <emphasis remap='B'>Mod1</emphasis>, <emphasis remap='B'>Mod2</emphasis>,
+<emphasis remap='B'>Mod3</emphasis>, <emphasis remap='B'>Mod4</emphasis>, and <emphasis remap='B'>Mod5</emphasis>. 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 <emphasis remap='B'>ListInputDevices</emphasis> request (else a <emphasis remap='B'>Value</emphasis> 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.</para>
+<para>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 <emphasis remap='B'>Failed</emphasis>
+if some such restriction is violated, and none of the modifiers are changed.</para>
+<para>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 <emphasis remap='B'>Busy</emphasis>,
+and none of the modifiers are changed.</para>
+<para>This request generates a <emphasis remap='P->B'>DeviceMappingNotify</emphasis> event on a
+<emphasis remap='B'>Success</emphasis> status. The <emphasis remap='P->B'>DeviceMappingNotify</emphasis> event will be sent only
+to those clients that have expressed an interest in receiving that event
+via the <emphasis remap='B'>XSelectExtensionEvent</emphasis> request.</para>
+<para>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
+<emphasis remap='B'>MappingFailed</emphasis> , 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 <emphasis remap='B'>MappingBusy</emphasis>,
+and none of the modifiers are changed.</para>
+</sect2>
+<sect2 id='controlling_button_mapping'><title>Controlling Button Mapping</title>
+<!-- .XS -->
+<para>\*(SN Controlling Button Mapping</para>
+<!-- .XE -->
+<para>These requests are analogous to the core <emphasis remap='B'>GetPointerMapping</emphasis>
+and <emphasis remap='B'>ChangePointerMapping</emphasis> requests. They allow a client to
+determine the current mapping of buttons on an extension device,
+and to change that mapping.</para>
+<para>To get the current button mapping for an extension device, use
+<emphasis remap='B'>GetDeviceButtonMapping</emphasis>.
+GetDeviceButtonMapping
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+nmap: CARD8
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+map_return: LISTofCARD8
+<!-- .br -->
+Errors: Device, Match</para>
+<!-- .in \-.5i -->
+<!-- .br -->
+<para>The <emphasis remap='B'>GetDeviceButtonMapping</emphasis> 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.</para>
+<para><emphasis remap='B'>nmap</emphasis> indicates the number of elements in the <emphasis remap='B'>map_return</emphasis>
+array. Only the first nmap entries will be copied by the library
+into the map_return array.</para>
+<para>To set the button mapping for an extension device, use
+<emphasis remap='B'>SetDeviceButtonMapping</emphasis>.
+SetDeviceButtonMapping
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+map: LISTofCARD8
+<!-- .br -->
+nmap: CARD8
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+status: CARD8
+<!-- .br -->
+Errors: Device, Match, Value</para>
+<!-- .in \-.5i -->
+<!-- .br -->
+<para>The <emphasis remap='B'>SetDeviceButtonMapping</emphasis> function sets the mapping of the specified
+device and causes the X server to generate a <emphasis remap='B'>DeviceMappingNotify</emphasis>
+event on a status of <emphasis remap='B'>MappingSuccess</emphasis>. Elements of the list are
+indexed starting from one. The length of the list,
+specified in <emphasis remap='B'>nmap</emphasis>,
+must be the same as
+<emphasis remap='B'>GetDeviceButtonMapping</emphasis> would return. Otherwise,
+<emphasis remap='B'>SetDeviceButtonMapping</emphasis> generates a <emphasis remap='B'>Value</emphasis> error. A zero element
+disables a buttons, and elements are not restricted in value by the
+number of physical buttons. However, no two elements can have the
+same nonzero value. Otherwise, this function generates a
+<emphasis remap='B'>Value</emphasis> error. If any of the buttons to be altered are in the
+down state, the status reply is <emphasis remap='B'>MappingBusy</emphasis> and the mapping is
+not changed.</para>
+</sect2>
+<sect2 id='obtaining_the_state_of_a_device'><title>Obtaining The State Of A Device</title>
+<!-- .XS -->
+<para>\*(SN Obtaining The State Of A Device</para>
+<!-- .XE -->
+<para>To obtain vectors that describe the state of the keys, buttons and valuators
+of an extension device, use <emphasis remap='B'>QueryDeviceState</emphasis>.
+QueryDeviceState
+<!-- .br -->
+<!-- .in .5i -->
+device: DEVICE
+<!-- .br -->
+<!-- .in \-.5i -->
+=&gt;
+<!-- .in +.5i -->
+device-id: CARD8
+<!-- .br -->
+data: LISTofINPUTCLASS
+<!-- .br -->
+<!-- .in \-.5i -->
+where</para>
+<!-- .in +.5i -->
+<!-- .br -->
+<informaltable pgwide='0' frame='none'>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>INPUTCLASS:</entry>
+ <entry align='left'>{VALUATOR, BUTTON, KEY}</entry>
+ </row>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>CLASS VALUATOR:</entry>
+ <entry align='left'><para>[class: CARD8
+<!-- .br -->
+&nbsp;num_valuators: CARD8
+<!-- .br -->
+mode: CARD8
+<!-- .in +.5i -->
+<!-- .br -->
+#x01 device mode
+<!-- .in +.5i -->
+<!-- .br -->
+(0 = Relative, 1 = Absolute)
+<!-- .br -->
+<!-- .in \-.5i -->
+#x02 proximity state
+<!-- .in +.5i -->
+<!-- .br -->
+(0 = InProximity, 1 = OutOfProximity)
+<!-- .in \-1.0i -->
+<!-- .br -->
+&nbsp;valuators: LISTofINT32]</para></entry>
+ </row>
+ <row>
+ <entry align='left'>.br</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>CLASS BUTTON:</entry>
+ <entry align='left'>[class: CARD8
+<!-- .br -->
+&nbsp;num_buttons: CARD8
+<!-- .br -->
+&nbsp;buttons: LISTofCARD8]</entry>
+ </row>
+ <row>
+ <entry align='left'>.br</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>.sp</entry>
+ <entry align='left'></entry>
+ </row>
+ <row>
+ <entry align='left'>CLASS KEY:</entry>
+ <entry align='left'>[class: CARD8
+<!-- .br -->
+&nbsp;num_keys: CARD8
+<!-- .br -->
+&nbsp;keys: LISTofCARD8]</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<!-- .br -->
+<para>Errors: Device</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>The <emphasis remap='B'>QueryDeviceState</emphasis> request returns the current logical state of the
+buttons, keys, and valuators on the specified input device.
+The <emphasis remap='I'>buttons</emphasis> and <emphasis remap='I'>keys</emphasis> 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.</para>
+<para>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.</para>
+<para>If the device reports proximity information, a bit in the mode field indicates
+whether the device is InProximity or OutOfProximity.</para>
+</sect2>
+</sect1>
+<sect1 id='events'><title>Events</title>
+<!-- .XS -->
+<para>\*(SN Events</para>
+<!-- .XE -->
+<para>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.</para>
+<sect2 id='button_key_and_motion_events'><title>Button, Key, and Motion Events</title>
+<!-- .XS -->
+<para>\*(SN Button, Key, and Motion Events</para>
+<!-- .XE -->
+<para>DeviceKeyPress
+<!-- .br -->
+DeviceKeyRelease
+<!-- .br -->
+DeviceButtonPress,
+<!-- .br -->
+DeviceButtonRelease
+<!-- .br -->
+DeviceMotionNotify</para>
+<!-- .in .5i -->
+<para>device: CARD8
+<!-- .br -->
+root, event: WINDOW
+<!-- .br -->
+child: Window or None
+<!-- .br -->
+same-screen: BOOL
+<!-- .br -->
+root-x, root-y, event-x, event-y: INT16
+<!-- .br -->
+detail: &lt;see below&gt;
+<!-- .br -->
+state: SETofKEYBUTMASK
+<!-- .br -->
+time: TIMESTAMP</para>
+<!-- .in \-.5i -->
+<para>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 <emphasis remap='B'>DeviceKeyPress</emphasis>
+and <emphasis remap='B'>DeviceKeyRelease</emphasis> are generated for all keys, even those mapped to modifier bits.
+The &ldquo;source&rdquo; 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 &ldquo;event&rdquo; window.</para>
+<para>The root is the root window of the &ldquo;source&rdquo; 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 &ldquo;event&rdquo; 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 detail component type varies with the event type:</para>
+<informaltable pgwide='0' frame='all'>
+ <tgroup cols='2' align='center' colsep='1' rowsep='1'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry align='left'>Event</entry>
+ <entry align='left'>Component</entry>
+ </row>
+ <row>
+ <entry align='left'><para>DeviceKeyPress,
+<!-- .br -->
+DeviceKeyRelease</para></entry>
+ <entry align='left'>KEYCODE</entry>
+ </row>
+ <row>
+ <entry align='left'>DeviceButtonPress,
+<!-- .br -->
+DeviceButtonRelease</entry>
+ <entry align='left'>BUTTON</entry>
+ </row>
+ <row>
+ <entry align='left'>DeviceMotionNotify</entry>
+ <entry align='left'>{ Normal , Hint }</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<para>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 <emphasis remap='B'>DeviceMotionHint</emphasis> is selected, the server is free to send
+only one <emphasis remap='B'>DeviceMotionNotify</emphasis> event (with detail <emphasis remap='B'>Hint</emphasis>) 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
+<emphasis remap='B'>QueryDeviceState</emphasis> or <emphasis remap='B'>GetDeviceMotionEvents</emphasis> request.</para>
+</sect2>
+<sect2 id='devicevaluator_event'><title>DeviceValuator Event</title>
+<!-- .XS -->
+<para>\*(SN DeviceValuator Event</para>
+<!-- .XE -->
+<para>DeviceValuator</para>
+<!-- .in .5i -->
+<para>device: CARD8
+<!-- .br -->
+device_state: SETofKEYBUTMASK
+<!-- .br -->
+num_valuators: CARD8
+<!-- .br -->
+first_valuator: CARD8
+<!-- .br -->
+valuators: LISTofINT32</para>
+<!-- .in \-.5i -->
+<para>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.</para>
+<para>The device_state component gives the state of the
+buttons and modifiers on the device generating the event.</para>
+<para>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.</para>
+<para>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.</para>
+</sect2>
+<sect2 id='device_focus_events'><title>Device Focus Events</title>
+<!-- .XS -->
+<para>\*(SN Device Focus Events</para>
+<!-- .XE -->
+<para>DeviceFocusIn
+<!-- .br -->
+DeviceFocusOut</para>
+<!-- .in .5i -->
+<para>device: CARD8
+<!-- .br -->
+time: TIMESTAMP
+<!-- .br -->
+event: WINDOW
+<!-- .br -->
+mode: { Normal, WhileGrabbed, Grab, Ungrab}
+<!-- .br -->
+detail: { Ancestor, Virtual, Inferior, Nonlinear, NonlinearVirtual, Pointer, PointerRoot, None}</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>These events are generated when the input focus changes and are reported to
+clients selecting <emphasis remap='B'>DeviceFocusChange</emphasis> for the specified device and window.
+Events generated by <emphasis remap='B'>SetDeviceFocus</emphasis> when the device is not grabbed
+have mode <emphasis remap='B'>Normal</emphasis>. Events generated by <emphasis remap='B'>SetDeviceFocus</emphasis> when the
+device is grabbed have mode <emphasis remap='B'>WhileGrabbed</emphasis>. Events generated when a
+device grab actives have mode <emphasis remap='B'>Grab</emphasis>, and events generated when a device
+grab deactivates have mode <emphasis remap='B'>Ungrab</emphasis>.</para>
+<para>All <emphasis remap='B'>DeviceFocusOut</emphasis> events caused by a window unmap are generated after
+any <emphasis remap='B'>UnmapNotify</emphasis> event, but the ordering of <emphasis remap='B'>DeviceFocusOut</emphasis> with
+respect to generated <emphasis remap='B'>EnterNotify</emphasis>, <emphasis remap='B'>LeaveNotify</emphasis>,
+<emphasis remap='B'>VisibilityNotify</emphasis> and <emphasis remap='B'>Expose</emphasis> events is not constrained.</para>
+<para><emphasis remap='B'>DeviceFocusIn</emphasis> and <emphasis remap='B'>DeviceFocusOut</emphasis> events are generated for
+focus changes of extension devices in the same manner as focus events for
+the core devices are generated.</para>
+</sect2>
+<sect2 id='device_state_notify_event'><title>Device State Notify Event</title>
+<!-- .XS -->
+<para>\*(SN Device State Notify Event</para>
+<!-- .XE -->
+<para>DeviceStateNotify</para>
+<!-- .in .5i -->
+<para>time: TIMESTAMP
+<!-- .br -->
+device: CARD8
+<!-- .br -->
+num_keys: CARD8
+<!-- .br -->
+num_buttons: CARD8
+<!-- .br -->
+num_valuators: CARD8
+<!-- .br -->
+classes_reported: CARD8 {SetOfDeviceMode | SetOfInputClass}
+<!-- .in +.5i -->
+<!-- .br -->
+SetOfDeviceMode:
+<!-- .in +.5i -->
+<!-- .br -->
+#x80 ProximityState
+<!-- .in +.5i -->
+<!-- .br -->
+0 = InProxmity, 1 = OutOfProximity
+<!-- .in \-.5i -->
+<!-- .br -->
+#x40 Device Mode
+<!-- .in +.5i -->
+<!-- .br -->
+(0 = Relative, 1 = Absolute)
+<!-- .br -->
+<!-- .in \-1.0i -->
+SetOfInputClass:
+<!-- .in +.5i -->
+<!-- .br -->
+#x04 reporting valuators
+<!-- .br -->
+#x02 reporting buttons
+<!-- .br -->
+#x01 reporting keys
+<!-- .in \-1.0i -->
+<!-- .br -->
+buttons: LISTofCARD8
+<!-- .br -->
+keys: LISTofCARD8
+<!-- .br -->
+valuators: LISTofCARD32</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>This event reports the state of the device just as in the
+<emphasis remap='B'>QueryDeviceState</emphasis> request. This event is reported to clients selecting
+<emphasis remap='B'>DeviceStateNotify</emphasis> for the device and window and is generated immediately
+after every <emphasis remap='B'>EnterNotify</emphasis> and <emphasis remap='B'>DeviceFocusIn</emphasis>. 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.</para>
+</sect2>
+<sect2 id='device_keystate_and_buttonstate_notify_e'><title>Device KeyState and ButtonState Notify Events</title>
+<!-- .XS -->
+<para>\*(SN Device KeyState and ButtonState Notify Events</para>
+<!-- .XE -->
+<para>DeviceKeyStateNotify</para>
+<!-- .in .5i -->
+<para>device: CARD8
+<!-- .br -->
+keys: LISTofCARD8</para>
+<!-- .in \-.5i -->
+<para>DeviceButtonStateNotify</para>
+<!-- .in .5i -->
+<para>device: CARD8
+<!-- .br -->
+buttons: LISTofCARD8</para>
+<!-- .in \-.5i -->
+<para>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.</para>
+</sect2>
+<sect2 id='devicemappingnotify_event'><title>DeviceMappingNotify Event</title>
+<!-- .XS -->
+<para>\*(SN DeviceMappingNotify Event</para>
+<!-- .XE -->
+<para>DeviceMappingNotify</para>
+<!-- .in .5i -->
+<para>time: TIMESTAMP
+<!-- .br -->
+device: CARD8
+<!-- .br -->
+request: CARD8
+<!-- .br -->
+first_keycode: CARD8
+<!-- .br -->
+count: CARD8</para>
+<!-- .in \-.5i -->
+<para>This event reports a change in the mapping of keys, modifiers, or buttons on
+an extension device. This event is reported to clients selecting
+<emphasis remap='B'>DeviceMappingNotify</emphasis> for the device and window and is generated
+after every client <emphasis remap='B'>SetDeviceButtonMapping</emphasis>, <emphasis remap='B'>ChangeDeviceKeyMapping</emphasis>,
+or <emphasis remap='B'>ChangeDeviceModifierMapping</emphasis> request.</para>
+</sect2>
+<sect2 id='changedevicenotify_event'><title>ChangeDeviceNotify Event</title>
+<!-- .XS -->
+<para>\*(SN ChangeDeviceNotify Event</para>
+<!-- .XE -->
+<para>ChangeDeviceNotify</para>
+<!-- .in .5i -->
+<para>device: CARD8
+<!-- .br -->
+time: TIMESTAMP
+<!-- .br -->
+request: CARD8</para>
+<!-- .in \-.5i -->
+<para>This event reports a change in the physical device being used as the core
+X keyboard or X pointer device.
+<emphasis remap='B'>ChangeDeviceNotify</emphasis> events are reported to clients selecting
+<emphasis remap='B'>ChangeDeviceNotify</emphasis> for the device and window and is generated
+after every client <emphasis remap='B'>ChangeKeyboardDevice</emphasis>
+or <emphasis remap='B'>ChangePointerDevice</emphasis> request.</para>
+</sect2>
+<sect2 id='proximity_events'><title>Proximity Events</title>
+<!-- .XS -->
+<para>\*(SN Proximity Events</para>
+<!-- .XE -->
+<para>ProximityIn
+<!-- .br -->
+ProximityOut</para>
+<!-- .in .5i -->
+<para>device: CARD8
+<!-- .br -->
+root, event: WINDOW
+<!-- .br -->
+child: Window or None
+<!-- .br -->
+same-screen: BOOL
+<!-- .br -->
+root-x, root-y, event-x, event-y: INT16
+<!-- .br -->
+state: SETofKEYBUTMASK
+<!-- .br -->
+time: TIMESTAMP
+<!-- .br -->
+device-state: SETofKEYBUTMASK
+<!-- .br -->
+axis-count: CARD8
+<!-- .br -->
+first-axis: CARD8
+<!-- .br -->
+axis-data: LISTofINT32</para>
+<!-- .br -->
+<!-- .in \-.5i -->
+<para>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.</para>
+<para>The &ldquo;source&rdquo; 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 &ldquo;event&rdquo; window.</para>
+<para>The root is the root window of the &ldquo;source&rdquo; 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 &ldquo;event&rdquo; 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.</para>
+<!-- .bp -->
+</sect2>
+</sect1>
+</article>