summaryrefslogtreecommitdiff
path: root/specs/library.xml
diff options
context:
space:
mode:
Diffstat (limited to 'specs/library.xml')
-rw-r--r--specs/library.xml8559
1 files changed, 8559 insertions, 0 deletions
diff --git a/specs/library.xml b/specs/library.xml
new file mode 100644
index 0000000..f399800
--- /dev/null
+++ b/specs/library.xml
@@ -0,0 +1,8559 @@
+<chapter><title>Input Extension</title>
+<sect1 id="Input_Extension_Overview">
+<title>Overview</title>
+<!-- .XS -->
+<!-- (SN Input Extension Overview -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This document describes an extension to
+the X11 server. The purpose of this extension is to support the use
+of additional input devices beyond the pointer and keyboard devices
+defined by the core X protocol. This first section gives an overview
+of the input extension. The following sections correspond to
+chapters 9, 10, and 11, ``Window and Session Manager Functions'',
+``Events'', and ``Event Handling Functions'' of the
+``Xlib - C Language Interface'' manual
+and describe how to use the input device extension.
+</para>
+<sect2 id="Design_Approach">
+<title>Design Approach</title>
+<!-- .XS -->
+<!-- (SN Design Approach -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The design approach of the extension is to define functions
+and events analogous to the core functions and events.
+This allows extension input devices and events to be individually
+distinguishable from each other and from the core input devices and events.
+These functions and events make use of a device identifier and support the
+reporting of <emphasis remap='I'>n</emphasis>-dimensional motion data as well as other data that
+is not currently reportable via the core input events.
+</para>
+</sect2>
+<sect2 id="Core_Input_Devices">
+<title>Core Input Devices</title>
+<!-- .XS -->
+<!-- (SN Core Input Devices -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+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>
+<!-- .LP -->
+The X keyboard is used to generate input that client programs can detect.
+</para>
+<para>
+<!-- .LP -->
+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
+<function>( KeyPress ,</function>
+<function>KeyRelease ,</function>
+<function>ButtonPress ,</function>
+<function>ButtonRelease ,</function>
+and
+<function>MotionNotify )</function>
+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>.
+<!-- .NT -->
+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.''
+<!-- .NE -->
+</para>
+<para>
+<!-- .LP -->
+Selection of the physical devices to be initially used by the server as the
+core devices is left implementation dependent. Functions 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 -->
+<!-- (SN Extension Input Devices -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+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. Input events from
+these devices are of extension types
+<function>( DeviceKeyPress ,</function>
+<function>DeviceKeyRelease ,</function>
+<function>DeviceButtonPress ,</function>
+<function>DeviceButtonRelease ,</function>
+<function>DeviceMotionNotify ,</function>
+and so on) and contain
+a device identifier so that events of the same type coming from different
+input devices can be distinguished.
+</para>
+<para>
+<!-- .LP -->
+Extension input events are not limited in size by the size of the server
+32-byte wire events. Extension input events
+may be constructed by the server sending as many
+wire-sized events as necessary to return the information required for
+that event.
+The library event reformatting routines
+are responsible for combining these into one or more client XEvents.
+</para>
+<para>
+<!-- .LP -->
+Any input device that generates key, button, or motion data may be used as
+an extension input device.
+Extension input devices may have zero or more keys, zero or more buttons,
+and may report zero 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>
+<!-- .LP -->
+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='I'>input device classes</emphasis>. Server implementors may add new
+classes of input devices without changing the protocol requests.
+</para>
+<para>
+<!-- .LP -->
+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>
+<sect3 id="Input_Device_Classes">
+<title>Input Device Classes</title>
+<!-- .XS -->
+<!-- (SN Input Device Classes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+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 functions. The following input device classes are currently
+defined:
+<variablelist>
+ <varlistentry>
+ <term>KEY</term>
+ <listitem>
+ <para>
+The device reports key events.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>BUTTON</term>
+ <listitem>
+ <para>
+The device reports button events.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>VALUATOR</term>
+ <listitem>
+ <para>
+The device reports valuator data in motion events.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PROXIMITY</term>
+ <listitem>
+ <para>
+The device reports proximity events.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>FOCUS</term>
+ <listitem>
+ <para>
+The device can be focused.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>FEEDBACK</term>
+ <listitem>
+ <para>
+The device supports feedbacks.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+Additional classes may be added in the future.
+Functions that support multiple input classes, such as the
+<function>XListInputDevices</function>
+function that lists all available input devices,
+organize the data they return by input class. Client programs that
+use these functions 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 functions to be recompiled.
+</para>
+</sect3>
+</sect2>
+<sect2 id="Using_Extension_Input_Devices">
+<title>Using Extension Input Devices</title>
+<!-- .XS -->
+<!-- (SN Using Extension Input Devices -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A client that wishes to access an input device does so through the library
+functions defined in the following sections. A typical sequence of requests
+that a client would make is as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+<function>XListInputDevices</function>
+- lists all of the available input devices. From the
+information returned by this request, determine whether the desired input
+device is attached to the server. For a description of the
+<function>XListInputDevices</function>
+request, see the section entitled ``Listing Available Devices.''
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XOpenDevice</function>
+- requests that the server open the device for access by this client.
+This request returns an
+<function>XDevice</function>
+structure that is used
+by most other input extension requests to identify the specified device.
+For a description of the
+<function>XOpenDevice</function>
+request, see the section entitled ``Enabling and Disabling Extension Devices.''
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Determine the event types and event classes needed to select the desired
+input extension events, and identify them when they are received.
+This is done via macros whose name corresponds to the desired event, for
+example,
+<function>DeviceKeyPress .</function>
+For a description of these macros,
+see the section entitled ``Selecting Extension Device Events.''
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XSelectExtensionEvent</function>
+- selects the desired events from the server.
+For a description of the
+<function>XSelextExtensionEvent</function>
+request, see the section entitled ``Selecting Extension Device Events.''
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XNextEvent</function>
+- receives the next available event. This is the core
+<function>XNextEvent</function>
+function provided by the standard X libarary.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Other requests are defined to grab and focus extension devices, to
+change their key, button, or modifier mappings, to control the
+propagation of input extension events, to get motion history from an
+extension device, and to send input extension events to another client.
+These functions are described in the following sections.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Library_Extension_Requests">
+<title>Library Extension Requests</title>
+<!-- .XS -->
+<!-- (SN Library Extension Requests -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Extension input devices are accessed by client programs through the
+use of new protocol requests.
+The following requests are provided as extensions to Xlib. Constants
+and structures referenced by these functions may be found in the
+files <function>&lt;X11/extensions/XI.h&gt;</function> and <function>&lt;X11/extensions/XInput.h&gt;</function>,
+which are attached to this document as
+Appendix A.<!-- xref -->
+</para>
+<para>
+<!-- .LP -->
+The library will return <function>NoSuchExtension</function> if an extension request
+is made to a server that does not support the input extension.
+</para>
+<para>
+<!-- .LP -->
+Input extension requests cannot be used to access the X keyboard and
+X pointer devices.
+</para>
+<sect2 id="Window_Manager_Functions">
+<title>Window Manager Functions</title>
+<!-- .XS -->
+<!-- (SN Window Manager Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section discusses the following X Input Extension Window Manager topics:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Changing the core devices
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Event synchronization and core grabs
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Extension active grabs
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Passively grabbing a key
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Passively grabbing a button
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Thawing a device
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Controlling device focus
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Controlling device feedback
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Ringing a bell on an input device
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Controlling device encoding
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Controlling button mapping
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Obtaining the state of a device
+ </para>
+ </listitem>
+</itemizedlist>
+<sect3 id="Changing_the_Core_Devices">
+<title>Changing the Core Devices</title>
+<!-- .XS -->
+<!-- (SN Changing the Core Devices -->
+<!-- .XE -->
+
+<para>
+<!-- .LP -->
+These functions are provided to change which physical device is used
+as the X pointer or X keyboard.
+</para>
+<!-- .NT -->
+<note><para>
+Using these functions may change the characteristics of the core devices.
+The new pointer device may have a different number of buttons from the
+old one, 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 indices into that array. Changing the core devices could cause
+such client programs to behave improperly or to terminate abnormally
+if they ignore the
+<function>ChangeDeviceNotify</function>
+event generated by these requests.
+</para></note>
+<!-- .NE -->
+
+<para>
+<!-- .LP -->
+These functions change the X keyboard or X pointer device and generate an
+<function>XChangeDeviceNotify</function>
+event and a
+<function>MappingNotify</function>
+event.
+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>
+<!-- .LP -->
+These requests fail and return
+<function>AlreadyGrabbed</function>
+if either the specified
+device or the core device it would replace are grabbed by some other client.
+They fail and return
+<function>GrabFrozen</function>
+if either device is frozen by the active grab of another client.
+</para>
+<para>
+<!-- .LP -->
+These requests fail with a
+<function>BadDevice</function>
+error if the specified device is invalid, has not previously been opened via
+<function>XOpenDevice ,</function>
+or is
+not supported as a core device by the server implementation.
+</para>
+<para>
+<!-- .LP -->
+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
+<function>ChangeDevice</function>
+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
+<function>XCloseDevice</function>
+request to close the new core device will fail with a
+<function>BadDevice</function>
+error.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To change which physical device is used as the X keyboard, use the
+<function>XChangeKeyboardDevice</function>
+function.
+The specified device must support input class
+<function>Keys</function>
+(as reported in the
+<function>ListInputDevices</function>
+request) or the request will fail with a
+<function>BadMatch</function>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XChangeKeyboardDevice</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If no error occurs,
+<function>XChangeKeyboardDevice</function>
+returns
+<function>Success .</function>
+A
+<function>ChangeDeviceNotify</function>
+event with the request field set to
+<function>NewKeyboard</function>
+is sent to all clients selecting that event.
+A
+<function>MappingNotify</function>
+event with the request field set to
+<function>MappingKeyboard</function>
+is sent to all clients.
+The requested device becomes the X keyboard, and the old keyboard becomes
+available as an extension input device.
+The focus state of the new keyboard is the same as
+the focus state of the old X keyboard.
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeKeyboardDevice</function>
+can generate
+<function>AlreadyGrabbed ,</function>
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+and
+<function>GrabFrozen</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To change which physical device is used as the X pointer,
+use the
+<function>XChangePointerDevice</function>
+function.
+The specified device must support input class
+<function>Valuators</function>
+(as reported in the
+<function>XListInputDevices</function>
+request) and report at least two axes of motion,
+or the request will fail with a
+<function>BadMatch</function>
+error.
+If the specified device reports more than two axes, the two specified in
+the xaxis and yaxis arguments will be used. Data from other
+valuators on the device will be ignored.
+</para>
+<para>
+<!-- .LP -->
+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
+<function>BadDevice</function>
+error.
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XChangePointerDevice</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>int<parameter> xaxis</parameter></paramdef>
+ <paramdef>int<parameter> yaxis</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>xaxis</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the zero-based index of the axis to be used as the x-axis of the
+pointer device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>yaxis</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the zero-based index of the axis to be used as the y-axis of the
+pointer device.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If no error occurs,
+<function>XChangePointerDevice</function>
+returns
+<function>Success .</function>
+A
+<function>ChangeDeviceNotify</function>
+event with the request field set to
+<function>NewPointer</function>
+is sent to all clients selecting that event.
+A
+<function>MappingNotify</function>
+event with the request field set to
+<function>MappingPointer</function>
+is sent to all clients.
+The requested device becomes the X pointer, and the old pointer becomes
+available as an extension input device.
+</para>
+<para>
+<!-- .LP -->
+<function>XChangePointerDevice</function>
+can generate
+<function>AlreadyGrabbed ,</function>
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+and
+<function>GrabFrozen</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Event_Synchronization_and_Core_Grabs">
+<title>Event Synchronization and Core Grabs</title>
+<!-- .XS -->
+<!-- (SN Event Synchronization and Core Grabs -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+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>
+<!-- .LP -->
+The core grab requests require a pointer_mode and keyboard_mode
+argument. The meaning of these modes is changed by the input extension.
+For the
+<function>XGrabPointer</function>
+and
+<function>XGrabButton</function>
+requests, pointer_mode controls synchronization of the pointer device,
+and keyboard_mode controls the synchronization of all other input devices.
+For the
+<function>XGrabKeyboard</function>
+and
+<function>XGrabKey</function>
+requests, pointer_mode controls the synchronization
+of all input devices, except the X keyboard, while keyboard_mode controls
+the synchronization of the keyboard. When using one of the core grab
+requests, the synchronization of extension devices
+is controlled by the mode specified for the device not being grabbed.
+</para>
+</sect3>
+<sect3 id="Extension_Active_Grabs">
+<title>Extension Active Grabs</title>
+<!-- .XS -->
+<!-- (SN Extension Active Grabs -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Active grabs of
+extension devices are supported via the
+<function>XGrabDevice</function>
+function in the same way that core devices are grabbed using the core
+<function>XGrabKeyboard</function>
+function, except that an extension input device
+is passed as a function parameter.
+The
+<function>XUngrabDevice</function>
+function allows a previous active grab for an extension device to be released.
+</para>
+<para>
+<!-- .LP -->
+Passive grabs of buttons and keys on extension devices are supported
+via the
+<function>XGrabDeviceButton</function>
+and
+<function>XGrabDeviceKey</function>
+functions.
+These passive grabs are released via the
+<function>XUngrabDeviceKey</function>
+and
+<function>XUngrabDeviceButton</function>
+functions.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To grab an extension device, use the
+<function>XGrabDevice</function>
+function.
+The device must have previously been opened using the
+<function>XOpenDevice</function>
+function.
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XGrabDevice</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>Window<parameter> grab_window</parameter></paramdef>
+ <paramdef>Bool<parameter> owner_events</parameter></paramdef>
+ <paramdef>int<parameter> event_count</parameter></paramdef>
+ <paramdef>XEventClass<parameter> *event_list</parameter></paramdef>
+ <paramdef>int<parameter> this_device_mode</parameter></paramdef>
+ <paramdef>int<parameter> other_device_mode</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ "<emphasis remap='I'>display</emphasis>"
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>grab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ID of a window associated with the device specified above.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>owner_events</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a boolean value of either
+<function>True</function>
+or
+<function>False .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of elements in the event_list array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to a list of event classes that indicate which events
+the client wishes to receive.
+These event classes must have been obtained
+using the device being grabbed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>this_device_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Controls further processing of events from this device. You can pass one
+of these constants:
+<function>GrabModeSync</function>
+or
+<function>GrabModeAsync .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>other_device_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Controls further processing of events from all other devices. You can pass one
+of these constants:
+<function>GrabModeSync</function>
+or
+<function>GrabModeAsync .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time. This may be either a timestamp expressed in
+milliseconds or
+<function>CurrentTime .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGrabDevice</function>
+actively grabs an extension input device and generates
+<function>DeviceFocusIn</function>
+and
+<function>DeviceFocusOut</function>
+events.
+Further input events from this device are reported only to the grabbing client.
+This function overrides any previous active grab by this client for this device.
+</para>
+<para>
+<!-- .LP -->
+The event_list parameter is a pointer to a list of event classes. This list
+indicates which events the client wishes to receive while the grab is active.
+If owner_events is
+<function>False ,</function>
+input events from this device are reported with respect to
+grab_window and are reported only if specified in event_list.
+If owner_events is
+<function>True ,</function>
+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 specified in event_list.
+</para>
+<para>
+<!-- .LP -->
+The this_device_mode argument controls the further processing
+of events from this device, and the other_device_mode argument controls
+the further processing of input events from all other devices.
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If the this_device_mode argument is
+<function>GrabModeAsync ,</function>
+device event processing continues
+normally; if the device is currently frozen by this client, then
+processing of device events is resumed.
+If the this_device_mode argument is
+<function>GrabModeSync ,</function>
+the state of the grabbed device
+(as seen by client applications) appears to freeze,
+and no further device events are generated by the server until the
+grabbing client issues a releasing
+<function>XAllowDeviceEvents</function>
+call 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>
+ </listitem>
+ <listitem>
+ <para>
+If the other_device_mode is
+<function>GrabModeAsync ,</function>
+event processing from other input devices is unaffected
+by activation of the grab.
+If other_device_mode is
+<function>GrabModeSync ,</function>
+the state of all devices except the grabbed device
+(as seen by client applications) appears to freeze, and no further
+events are generated by the server until the grabbing client issues a
+releasing
+<function>XAllowEvents</function>
+or
+<function>XAllowDeviceEvents</function>
+call or until the device grab is released.
+Actual events are not lost
+while the other devices are frozen; they are simply queued for later
+processing.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<function>XGrabDevice</function>
+fails on the following conditions:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If the device is actively grabbed by some other client, it returns
+<function>AlreadyGrabbed .</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If grab_window is not viewable, it returns
+<function>GrabNotViewable .</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the specified time is earlier
+than the last-grab-time for the specified device
+or later than the current X server time, it returns
+<function>GrabInvalidTime .</function>
+Otherwise,
+the last-grab-time for the specified device is set
+to the specified time and
+<function>CurrentTime</function>
+is replaced by the current X server time.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the device is frozen by an active grab of another client, it returns
+<function>GrabFrozen .</function>
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+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>
+<!-- .LP -->
+<function>XGrabDevice</function>
+can generate
+<function>BadClass ,</function>
+<function>BadDevice ,</function>
+<function>BadValue ,</function>
+and
+<function>BadWindow</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To release a grab of an extension device, use the
+<function>XUngrabDevice</function>
+function.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XUngrabDevice</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time. This may be either a timestamp expressed in
+milliseconds, or
+<function>CurrentTime .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XUngrabDevice</function>
+allows a client to release an extension input device and any
+queued events if this client has it grabbed from either
+<function>XGrabDevice</function>
+or
+<function>XGrabDeviceKey .</function>
+If any other devices are frozen by the grab,
+<function>XUngrabDevice</function>
+thaws them.
+This function does not release the device and any
+queued events if the specified time is earlier than the last-device-grab
+time or is later than the current X server time. It also generates
+<function>DeviceFocusIn</function>
+and
+<function>DeviceFocusOut</function>
+events. The X server automatically performs an
+<function>XUngrabDevice</function>
+if the event window for an active device grab becomes not viewable
+or if the client terminates without releasing the grab.
+</para>
+<para>
+<!-- .LP -->
+<function>XUngrabDevice</function>
+can generate
+<function>BadDevice</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Passively_Grabbing_a_Key">
+<title>Passively Grabbing a Key</title>
+<!-- .XS -->
+<!-- (SN Passively Grabbing a Key -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To passively grab a single key on an extension device, use
+<function>XGrabDeviceKey .</function>
+That device must have previously been opened using the
+<function>XOpenDevice</function>
+function, or the request will fail with a
+<function>BadDevice</function>
+error.
+If the specified device does not support input class
+<function>Keys ,</function>
+the request will fail with a
+<function>BadMatch</function>
+error.
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XGrabDeviceKey</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>int<parameter> keycode</parameter></paramdef>
+ <paramdef>unsignedint<parameter> modifiers</parameter></paramdef>
+ <paramdef>XDevice<parameter> *modifier_device</parameter></paramdef>
+ <paramdef>Window<parameter> grab_window</parameter></paramdef>
+ <paramdef>Bool<parameter> owner_events</parameter></paramdef>
+ <paramdef>int<parameter> event_count</parameter></paramdef>
+ <paramdef>XEventClass<parameter> *event_list</parameter></paramdef>
+ <paramdef>int<parameter> this_device_mode</parameter></paramdef>
+ <paramdef>int<parameter> other_device_mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keycode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the keycode of the key that is to be grabbed. You can pass
+either the keycode or
+<function>AnyKey .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifiers</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the set of keymasks. This mask is the bitwise inclusive OR
+of these keymask bits:
+<function>ShiftMask ,</function>
+<function>LockMask ,</function>
+<function>ControlMask ,</function>
+<function>Mod1Mask ,</function>
+<function>Mod2Mask ,</function>
+<function>Mod3Mask ,</function>
+<function>Mod4Mask ,</function>
+and
+<function>Mod5Mask .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+
+ </term>
+ <listitem>
+ <para>
+You can also pass
+<function>AnyModifier ,</function>
+which is equivalent to issuing the grab key request
+for all possible modifier combinations (including the combination
+of no modifiers).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifier_device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device whose modifiers are to be used. If NULL is
+specified, the core X keyboard is used as the modifier_device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>grab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ID of a window associated with the device specified above.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>owner_events</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a boolean value of either
+<function>True</function>
+or
+<function>False .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of elements in the event_list array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to a list of event classes that indicate which events
+the client wishes to receive.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>this_device_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Controls further processing of events from this device.
+You can pass one of these constants:
+<function>GrabModeSync</function>
+or
+<function>GrabModeAsync .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>other_device_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Controls further processing of events from all other devices.
+You can pass one of these constants:
+<function>GrabModeSync</function>
+or
+<function>GrabModeAsync .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGrabDeviceKey</function>
+is analogous to the core
+<function>XGrabKey</function>
+function. It creates an
+explicit passive grab for a key on an extension device.
+The
+<function>XGrabDeviceKey</function>
+function establishes a passive grab on a device.
+Consequently, in the future,
+</para>
+<itemizedlist>
+ <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>
+ <listitem>
+ <para>
+AND no other modifier keys logically are down,
+ </para>
+ </listitem>
+ <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>
+ <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>
+ <listitem>
+ <para>
+THEN the device is actively grabbed, as for
+<function>XGrabDevice ,</function>
+the last-device-grab time is set to the time at which the key was pressed
+(as transmitted in the
+<function>DeviceKeyPress</function>
+event), and the
+<function>DeviceKeyPress</function>
+event is reported.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The interpretation of the remaining arguments is as for
+<function>XGrabDevice .</function>
+The active grab is terminated automatically when the logical state of the
+device has the specified key released
+(independent of the logical state of the modifier keys).
+</para>
+<para>
+<!-- .LP -->
+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>
+<!-- .LP -->
+A modifier of
+<function>AnyModifier</function>
+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
+<function>AnyKey</function>
+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
+information returned by the
+<function>XListInputDevices</function>
+function.
+If it is not within that range,
+<function>XGrabDeviceKey</function>
+generates a
+<function>BadValue</function>
+error.
+</para>
+<para>
+<!-- .LP -->
+<function>XGrabDeviceKey</function>
+generates a
+<function>BadAccess</function>
+error if some other client has issued a
+<function>XGrabDeviceKey</function>
+with the same device and key combination on the same window.
+When using
+<function>AnyModifier</function>
+or
+<function>AnyKey ,</function>
+the request fails completely and the X server generates a
+<function>BadAccess</function>
+error, and no grabs are established if there is a conflicting grab
+for any combination.
+</para>
+<para>
+<!-- .LP -->
+<function>XGrabDeviceKey</function>
+returns
+<function>Success</function>
+upon successful completion of the request.
+</para>
+<para>
+<!-- .LP -->
+<function>XGrabDeviceKey</function>
+can generate
+<function>BadAccess ,</function>
+<function>BadClass ,</function>
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+<function>BadValue ,</function>
+and
+<function>BadWindow</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To release a passive grab of a single key on an extension device, use
+<function>XUngrabDeviceKey .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XUngrabDeviceKey</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>int<parameter> keycode</parameter></paramdef>
+ <paramdef>unsignedint<parameter> modifiers</parameter></paramdef>
+ <paramdef>XDevice<parameter> *modifier_device</parameter></paramdef>
+ <paramdef>Window<parameter> ungrab_window</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keycode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the keycode of the key that is to be ungrabbed. You can pass
+either the keycode or
+<function>AnyKey .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifiers</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the set of keymasks. This mask is the bitwise inclusive OR
+of these keymask bits:
+<function>ShiftMask ,</function>
+<function>LockMask ,</function>
+<function>ControlMask , </function>
+<function>Mod1Mask ,</function>
+<function>Mod2Mask ,</function>
+<function>Mod3Mask ,</function>
+<function>Mod4Mask ,</function>
+and
+<function>Mod5Mask .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+
+ </term>
+ <listitem>
+ <para>
+You can also pass
+<function>AnyModifier ,</function>
+which is equivalent to issuing the ungrab key
+request for all possible modifier combinations (including the combination
+of no modifiers).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifier_device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device whose modifiers are to be used. If NULL is
+specified, the core X keyboard is used as the modifier_device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ungrab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ID of a window associated with the device specified above.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XUngrabDeviceKey</function>
+is analogous to the core
+<function>XUngrabKey</function>
+function. It releases an explicit passive grab for a key
+on an extension input device.
+</para>
+<para>
+<!-- .LP -->
+<function>XUngrabDeviceKey</function>
+can generate
+<function>BadAlloc ,</function>
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+<function>BadValue ,</function>
+and
+<function>BadWindow</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Passively_Grabbing_a_Button">
+<title>Passively Grabbing a Button</title>
+<!-- .XS -->
+<!-- (SN Passively Grabbing a Button -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To establish a passive grab for a single button on an extension device, use
+<function>XGrabDeviceButton .</function>
+The specified device must have previously been opened using the
+<function>XOpenDevice</function>
+function, or the request will fail with a
+<function>BadDevice</function>
+error. If the specified device does not support input class
+<function>Buttons ,</function>
+the request will fail with a
+<function>BadMatch</function>
+error.
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XGrabDeviceButton</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>unsignedint<parameter> button</parameter></paramdef>
+ <paramdef>unsignedint<parameter> modifiers</parameter></paramdef>
+ <paramdef>XDevice*modifier_device<parameter> </parameter></paramdef>
+ <paramdef>Window<parameter> grab_window</parameter></paramdef>
+ <paramdef>Bool<parameter> owner_events</parameter></paramdef>
+ <paramdef>int<parameter> event_count</parameter></paramdef>
+ <paramdef>XEventClass<parameter> *event_list</parameter></paramdef>
+ <paramdef>int<parameter> this_device_mode</parameter></paramdef>
+ <paramdef>int<parameter> other_device_mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>button</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the code of the button that is to be grabbed. You can pass
+either the button or
+<function>AnyButton .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifiers</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the set of keymasks. This mask is the bitwise inclusive OR
+of these keymask bits:
+<function>ShiftMask ,</function>
+<function>LockMask ,</function>
+<function>ControlMask , </function>
+<function>Mod1Mask ,</function>
+<function>Mod2Mask ,</function>
+<function>Mod3Mask ,</function>
+<function>Mod4Mask ,</function>
+and
+<function>Mod5Mask .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+
+ </term>
+ <listitem>
+ <para>
+You can also pass
+<function>AnyModifier ,</function>
+which is equivalent to issuing the grab request
+for all possible modifier combinations (including the combination
+of no modifiers).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifier_device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device whose modifiers are to be used. If NULL is
+specified, the core X keyboard is used as the modifier_device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>grab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ID of a window associated with the device specified above.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>owner_events</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a boolean value of either
+<function>True</function>
+or
+<function>False .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of elements in the event_list array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a list of event classes that indicates which device events are to be
+reported to the client.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>this_device_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Controls further processing of events from this device. You can pass one
+of these constants:
+<function>GrabModeSync</function>
+or
+<function>GrabModeAsync .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>other_device_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Controls further processing of events from all other devices. You can pass one
+of these constants:
+<function>GrabModeSync</function>
+or
+<function>GrabModeAsync .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGrabDeviceButton </function>
+is analogous to the core
+<function>XGrabButton</function>
+function.
+It creates an explicit passive grab for a button on an extension input device.
+Because 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
+<function>XOpenDevice</function>
+function.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XGrabDeviceButton</function>
+function establishes a passive grab on a device.
+Consequently, in the future,
+</para>
+<itemizedlist>
+ <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>
+ <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>
+ <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>
+ <listitem>
+ <para>
+THEN the device is actively grabbed, as for
+<function>XGrabDevice ,</function>
+the last-grab time is set to the time at which the button was pressed
+(as transmitted in the
+<function>DeviceButtonPress</function>
+event), and the
+<function>DeviceButtonPress</function>
+event is reported.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The interpretation of the remaining arguments is as for
+<function>XGrabDevice .</function>
+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>
+<!-- .LP -->
+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>
+<!-- .LP -->
+A modifier of
+<function>AnyModifier</function>
+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
+<function>AnyButton</function>
+is equivalent to issuing
+the request for all possible buttons.
+Otherwise, it is not required that the
+specified button be assigned to a physical button.
+</para>
+<para>
+<!-- .LP -->
+<function>XGrabDeviceButton</function>
+generates a
+<function>BadAccess</function>
+error if some other client has issued a
+<function>XGrabDeviceButton</function>
+with the same device and button combination on the same window.
+When using
+<function>AnyModifier</function>
+or
+<function>AnyButton ,</function>
+the request fails completely and the X server generates a
+<function>BadAccess</function>
+error and no grabs are
+established if there is a conflicting grab for any combination.
+</para>
+<para>
+<!-- .LP -->
+<function>XGrabDeviceButton</function>
+can generate
+<function>BadAccess , </function>
+<function>BadClass ,</function>
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+<function>BadValue ,</function>
+and
+<function>BadWindow</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To release a passive grab of a button on an extension device, use
+<function>XUngrabDeviceButton .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XUngrabDeviceButton</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>unsignedint<parameter> button</parameter></paramdef>
+ <paramdef>unsignedint<parameter> modifiers</parameter></paramdef>
+ <paramdef>XDevice<parameter> *modifier_device</parameter></paramdef>
+ <paramdef>Window<parameter> ungrab_window</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>button</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the code of the button that is to be ungrabbed. You can pass
+either a button or
+<function>AnyButton .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifiers</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the set of keymasks. This mask is the bitwise inclusive OR
+of these keymask bits:
+<function>ShiftMask ,</function>
+<function>LockMask ,</function>
+<function>ControlMask , </function>
+<function>Mod1Mask ,</function>
+<function>Mod2Mask ,</function>
+<function>Mod3Mask ,</function>
+<function>Mod4Mask ,</function>
+and
+<function>Mod5Mask .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+
+ </term>
+ <listitem>
+ <para>
+You can also pass
+<function>AnyModifier ,</function>
+which is equivalent to issuing the ungrab key
+request for all possible modifier combinations (including the combination
+of no modifiers).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifier_device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device whose modifiers are to be used. If NULL is
+specified, the core X keyboard is used as the modifier_device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ungrab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ID of a window associated with the device specified above.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XUngrabDeviceButton </function>
+is analogous to the core
+<function>XUngrabButton</function>
+function. It releases an explicit passive grab for a button
+on an extension device.
+That device must have previously been opened using the
+<function>XOpenDevice</function>
+function, or a
+<function>BadDevice</function>
+error will result.
+</para>
+<para>
+<!-- .LP -->
+A modifier of
+<function>AnyModifier</function>
+is equivalent to issuing the request for all
+possible modifier combinations (including the combination of no
+modifiers).
+</para>
+<para>
+<!-- .LP -->
+<function>XUngrabDeviceButton </function>
+can generate
+<function>BadAlloc , </function>
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+<function>BadValue ,</function>
+and
+<function>BadWindow</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Thawing_a_Device">
+<title>Thawing a Device</title>
+<!-- .XS -->
+<!-- (SN Thawing a Device -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To allow further events to be processed when a device has been frozen, use
+<function>XAllowDeviceEvents .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XAllowDeviceEvents</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>int<parameter> event_mode</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event mode. You can pass one of these constants:
+<function>AsyncThisDevice ,</function>
+<function>SyncThisDevice ,</function>
+<function>AsyncOtherDevices ,</function>
+<function>ReplayThisDevice ,</function>
+<function>AsyncAll ,</function>
+or
+<function>SyncAll .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time. This may be either a timestamp expressed in
+milliseconds, or
+<function>CurrentTime .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XAllowDeviceEvents</function>
+releases some queued events if the client has caused a device to freeze.
+It has no effect if the specified time is earlier than the last-grab
+time of the most recent active grab for the client and device,
+or if the specified time is later than the current X server time.
+The following describes the processing that occurs depending on what constant
+you pass to the event_mode argument:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+<function>AsyncThisDevice</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the specified device is frozen by the client, event processing for that
+continues as usual. If the device is frozen multiple times by the client on
+behalf of multiple separate grabs,
+<function>AsyncThisDevice</function>
+thaws for all.
+<function>AsyncThisDevice</function>
+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>
+ <listitem>
+ <para>
+<function>SyncThisDevice</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the specified device is frozen and actively grabbed by the client,
+event processing for that device continues normally until the next
+key or button 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.
+<function>SyncThisDevice</function>
+has no effect if the specified device is not frozen by the client
+or is not grabbed by the client.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>ReplayThisDevice</function>
+ </para>
+ </listitem>
+ <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
+<function>GrabDeviceButton</function>
+or from a previous
+<function>AllowDeviceEvents</function>
+with mode
+<function>SyncThisDevice , </function>
+but not from a
+<function>Grab ),</function>
+the grab is released and that event is completely reprocessed.
+This time, however, the request ignores any passive grabs at or above
+(toward 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>
+ <listitem>
+ <para>
+<function>AsyncOtherDevices</function>
+ </para>
+ </listitem>
+ <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,
+<function>AsyncOtherDevices</function>
+``thaws'' for all.
+<function>AsyncOtherDevices</function>
+has no effect if the devices are not frozen by the client,
+but those devices need not be grabbed by the client.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>SyncAll</function>
+ </para>
+ </listitem>
+ <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,
+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).
+<function>SyncAll</function>
+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,
+<function>SyncAll</function>
+"thaws" for both (but a subsequent freeze for
+<function>SyncAll</function>
+will freeze each device only once).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>AsyncAll</function>
+ </para>
+ </listitem>
+ <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,
+<function>AsyncAll</function>
+``thaws ''for all.
+If any device is frozen twice by the client on behalf of two separate grabs,
+<function>AsyncAll</function>
+``thaws'' for both.
+<function>AsyncAll</function>
+has no effect unless all devices are frozen by the client.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<function>AsyncThisDevice ,</function>
+<function>SyncThisDevice ,</function>
+and
+<function>ReplayThisDevice </function>
+have no effect on the processing of events from the remaining devices.
+<function>AsyncOtherDevices</function>
+has no effect on the processing of events from the specified device.
+When the event_mode is
+<function>SyncAll</function>
+or
+<function>AsyncAll ,</function>
+the device parameter is ignored.
+</para>
+<para>
+<!-- .LP -->
+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>
+<para>
+<!-- .LP -->
+<function>XAllowDeviceEvents</function>
+can generate
+<function>BadDevice</function>
+and
+<function>BadValue</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Controlling_Device_Focus">
+<title>Controlling Device Focus</title>
+<!-- .XS -->
+<!-- (SN Controlling Device Focus -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The current focus window for an extension input device can be
+determined using the
+<function>XGetDeviceFocus</function>
+function.
+Extension devices are focused using the
+<function>XSetDeviceFocus</function>
+function in the same way that the keyboard is focused using the core
+<function>XSetInputFocus</function>
+function, except that a device ID is passed as
+a function parameter. One additional focus state,
+<function>FollowKeyboard ,</function>
+is provided for extension devices.
+</para>
+<para>
+<!-- .LP -->
+To get the current focus state, revert state,
+and focus time of an extension device, use
+<function>XGetDeviceFocus .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XGetDeviceFocus</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>Window<parameter> *focus_return</parameter></paramdef>
+ <paramdef>int<parameter> *revert_to_return</parameter></paramdef>
+ <paramdef>Time<parameter> *focus_time_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>focus_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the address of a variable into which the server can return the ID of
+the window that contains the device focus or one of the constants
+<function>None ,</function>
+<function>PointerRoot ,</function>
+or
+<function>FollowKeyboard . </function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>revert_to_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the address of a variable into which the server can
+return the current revert_to status for the device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>focus_time_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the address of a variable into which the server can
+return the focus time last set for the device.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetDeviceFocus</function>
+returns the focus state, the revert-to state,
+and the last-focus-time for an extension input device.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetDeviceFocus</function>
+can generate
+<function>BadDevice</function>
+and
+<function>BadMatch</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set the focus of an extension device, use
+<function>XSetDeviceFocus .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XSetDeviceFocus</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>Window<parameter> focus</parameter></paramdef>
+ <paramdef>int<parameter> revert_to</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>focus</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ID of the window to which the device's focus should be set.
+This may be a window ID, or
+<function>PointerRoot ,</function>
+<function>FollowKeyboard ,</function>
+or
+<function>None .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>revert_to</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies to which window the focus of the device should revert
+if the focus window becomes not viewable. One of the following
+constants may be passed:
+<function>RevertToParent ,</function>
+<function>RevertToPointerRoot ,</function>
+<function>RevertToNone ,</function>
+or
+<function>RevertToFollowKeyboard .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time. You can pass either a timestamp, expressed in
+milliseconds, or
+<function>CurrentTime .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetDeviceFocus</function>
+changes the focus for an extension input device and the
+last-focus-change-time. It 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.
+This function causes the X server to generate
+<function>DeviceFocusIn</function>
+and
+<function>DeviceFocusOut</function>
+events.
+</para>
+<para>
+<!-- .LP -->
+The action taken by the server when this function is requested depends
+on the value of the focus argument:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If the focus argument is
+<function>None ,</function>
+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>
+ <listitem>
+ <para>
+If the focus argument is a window ID, 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>
+ <listitem>
+ <para>
+If the focus argument is
+<function>PointerRoot ,</function>
+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>
+ <listitem>
+ <para>
+If the focus argument is
+<function>FollowKeyboard , </function>
+the focus window is dynamically taken to be the same as the focus
+of the X keyboard at each input event.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The specified focus window must be viewable at the time
+<function>XSetDeviceFocus</function>
+is called. Otherwise, it generates a
+<function>BadMatch</function>
+error.
+If the focus window later becomes not viewable,
+the X server evaluates the revert_to argument
+to determine the new focus window.
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If the revert_to argument is
+<function>RevertToParent ,</function>
+the focus reverts to the parent (or the closest viewable ancestor),
+and the new revert_to value is taken to be
+<function>RevertToNone . </function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the revert_to argument is
+<function>RevertToPointerRoot ,</function>
+<function>RevertToFollowKeyboard ,</function>
+or
+<function>RevertToNone ,</function>
+the focus reverts to that value.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+When the focus reverts,
+the X server generates
+<function>DeviceFocusIn</function>
+and
+<function>DeviceFocusOut</function>
+events, but the last-focus-change time is not affected.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetDeviceFocus</function>
+can generate
+<function>BadDevice ,</function>
+<function>BadMatch , </function>
+<function>BadValue ,</function>
+and
+<function>BadWindow</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Controlling_Device_Feedback">
+<title>Controlling Device Feedback</title>
+<!-- .XS -->
+<!-- (SN Controlling Device Feedback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To determine the current feedback settings of an extension input device, use
+<function>XGetFeedbackControl .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>XFeedbackState * <function> XGetFeedbackControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>int<parameter> *num_feedbacks_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_feedbacks_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of feedbacks supported by the device.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetFeedbackControl</function>
+returns a list of
+<function>FeedbackState</function>
+structures that describe the feedbacks supported by the specified device.
+There is an
+<function>XFeedbackState</function>
+structure for each class of feedback. These are of
+variable length, but the first three members are common to all.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+} XFeedbackState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The common members are as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The class member identifies the class of feedback.
+It may be compared to constants defined in the file
+<function>&lt; X11/extensions/XI.h &gt;.</function>
+Currently defined feedback constants include:
+<function>KbdFeedbackClass , </function>
+<function>PtrFeedbackClass ,</function>
+<function>StringFeedbackClass ,</function>
+<function>IntegerFeedbackClass , </function>
+<function>LedFeedbackClass ,</function>
+and
+<function>BellFeedbackClass .</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The length member specifies the length of the
+<function>FeedbackState</function>
+structure and can be used by clients to traverse the list.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The id member uniquely identifies a feedback for a given device and class.
+This allows a device to support more than one feedback of the same class.
+Other feedbacks of other classes or devices may have the same ID.
+<!-- .sp -->
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Those feedbacks equivalent to those
+supported by the core keyboard are reported in class
+<function>KbdFeedback</function>
+using the
+<function>XKbdFeedbackState</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int click;
+ int percent;
+ int pitch;
+ int duration;
+ int led_mask;
+ int global_auto_repeat;
+ char auto_repeats[32];
+} XKbdFeedbackState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The additional members of the
+<function>XKbdFeedbackState</function>
+structure report the current state of the feedback:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The click member specifies the key-click volume and has a value in the range
+0 (off) to 100 (loud).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The percent member specifies the bell volume and has a value in the range
+0 (off) to 100 (loud).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The pitch member specifies the bell pitch in Hz. The range of the value is
+implementation-dependent.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The duration member specifies the duration in milliseconds of the bell.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The led_mask member is a bit mask that describes the current state of up to
+32 LEDs. A value of 1 in a bit indicates that the corresponding LED is on.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The global_auto_repeat member has a value of
+<function>AutoRepeatModeOn</function>
+or
+<function>AutoRepeatModeOff .</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The auto_repeats member is a bit vector. Each bit set to 1 indicates
+that auto-repeat is enabled for the corresponding key. The vector is
+represented as 32 bytes. Byte N (from 0) contains the bits for keys
+8N to 8N + 7, with the least significant bit in the byte representing
+key 8N.
+<!-- .sp -->
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Those feedbacks equivalent to those
+supported by the core pointer are reported in class
+<function>PtrFeedback</function>
+using the
+<function>XPtrFeedbackState</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int accelNum;
+ int accelDenom;
+ int threshold;
+} XPtrFeedbackState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The additional members of the
+<function>XPtrFeedbackState</function>
+structure report the current state of the feedback:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The accelNum member returns the numerator for the acceleration multiplier.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The accelDenom member returns the denominator for the acceleration multiplier.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The accelDenom member returns the threshold for the acceleration.
+<!-- .sp -->
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Integer feedbacks are those capable of displaying integer numbers
+and reported via the
+<function>XIntegerFeedbackState</function>
+structure.
+The minimum and maximum values that they can display are reported.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int resolution;
+ int minVal;
+ int maxVal;
+} XIntegerFeedbackState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The additional members of the
+<function>XIntegerFeedbackState</function>
+structure report the capabilities of the feedback:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The resolution member specifies the number of digits that the feedback
+can display.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The minVal member specifies the minimum value that the feedback can display.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The maxVal specifies the maximum value that the feedback can display.
+<!-- .sp -->
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+String feedbacks are those that can display character information
+and are reported via the
+<function>XStringFeedbackState</function>
+structure.
+Clients set these feedbacks by passing a list of
+<function>KeySyms</function>
+to be displayed.
+The
+<function>XGetFeedbackControl</function>
+function returns the
+set of key symbols that the feedback can display, as well as the
+maximum number of symbols that can be displayed.
+The
+<function>XStringFeedbackState</function>
+structure is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int max_symbols;
+ int num_syms_supported;
+ KeySym *syms_supported;
+} XStringFeedbackState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The additional members of the
+<function>XStringFeedbackState</function>
+structure report the capabilities of the feedback:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The max_symbols member specifies the maximum number of symbols
+that can be displayed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The syms_supported member is a pointer to the list of supported symbols.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The num_syms_supported member specifies the length of the list of supported symbols.
+<!-- .sp -->
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Bell feedbacks are those that can generate a sound
+and are reported via the
+<function>XBellFeedbackState</function>
+structure.
+Some implementations may support a bell as part of a
+<function>KbdFeedback</function>
+feedback. Class
+<function>BellFeedback</function>
+is provided for implementations that do not choose to do
+so and for devices that support multiple feedbacks that can produce sound.
+The meaning of the members is the same as that of the corresponding fields in
+the
+<function>XKbdFeedbackState</function>
+structure.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int percent;
+ int pitch;
+ int duration;
+} XBellFeedbackState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Led feedbacks are those that can generate a light and are reported via the
+<function>XLedFeedbackState</function>
+structure.
+Up to 32 lights per feedback are supported.
+Each bit in led_mask
+corresponds to one supported light, and the corresponding bit in led_values
+indicates whether that light is currently on (1) or off (0).
+Some implementations may support leds as part of a
+<function>KbdFeedback</function>
+feedback.
+Class
+<function>LedFeedback</function>
+is provided for implementations that do not choose to do
+so and for devices that support multiple led feedbacks.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ Mask led_values;
+ Mask led_mask;
+} XLedFeedbackState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetFeedbackControl</function>
+can generate
+<function>BadDevice</function>
+and
+<function>BadMatch</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To free the information returned by the
+<function>XGetFeedbackControl</function>
+function, use
+<function>XFreeFeedbackList .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>void <function> XFreeFeedbackList</function></funcdef>
+ <paramdef>XFeedbackState<parameter> *list</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pointer to the
+<function>XFeedbackState</function>
+structure returned by
+a previous call to
+<function>XGetFeedbackControl .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XFreeFeedbackList</function>
+frees the list of feedback control information.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To change the settings of a feedback on an extension device, use
+<function>XChangeFeedbackControl .</function>
+This function modifies the current control values of the specified feedback
+using information passed in the appropriate
+<function>XFeedbackControl</function>
+structure for the feedback.
+Which values are modified depends on the valuemask passed.
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XChangeFeedbackControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef>
+ <paramdef>XFeedbackControl<parameter> *value</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>valuemask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies one value for each bit in the mask (least to most significant
+bit). The values are associated with the feedbacks for the specified
+device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the
+<function>XFeedbackControl</function>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XChangeFeedbackControl</function>
+controls the device characteristics described by the
+<function>XFeedbackControl</function>
+structure.
+There is an
+<function>XFeedbackControl</function>
+structure for each class of feedback.
+These are of variable length, but the first
+three members are common to all and are as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+} XFeedbackControl;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Feedback class
+<function>KbdFeedback</function>
+controls feedbacks equivalent to those provided by the core keyboard using the
+<function>KbdFeedbackControl</function>
+structure, which is defined as follows:.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int click;
+ int percent;
+ int pitch;
+ int duration;
+ int led_mask;
+ int led_value;
+ int key;
+ int auto_repeat_mode;
+} XKbdFeedbackControl;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+This class controls the device characteristics described by the
+<function>XKbdFeedbackControl</function>
+structure. These include the key_click_percent,
+global_auto_repeat, and individual key auto-repeat. Valid modes
+are
+<function>AutoRepeatModeOn ,</function>
+<function>AutoRepeatModeOff ,</function>
+and
+<function>AutoRepeatModeDefault .</function>
+</para>
+<para>
+<!-- .LP -->
+Valid masks are as follows:
+<!-- .sM -->
+</para>
+
+<literallayout class="monospaced">
+
+#define DvKeyClickPercent (1>&lt;&lt;0)
+#define DvPercent (1>&lt;&lt;0)
+#define DvPitch (1>&lt;&lt;0)
+#define DvDuration (1>&lt;&lt;0)
+#define DvLed (1>&lt;&lt;0)
+#define DvLedMode (1>&lt;&lt;0)
+#define DvKey (1>&lt;&lt;0)
+#define DvAutoRepeatMode (1>&lt;&lt;0)
+</literallayout>
+
+<para>
+<!-- .LP -->
+Feedback class
+<function>PtrFeedback</function>
+controls feedbacks equivalent to those provided by the core pointer using the
+<function>PtrFeedbackControl</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int accelNum;
+ int accelDenom;
+ int threshold;
+} XPtrFeedbackControl;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Which values are modified depends on the valuemask passed.
+</para>
+<para>
+<!-- .LP -->
+Valid masks are as follows:
+<!-- .sM -->
+</para>
+
+<literallayout class="monospaced">
+#define DvAccelnum (1L&lt;&lt;0)
+#define DvAccelDenom (1L&lt;&lt;1)
+#define DvThreshold (1L&lt;&lt;2)
+</literallayout>
+
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The acceleration, expressed as a fraction, is a multiplier for movement.
+For example,
+specifying 3/1 means that the device moves three times as fast as normal.
+The fraction may be rounded arbitrarily by the X server.
+Acceleration takes effect only if the device moves more than threshold pixels at
+once and applies only to the amount beyond the value in the threshold argument.
+Setting a value to -1 restores the default.
+The values of the accelNumerator and threshold fields must be nonzero for
+the pointer values to be set.
+Otherwise, the parameters will be unchanged.
+Negative values generate a
+<function>BadValue</function>
+error, as does a zero value
+for the accelDenominator field.
+</para>
+<para>
+<!-- .LP -->
+This request fails with a
+<function>BadMatch</function>
+error if the specified device is not currently reporting relative motion.
+If a device that is capable of reporting both relative and absolute motion
+has its mode changed from
+<function>Relative</function>
+to
+<function>Absolute</function>
+by an
+<function>XSetDeviceMode</function>
+request, valuator control values
+will be ignored by the server while the device is in that mode.
+</para>
+<para>
+<!-- .LP -->
+Feedback class
+<function>IntegerFeedback</function>
+controls integer feedbacks displayed on input devices and are
+reported via the
+<function>IntegerFeedbackControl</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int int_to_display;
+} XIntegerFeedbackControl;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Valid masks are as follows:
+<!-- .sM -->
+</para>
+
+<literallayout class="monospaced">
+
+#define DvInteger (1L&lt;&lt;0)
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Feedback class
+<function>StringFeedback</function>
+controls string feedbacks displayed on input devices
+and reported via the
+<function>StringFeedbackControl</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int num_keysyms;
+ KeySym *syms_to_display;
+} XStringFeedbackControl;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Valid masks are as follows:
+<!-- .sM -->
+</para>
+<literallayout class="monospaced">
+
+#define DvString (1L&lt;&lt;0)
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Feedback class
+<function>BellFeedback</function>
+controls a bell on an input device and is reported via the
+<function>BellFeedbackControl</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int percent;
+ int pitch;
+ int duration;
+} XBellFeedbackControl;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Valid masks are as follows:
+<!-- .sM -->
+</para>
+
+
+<literallayout class="monospaced">
+
+#define DvPercent (1L&lt;&lt;1)
+#define DvPitch (1L&lt;&lt;2)
+#define DvDuration (1L&lt;&lt;3)
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Feedback class
+<function>LedFeedback</function>
+controls lights on an input device and are reported via the
+<function>LedFeedbackControl</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int led_mask;
+ int led_values;
+} XLedFeedbackControl;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Valid masks are as follows:
+<!-- .sM -->
+</para>
+
+<literallayout class="monospaced">
+
+#define DvLed (1L&lt;&lt;4)
+#define DvLedMode (1L&lt;&lt;5)
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XChangeFeedbackControl</function>
+can generate
+<function>BadDevice ,</function>
+<function>BadFeedBack ,</function>
+<function>BadMatch ,</function>
+and
+<function>BadValue</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Ringing_a_Bell_on_an_Input_Device">
+<title>Ringing a Bell on an Input Device</title>
+<!-- .XS -->
+<!-- (SN Ringing a Bell on an Input Device -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To ring a bell on an extension input device, use
+<function>XDeviceBell .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XDeviceBell</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>XIDfeedbackclass,<parameter> feedbackid</parameter></paramdef>
+ <paramdef>int<parameter> percent</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>feedbackclass</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the feedbackclass. Valid values are
+<function>KbdFeedbackClass</function>
+and
+<function>BellFeedbackClass .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>feedbackid</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ID of the feedback that has the bell.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>percent</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the volume in the range -100 (quiet) to 100 percent (loud).
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XDeviceBell</function>
+is analogous to the core
+<function>XBell</function>
+function. 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
+<function>BadValue</function>
+error results.
+The volume at which the bell rings when the percent argument is nonnegative is:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+ base - [(base * percent) / 100] + percent
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The volume at which the bell rings
+when the percent argument is negative is:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+ base + [(base * percent) / 100]
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+To change the base volume of the bell, use
+<function>XChangeFeedbackControl .</function>
+</para>
+<para>
+<!-- .LP -->
+<function>XDeviceBell</function>
+can generate
+<function>BadDevice</function>
+and
+<function>BadValue</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Controlling_Device_Encoding">
+<title>Controlling Device Encoding</title>
+<!-- .XS -->
+<!-- (SN Controlling Device Encoding -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To get the key mapping of an extension device that supports input class
+<function>Keys ,</function>
+use
+<function>XGetDeviceKeyMapping .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>KeySym * <function> XGetDeviceKeyMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>KeyCode<parameter> first_keycode_wanted</parameter></paramdef>
+ <paramdef>int<parameter> keycode_count</parameter></paramdef>
+ <paramdef>int<parameter> *keysyms_per_keycode_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>first_keycode_wanted</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the first keycode that is to be returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keycode_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of keycodes that are to be returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysyms_per_keycode_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of keysyms per keycode.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetDeviceKeyMapping </function>
+is analogous to the core
+<function>XGetKeyboardMapping</function>
+function.
+It returns the symbols for the specified number of keycodes for the
+specified extension device.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetDeviceKeyMapping </function>
+returns the symbols for the
+specified number of keycodes for the
+specified extension device, starting with the specified keycode.
+The first_keycode_wanted must be greater than or equal to
+min-keycode as returned
+by the
+<function>XListInputDevices</function>
+request (else a
+<function>BadValue</function>
+error results). The following value:
+<literallayout class="monospaced">
+first_keycode_wanted + keycode_count - 1
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+must be less than or equal to max-keycode as returned
+by the
+<function>XListInputDevices</function>
+request (else a
+<function>BadValue</function>
+error results).
+</para>
+<para>
+<!-- .LP -->
+The number of elements in the keysyms list is as follows:
+<literallayout class="monospaced">
+keycode_count * keysyms_per_keycode_return
+</literallayout>
+And KEYSYM number N (counting from zero) for keycode K has an index
+(counting from zero), in keysyms, of the following:
+<literallayout class="monospaced">
+(K - first_keycode_wanted) * keysyms_per_keycode_return + N
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The keysyms_per_keycode_return value is chosen arbitrarily by the server
+to be large enough to report all requested symbols.
+A special KEYSYM value of
+<function>NoSymbol</function>
+is used to fill in unused elements for individual keycodes.
+</para>
+<para>
+<!-- .LP -->
+To free the data returned by this function, use
+<function>XFree .</function>
+</para>
+<para>
+<!-- .LP -->
+If the specified device has not first been opened by this client via
+<function>XOpenDevice ,</function>
+this request will fail with a
+<function>BadDevice</function>
+error.
+If that device does not support input class
+<function>Keys ,</function>
+this request will fail with a
+<function>BadMatch</function>
+error.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetDeviceKeyMapping </function>
+can generate
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+and
+<function>BadValue</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To change the keyboard mapping of an extension device that supports input class
+<function>Keys ,</function>
+use
+<function>XChangeDeviceKeyMapping .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XChangeDeviceKeyMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>int<parameter> first_keycode</parameter></paramdef>
+ <paramdef>int<parameter> keysyms_per_keycode</parameter></paramdef>
+ <paramdef>KeySym<parameter> *keysyms</parameter></paramdef>
+ <paramdef>int<parameter> num_codes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>first_keycode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the first keycode that is to be changed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysyms_per_keycode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the keysyms that are to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysyms</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to an array of keysyms.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_codes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of keycodes that are to be changed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XChangeDeviceKeyMapping</function>
+is analogous to the core
+<function>XChangeKeyboardMapping</function>
+function.
+It defines the symbols for the specified number of keycodes for the
+specified extension keyboard device.
+</para>
+<para>
+<!-- .LP -->
+If the specified device has not first been opened by this client via
+<function>XOpenDevice ,</function>
+this request will fail with a
+<function>BadDevice</function>
+error.
+If the specified device does not support input class
+<function>Keys ,</function>
+this request will fail with a
+<function>BadMatch</function>
+error.
+</para>
+<para>
+<!-- .LP -->
+The number of elements in the keysyms list must be a multiple of
+keysyms_per_keycode. Otherwise,
+<function>XChangeDeviceKeyMapping</function>
+generates a
+<function>BadLength</function>
+error.
+The specified first_keycode must be greater than or equal to
+the min_keycode value returned by the
+<function>ListInputDevices</function>
+request, or this request will fail with a
+<function>BadValue</function>
+error. In addition, if the following expression is not less than
+the max_keycode value returned by the
+<function>ListInputDevices</function>
+request, the request will fail with a
+<function>BadValue</function>
+error:
+<literallayout class="monospaced">
+ first_keycode + (num_codes / keysyms_per_keycode) - 1
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeDeviceKeyMapping</function>
+can generate
+<function>BadAlloc ,</function>
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+and
+<function>BadValue</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the keycodes that are used as modifiers on an
+extension device that supports input class
+<function>Keys ,</function>
+use
+<function>XGetDeviceModifierMapping .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>XModifierKeymap * <function> XGetDeviceModifierMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetDeviceModifierMapping</function>
+is analogous to the core
+<function>XGetModifierMapping</function>
+function.
+The
+<function>XGetDeviceModifierMapping</function>
+function returns a newly created
+<function>XModifierKeymap</function>
+structure that contains the keys being used as
+modifiers for the specified device.
+The structure should be freed after use with
+<function>XFreeModifierMapping .</function>
+If only zero values appear in the set for any modifier,
+that modifier is disabled.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetDeviceModifierMapping</function>
+can generate
+<function>BadDevice</function>
+and
+<function>BadMatch</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set which keycodes are to be used as modifiers for an extension device, use
+<function>XSetDeviceModifierMapping .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XSetDeviceModifierMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>XModifierKeymap<parameter> *modmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the
+<function>XModifierKeymap</function>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetDeviceModifierMapping</function>
+is analogous to the core
+<function>XSetModifierMapping</function>
+function.
+The
+<function>XSetDeviceModifierMapping</function>
+function specifies the keycodes of the keys, if any,
+that are to be used as modifiers. A zero value means
+that no key should be used. No two arguments can have the same nonzero
+keycode value. Otherwise,
+<function>XSetDeviceModifierMapping</function>
+generates a
+<function>BadValue</function>
+error.
+There are eight modifiers, and the modifiermap member of the
+<function>XModifierKeymap</function>
+structure contains eight sets of max_keypermod
+keycodes, one for each modifier in the order
+<function>Shift ,</function>
+<function>Lock ,</function>
+<function>Control ,</function>
+<function>Mod1 ,</function>
+<function>Mod2 ,</function>
+<function>Mod3 ,</function>
+<function>Mod4 ,</function>
+and
+<function>Mod5 .</function>
+Only nonzero keycodes have meaning in each set, and zero keycodes
+are ignored.
+In addition, all of the nonzero keycodes must be in the range specified by
+min_keycode and max_keycode reported by the
+<function>XListInputDevices</function>
+function.
+Otherwise,
+<function>XSetModifierMapping</function>
+generates a
+<function>BadValue</function>
+error.
+No keycode may appear twice in the entire map.
+Otherwise, it generates a
+<function>BadValue</function>
+error.
+</para>
+<para>
+<!-- .LP -->
+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
+<function>MappingFailed ,</function>
+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
+<function>MappingBusy , </function>
+and none of the modifiers are changed.
+<function>XSetModifierMapping</function>
+generates a
+<function>DeviceMappingNotify</function>
+event on a
+<function>MappingSuccess</function>
+status.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetDeviceModifierMapping</function>
+can generate
+<function>BadAlloc ,</function>
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+and
+<function>BadValue</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Controlling_Button_Mapping">
+<title>Controlling Button Mapping</title>
+<!-- .XS -->
+<!-- (SN Controlling Button Mapping -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To set the mapping of the buttons on an extension device, use
+<function>XSetDeviceButtonMapping .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XSetDeviceButtonMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>unsignedchar<parameter> map[]</parameter></paramdef>
+ <paramdef>int<parameter> nmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>map</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mapping list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of items in the mapping list.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetDeviceButtonMapping</function>
+sets the mapping of the buttons on an extension device.
+If it succeeds, the X server generates a
+<function>DeviceMappingNotify</function>
+event, and
+<function>XSetDeviceButtonMapping</function>
+returns
+<function>MappingSuccess .</function>
+Elements of the list are indexed starting from one.
+The length of the list must be the same as
+<function>XGetDeviceButtonMapping</function>
+would return, or a
+<function>BadValue</function>
+error results.
+The index is a button number, and the element of the list
+defines the effective number.
+A zero element disables a button, and elements are not restricted in
+value by the number of physical buttons.
+However, no two elements can have the same nonzero value, or a
+<function>BadValue</function>
+error results.
+If any of the buttons to be altered are logically in the down state,
+<function>XSetDeviceButtonMapping</function>
+returns
+<function>MappingBusy ,</function>
+and the mapping is not changed.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetDeviceButtonMapping</function>
+can generate
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+and
+<function>BadValue</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To get the button mapping, use
+<function>XGetDeviceButtonMapping .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XGetDeviceButtonMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>unsignedchar<parameter> map_return[]</parameter></paramdef>
+ <paramdef>int<parameter> nmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>map_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mapping list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of items in the mapping list.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetDeviceButtonMapping</function>
+returns the current mapping of the specified extension device.
+Elements of the list are indexed starting from one.
+<function>XGetDeviceButtonMapping</function>
+returns the number of physical buttons actually on the pointer.
+The nominal mapping for the buttons is the identity mapping: map[i]=i.
+The nmap argument specifies the length of the array where the button
+mapping is returned, and only the first nmap elements are returned
+in map_return.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetDeviceButtonMapping</function>
+can generate
+<function>BadDevice</function>
+and
+<function>BadMatch</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Obtaining_the_State_of_a_Device">
+<title>Obtaining the State of a Device</title>
+<!-- .XS -->
+<!-- (SN Obtaining the State of a Device -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To obtain information that describes the state of the keys, buttons, and
+valuators of an extension device, use
+<function>XQueryDeviceState .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>XDeviceState * <function> XQueryDeviceState</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XQueryDeviceState</function>
+returns a pointer to an
+<function>XDeviceState</function>
+structure, which points to a list of
+structures that describe the state of the keys, buttons, and valuators
+on the device:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID device_id;
+ int num_classes;
+ XInputClass *data;
+} XDeviceState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The structures are of variable length, but the first
+two members are common to all and are as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+} XInputClass;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The class member contains a class identifier. This identifier can be
+compared with constants defined in the file
+<function>&lt; X11/extensions/XI.h &gt;.</function>
+Currently defined constants are:
+<function>KeyClass ,</function>
+<function>ButtonClass ,</function>
+and
+<function>ValuatorClass .</function>
+</para>
+<para>
+<!-- .LP -->
+The length member contains the length of the structure and can be used
+by clients to traverse the list.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XValuatorState</function>
+structure describes the current state of the valuators
+on the device.
+The num_valuators member contains the number of valuators
+on the device.
+The mode member is a mask whose bits report the data mode
+and other state information for the device.
+The following bits are currently defined:
+<literallayout class="monospaced">
+<!-- .TA .5i 1.5i 2.5i -->
+<!-- .ta .5i 1.5i 2.5i -->
+ DeviceMode 1 &lt;&lt; 0 Relative = 0, Absolute = 1
+ ProximityState 1 &lt;&lt; 1 InProximity = 0, OutOfProximity = 1
+</literallayout>
+The valuators member contains a pointer to an array of integers that
+describe the current value of the valuators.
+If the mode is
+<function>Relative ,</function>
+these values are undefined.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ unsigned char num_valuators;
+ unsigned char mode;
+ int *valuators;
+} XValuatorState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XKeyState</function>
+structure describes the current state of the keys
+on the device. Byte N (from 0) contains the
+bits for key 8N to 8N + 7 with the least significant bit in the
+byte representing key 8N.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ short num_keys;
+ char keys[32];
+} XKeyState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XButtonState</function>
+structure describes the current state of the buttons
+on the device. Byte N (from 0) contains the bits for button 8N to 8N + 7
+with the least significant bit in the
+byte representing button 8N.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ short num_buttons;
+ char buttons[32];
+} XButtonState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XQueryDeviceState</function>
+can generate
+<function>BadDevice</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To free the data returned by this function, use
+<function>XFreeDeviceState .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>void <function> XFreeDeviceState</function></funcdef>
+ <paramdef>XDeviceState<parameter> *state</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>state</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pointer to the
+<function>XDeviceState</function>
+data returned by a previous call to
+<function>XQueryDeviceState .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XFreeDeviceState</function>
+frees the device state data.
+</para>
+</sect3>
+</sect2>
+<sect2 id="Events">
+<title>Events</title>
+<!-- .XS -->
+<!-- (SN Events -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+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.
+The remainder of this section discusses the following X Input Extension
+event topics:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Event types
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Event classes
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Event structures
+ </para>
+ </listitem>
+</itemizedlist>
+<sect3 id="Event_Types">
+<title>Event Types</title>
+<!-- .XS -->
+<!-- (SN Event Types -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Event types are integer numbers that a client can use to determine what
+kind of event it has received. The client compares the type field of
+the event structure with known event types to make this determination.
+</para>
+<para>
+<!-- .LP -->
+The core input event types are constants and are defined in the header file
+<function>&lt; X11/X.h &gt;.</function>
+Extension event types are not constants. Instead, they
+are dynamically allocated by the extension's request to the X server
+when the extension is initialized. Because of this, extension event
+types must be obtained by the client from the server.
+</para>
+<para>
+<!-- .LP -->
+The client program determines the event type for an extension event by using
+the information returned by the
+<function>XOpenDevice</function>
+request.
+This type can then be used for comparison with the type field
+of events received by the client.
+</para>
+<para>
+<!-- .LP -->
+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>
+<!-- .LP -->
+The following table lists the event category and its associated event
+type or types.
+</para>
+
+<informaltable>
+ <tgroup cols='2' align='center'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry>Event Category</entry>
+ <entry>Event Type</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Device key</entry>
+ <entry><function>DeviceKeyPress</function></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><function>DeviceKeyRelease</function></entry>
+ </row>
+ <row>
+ <entry>Device motion</entry>
+ <entry><function>DeviceButtonPress</function></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><function>DeviceButtonRelease</function></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><function>DeviceMotionNotify</function></entry>
+ </row>
+ <row>
+ <entry>Device input focus</entry>
+ <entry><function>DeviceFocusIn</function></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><function>DeviceFocusOut</function></entry>
+ </row>
+ <row>
+ <entry>Device state notification</entry>
+ <entry><function>DeviceStateNotify</function></entry>
+ </row>
+ <row>
+ <entry>Device proximity</entry>
+ <entry><function>ProximityIn</function></entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><function>ProximityOut</function></entry>
+ </row>
+ <row>
+ <entry>Device mapping</entry>
+ <entry><function>DeviceMappingNotify</function></entry>
+ </row>
+ <row>
+ <entry>Device change</entry>
+ <entry><function>ChangeDeviceNotify</function></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+</sect3>
+<sect3 id="Event_Classes">
+<title>Event Classes</title>
+<!-- .XS -->
+<!-- (SN Event Classes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Event classes are integer numbers that are used in the same way as the
+core event masks. They are used by a client program to indicate to the
+server which events that client program wishes to receive.
+</para>
+<para>
+<!-- .LP -->
+The core input event masks are constants and are defined in the header file
+<function>&lt; X11/X.h &gt;.</function>
+Extension event classes are not constants. Instead, they are dynamically
+allocated by the extension's request to the X server
+when the extension is initialized. Because of this, extension event
+classes must be obtained by the client from the server.
+</para>
+<para>
+<!-- .LP -->
+The event class for an extension event and device is obtained from
+information returned by the
+<function>XOpenDevice</function>
+function.
+This class can then be used in an
+<function>XSelectExtensionEvent</function>
+request to ask that events of that type from that device be sent to
+the client program.
+</para>
+<para>
+<!-- .LP -->
+For
+<function>DeviceButtonPress</function>
+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
+<function>DeviceButtonRelease</function>
+event for each
+<function>DeviceButtonPress</function>
+event it receives, it should specify the
+<function>DeviceButtonPressGrab</function>
+class in addition to the
+<function>DeviceButtonPress</function>
+class.
+This restricts the client in that only one client at a time
+may request
+<function>DeviceButtonPress</function>
+events from the same device and
+window if any client specifies this class.
+</para>
+<para>
+<!-- .LP -->
+If any client has specified the
+<function>DeviceButtonPressGrab</function>
+class, any requests by any other client that specify the same device
+and window and specify either
+<function>DeviceButtonPress</function>
+or
+<function>DeviceButtonPressGrab</function>
+will cause an
+<function>Access</function>
+error to be generated.
+</para>
+<para>
+<!-- .LP -->
+If only the
+<function>DeviceButtonPress</function>
+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>
+<!-- .LP -->
+The client may also select
+<function>DeviceMotion</function>
+events only when a button is down.
+It does this by specifying the event classes
+<function>DeviceButton1Motion</function>
+through
+<function>DeviceButton5Motion . </function>
+An input device will support only
+as many button motion classes as it has buttons.
+</para>
+</sect3>
+<sect3 id="Event_Structures">
+<title>Event Structures</title>
+<!-- .XS -->
+<!-- (SN Event Structures -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Each extension event type has a corresponding structure declared in
+<function>&lt; X11/extensions/XInput.h &gt;.</function>
+All event structures have the following common members:
+<variablelist>
+ <varlistentry>
+ <term>
+ type
+ </term>
+ <listitem>
+ <para>
+Set to the event type number that uniquely identifies it. For example,
+when the X server reports a
+<function>DeviceKeyPress</function>
+event to a client application, it sends an
+<function>XDeviceKeyPressEvent</function>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ serial
+ </term>
+ <listitem>
+ <para>
+Set from the serial number reported in the protocol but expanded from the
+16-bit least significant bits to a full 32-bit value.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ send_event
+ </term>
+ <listitem>
+ <para>
+Set to
+<function>True</function>
+if the event came from an
+<function>XSendEvent</function>
+request.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ display
+ </term>
+ <listitem>
+ <para>
+Set to a pointer to a structure that defines the display
+on which the event was read.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+Extension event structures report the current position of the X pointer.
+In addition, if the device reports motion data and is reporting absolute data,
+the current value of any valuators the device contains is also reported.
+</para>
+<sect4 id="Device_Key_Events">
+<title>Device Key Events</title>
+<!-- .XS -->
+<!-- (SN Device Key Events -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Key events from extension devices contain all the information that is
+contained in a key event from the X keyboard. In addition, they contain
+a device ID and report the current value of any valuators on the device,
+if that device is reporting absolute data.
+If data for more than six valuators is being reported, more than one
+key event will be sent.
+The axes_count member contains the number of axes that are being
+reported. The server sends as many of these events as are
+needed to report the device data. Each event contains the total number
+of axes reported in the axes_count member and the first axis reported
+in the current event in the first_axis member.
+If the device supports input class
+<function>Valuators , </function>
+but is not reporting absolute mode data,
+the axes_count member contains zero (0).
+</para>
+<para>
+<!-- .LP -->
+The location reported in
+the x, y and x_root, y_root members is the location of the core X pointer.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XDeviceKeyEvent</function>
+structure is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed */
+ Bool send_event; /* true if from SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window reported relative to */
+ XID deviceid;
+ Window root; /* root window event occurred on */
+ Window subwindow; /* child window */
+ Time time; /* milliseconds */
+ int x, y; /* x, y coordinates in event window */
+ int x_root; /* coordinates relative to root */
+ int y_root; /* coordinates relative to root */
+ unsigned int state; /* key or button mask */
+ unsigned int keycode; /* detail */
+ Bool same_screen; /* same screen flag */
+ unsigned int device_state; /* device key or button mask */
+ unsigned char axes_count;
+ unsigned char first_axis;
+ int axis_data[6];
+} XDeviceKeyEvent;
+
+typedef XDeviceKeyEvent XDeviceKeyPressedEvent;
+typedef XDeviceKeyEvent XDeviceKeyReleasedEvent;
+</literallayout>
+<!-- .eM -->
+</para>
+</sect4>
+<sect4 id="Device_Button_Events">
+<title>Device Button Events</title>
+<!-- .XS -->
+<!-- (SN Device Button Events -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Button events from extension devices contain all the information that is
+contained in a button event from the X pointer. In addition, they contain
+a device ID and report the current value of any valuators on the device
+if that device is reporting absolute data.
+If data for more than six valuators is being reported, more than one
+button event may be sent.
+The axes_count member contains the number of axes that are being
+reported. The server sends as many of these events as are
+needed to report the device data. Each event contains the total number
+of axes reported in the axes_count member and the first axis reported
+in the current event in the first_axis member.
+If the device supports input class
+<function>Valuators , </function>
+but is not reporting absolute mode data,
+the axes_count member contains zero (0).
+</para>
+<para>
+<!-- .LP -->
+The location reported in
+the x, y and x_root, y_root members is the location of the core X pointer.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window reported relative to */
+ XID deviceid;
+ Window root; /* root window that the event occurred on */
+ Window subwindow; /* child window */
+ Time time; /* milliseconds */
+ int x, y; /* x, y coordinates in event window */
+ int x_root; /* coordinates relative to root */
+ int y_root; /* coordinates relative to root */
+ unsigned int state; /* key or button mask */
+ unsigned int button; /* detail */
+ Bool same_screen; /* same screen flag */
+ unsigned int device_state; /* device key or button mask */
+ unsigned char axes_count;
+ unsigned char first_axis;
+ int axis_data[6];
+} XDeviceButtonEvent;
+
+typedef XDeviceButtonEvent XDeviceButtonPressedEvent;
+typedef XDeviceButtonEvent XDeviceButtonReleasedEvent;
+</literallayout>
+<!-- .eM -->
+</para>
+</sect4>
+<sect4 id="Device_Motion_Events">
+<title>Device Motion Events</title>
+<!-- .XS -->
+<!-- (SN Device Motion Events -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Motion events from extension devices contain all the information that is
+contained in a motion event from the X pointer. In addition, they contain
+a device ID and report the current value of any valuators on the device.
+</para>
+<para>
+<!-- .LP -->
+The location reported in
+the x, y and x_root, y_root members is the location of the core X pointer,
+and so is 2-dimensional.
+</para>
+<para>
+<!-- .LP -->
+Extension motion devices may report motion data for a variable number of
+axes.
+The axes_count member contains the number of axes that are being
+reported. The server sends as many of these events as are
+needed to report the device data. Each event contains the total number
+of axes reported in the axes_count member and the first axis reported
+in the current event in the first_axis member.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window reported relative to */
+ XID deviceid;
+ Window root; /* root window that the event occurred on */
+ Window subwindow; /* child window */
+ Time time; /* milliseconds */
+ int x, y; /* x, y coordinates in event window */
+ int x_root; /* coordinates relative to root */
+ int y_root; /* coordinates relative to root */
+ unsigned int state; /* key or button mask */
+ char is_hint; /* detail */
+ Bool same_screen; /* same screen flag */
+ unsigned int device_state; /* device key or button mask */
+ unsigned char axes_count;
+ unsigned char first_axis;
+ int axis_data[6];
+} XDeviceMotionEvent;
+</literallayout>
+<!-- .eM -->
+</para>
+</sect4>
+<sect4 id="Device_Focus_Events">
+<title>Device Focus Events</title>
+<!-- .XS -->
+<!-- (SN Device Focus Events -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+These events are equivalent to the core focus events.
+They contain the same information, with the addition
+of a device ID to identify which device has had a focus change,
+and a timestamp.
+</para>
+<para>
+<!-- .LP -->
+<function>DeviceFocusIn</function>
+and
+<function>DeviceFocusOut</function>
+events are generated for
+focus changes of extension devices in the same manner as core focus
+events are generated.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window it is reported relative to */
+ XID deviceid;
+ int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */
+ int detail;
+ /*
+ * NotifyAncestor, NotifyVirtual, NotifyInferior,
+ * NotifyNonLinear,NotifyNonLinearVirtual, NotifyPointer,
+ * NotifyPointerRoot, NotifyDetailNone
+ */
+ Time time;
+} XDeviceFocusChangeEvent;
+
+typedef XDeviceFocusChangeEvent XDeviceFocusInEvent;
+typedef XDeviceFocusChangeEvent XDeviceFocusOutEvent;
+</literallayout>
+<!-- .eM -->
+</para>
+</sect4>
+<sect4 id="Device_StateNotify_Event">
+<title>Device StateNotify Event</title>
+<!-- .XS -->
+<!-- (SN Device StateNotify Event -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This event is analogous to the core keymap event but
+reports the current state of the device for each
+input class that it supports.
+It is generated after every
+<function>DeviceFocusIn</function>
+event and
+<function>EnterNotify</function>
+event and is delivered to clients who have selected
+<function>XDeviceStateNotify</function>
+events.
+</para>
+<para>
+<!-- .LP -->
+If the device supports input class
+<function>Valuators ,</function>
+the mode member in the
+<function>XValuatorStatus</function>
+structure is a bitmask that reports the device mode,
+proximity state, and other state information.
+The following bits are currently defined:
+<literallayout class="monospaced">
+<!-- .TA .5i 1.5i -->
+<!-- .ta .5i 1.5i -->
+ 0x01 Relative = 0, Absolute = 1
+ 0x02 InProximity = 0, OutOfProximity = 1
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+If the device supports more valuators than can be reported in a single
+<function>XEvent ,</function>
+multiple
+<function>XDeviceStateNotify</function>
+events will be generated.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+} XInputClass;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ XID deviceid;
+ Time time;
+ int num_classes;
+ char data[64];
+} XDeviceStateNotifyEvent;
+
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ unsigned char num_valuators;
+ unsigned char mode;
+ int valuators[6];
+} XValuatorStatus;
+
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ short num_keys;
+ char keys[32];
+} XKeyStatus;
+
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ short num_buttons;
+ char buttons[32];
+} XButtonStatus;
+</literallayout>
+<!-- .eM -->
+</para>
+</sect4>
+<sect4 id="Device_Mapping_Event">
+<title>Device Mapping Event</title>
+<!-- .XS -->
+<!-- (SN Device Mapping Event -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This event is equivalent to the core
+<function>MappingNotify</function>
+event.
+It notifies client programs when the mapping of keys,
+modifiers, or buttons on an extension device has changed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ int type;
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ Window window;
+ XID deviceid;
+ Time time;
+ int request;
+ int first_keycode;
+ int count;
+} XDeviceMappingEvent;
+</literallayout>
+<!-- .eM -->
+</para>
+</sect4>
+<sect4 id="ChangeDeviceNotify_Event">
+<title>ChangeDeviceNotify Event</title>
+<!-- .XS -->
+<!-- (SN ChangeDeviceNotify Event -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This event has no equivalent in the core protocol. It notifies client
+programs when one of the core devices has been changed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ int type;
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ Window window;
+ XID deviceid;
+ Time time;
+ int request;
+} XChangeDeviceNotifyEvent;
+</literallayout>
+<!-- .eM -->
+</para>
+</sect4>
+<sect4 id="Proximity_Events">
+<title>Proximity Events</title>
+<!-- .XS -->
+<!-- (SN Proximity Events -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+These events have no equivalent in the core protocol. Some input
+devices such as graphics tablets or touchscreens may send these
+events to indicate that a stylus has moved into or out of contact
+with a positional sensing surface.
+</para>
+<para>
+<!-- .LP -->
+The event contains the current value of any valuators on the device
+if that device is reporting absolute data.
+If data for more than six valuators is being reported, more than one
+proximity event may be sent.
+The axes_count member contains the number of axes that are being
+reported. The server sends as many of these events as are
+needed to report the device data. Each event contains the total number
+of axes reported in the axes_count member and the first axis reported
+in the current event in the first_axis member.
+If the device supports input class
+<function>Valuators , </function>
+but is not reporting absolute mode data,
+the axes_count member contains zero (0).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ int type; /* ProximityIn or ProximityOut */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ XID deviceid;
+ Window root;
+ Window subwindow;
+ Time time;
+ int x, y;
+ int x_root, y_root;
+ unsigned int state;
+ Bool same_screen;
+ unsigned int device_state; /* device key or button mask */
+ unsigned char axes_count;
+ unsigned char first_axis;
+ int axis_data[6];
+} XProximityNotifyEvent;
+
+typedef XProximityNotifyEvent XProximityInEvent;
+typedef XProximityNotifyEvent XProximityOutEvent;
+</literallayout>
+<!-- .eM -->
+</para>
+</sect4>
+</sect3>
+</sect2>
+<sect2 id="Event_Handling_Functions">
+<title>Event Handling Functions</title>
+<!-- .XS -->
+<!-- (SN Event Handling Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section discusses the X Input Extension
+event handling functions that allow you to:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Determine the extension version
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+List the available devices
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Enable and disable extension devices
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Change the mode of a device
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Initialize valuators on an input device
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Get input device controls
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Change input device controls
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Select extension device events
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Determine selected device events
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Control event propogation
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Send an event
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Get motion history
+ </para>
+ </listitem>
+</itemizedlist>
+<sect3 id="Determining_the_Extension_Version">
+<title>Determining the Extension Version</title>
+<!-- .XS -->
+<!-- (SN Determining the Extension Version -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>XExtensionVersion * <function> XGetExtensionVersion</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the name of the desired extension.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetExtensionVersion</function>
+allows a client to determine whether a server supports
+the desired version of the input extension.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XExtensionVersion</function>
+structure returns information about the version of the extension
+supported by the server and is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ Bool present;
+ short major_version;
+ short minor_version;
+} XExtensionVersion;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The major and minor versions can be compared with constants defined in
+the header file
+<function>&lt; X11/extensions/XI.h &gt;.</function>
+Each version is a superset of the previous versions.
+</para>
+<para>
+<!-- .LP -->
+You should use
+<function>XFree</function>
+to free the data returned by this function.
+</para>
+</sect3>
+<sect3 id="Listing_Available_Devices">
+<title>Listing Available Devices</title>
+<!-- .XS -->
+<!-- (SN Listing Available Devices -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A client program that wishes to access a specific device
+must first determine whether that device is connected to the X server. This
+is done through the
+<function>XListInputDevices</function>
+function, which will return a list of all devices that can be opened
+by the X server. The client program can use one
+of the names defined in the
+<function>&lt; X11/extensions/XI.h &gt;</function>
+header file in an
+<function>XInternAtom </function>
+request to determine the device type of the desired device. This type
+can then be compared with the device types returned by the
+<function>XListInputDevices</function>
+request.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>XDeviceInfo * <function> XListInputDevices</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> *ndevices</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ndevices</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the address of a variable into which the server
+can return the number of input devices available to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XListInputDevices</function>
+allows a client to determine which devices
+are available for X input and information about those devices.
+An array of
+<function>XDeviceInfo</function>
+structures is returned, with one element in the array for each device.
+The number of devices is returned in the ndevices argument.
+</para>
+<para>
+<!-- .LP -->
+The X pointer device and X keyboard device are reported, as well as
+all available extension input devices. The use member of the
+<function>XDeviceInfo</function>
+structure specifies the current use of the device.
+If the value of this member is
+<function>IsXPointer ,</function>
+the device is the X pointer device. If the value is
+<function>IsXKeyboard ,</function>
+the device is the X keyboard device. If the value is
+<function>IsXExtensionDevice ,</function>
+the device is available for use as an extension input device.
+</para>
+<para>
+<!-- .LP -->
+Each
+<function>XDeviceInfo</function>
+entry contains a pointer to a list of structures
+that describe the characteristics of each class
+of input supported by that device. The num_classes member
+contains the number of entries in that list.
+</para>
+<para>
+<!-- .LP -->
+If the device supports input class
+<function>Valuators ,</function>
+one of the structures pointed to by the
+<function>XDeviceInfo</function>
+structure will be an
+<function>XValuatorInfo</function>
+structure. The axes member of that structure
+contains the address of an array of
+<function>XAxisInfo</function>
+structures.
+There is one element in this array for each axis of motion
+reported by the device. The number of elements in this
+array is contained in the num_axes element of the
+<function>XValuatorInfo</function>
+structure.
+The size of the motion buffer for the device is
+reported in the motion_buffer member of the
+<function>XValuatorInfo</function>
+structure.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XDeviceInfo</function>
+structure is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct _XDeviceInfo {
+ XID id;
+ Atom type;
+ char *name;
+ int num_classes;
+ int use;
+ XAnyClassPtr inputclassinfo;
+} XDeviceInfo;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The structures pointed to by the
+<function>XDeviceInfo</function>
+structure are defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct _XKeyInfo {
+ XID class;
+ int length;
+ unsigned short min_keycode;
+ unsigned short max_keycode;
+ unsigned short num_keys;
+} XKeyInfo;
+
+typedef struct _XButtonInfo {
+ XID class;
+ int length;
+ short num_buttons;
+} XButtonInfo;
+
+typedef struct _XValuatorInfo {
+ XID class;
+ int length;
+ unsigned char num_axes;
+ unsigned char mode;
+ unsigned long motion_buffer;
+ XAxisInfoPtr axes;
+} XValuatorInfo;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAxisInfo</function>
+structure pointed to by the
+<function>XValuatorInfo</function>
+structure is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct _XAxisInfo {
+ int resolution;
+ int min_value;
+ int max_value;
+} XAxisInfo;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The following atom names are defined in the
+<function>&lt; X11/extensions/XI.h &gt;</function>
+header file.
+<literallayout class="monospaced">
+<!-- .TA 2i -->
+<!-- .ta 2i -->
+MOUSE QUADRATURE
+TABLET SPACEBALL
+KEYBOARD DATAGLOVE
+TOUCHSCREEN EYETRACKER
+TOUCHPAD CURSORKEYS
+BUTTONBOX FOOTMOUSE
+BARCODE ID_MODULE
+KNOB_BOX ONE_KNOB
+TRACKBALL NINE_KNOB\s+1
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+These names can be used in an
+<function>XInternAtom</function>
+request to return an atom that can be used for comparison
+with the type member of the
+<function>XDeviceInfo</function>
+structure.
+</para>
+<para>
+<!-- .LP -->
+<function>XListInputDevices</function>
+returns NULL if there are no input devices to list.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To free the data returned by
+<function>XListInputDevices ,</function>
+use
+<function>XFreeDeviceList .</function>
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>void <function> XFreeDeviceList</function></funcdef>
+ <paramdef>XDeviceInfo<parameter> *list</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pointer to the
+<function>XDeviceInfo</function>
+array returned by a previous call to
+<function>XListInputDevices .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XFreeDeviceList</function>
+frees the list of input device information.
+</para>
+</sect3>
+<sect3 id="Enabling_and_Disabling_Extension_Devices">
+<title>Enabling and Disabling Extension Devices</title>
+<!-- .XS -->
+<!-- (SN Enabling and Disabling Extension Devices -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Each client program that wishes to access an extension device must request
+that the server open that device by calling the
+<function>XOpenDevice</function>
+function.
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>XDevice * <function> XOpenDevice</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XID<parameter> device_id</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device_id</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ID that uniquely identifies the device to be opened.
+This ID is obtained from the
+<function>XListInputDevices</function>
+request.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XOpenDevice</function>
+opens the device for the requesting client and, on success, returns an
+<function>XDevice</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID device_id;
+ int num_classes;
+ XInputClassInfo *classes;
+} XDevice;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDevice</function>
+structure contains a pointer to an array of
+<function>XInputClassInfo</function>
+structures. Each element in that array
+contains information about events of a particular input class supported
+by the input device.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XInputClassInfo</function>
+structure is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ unsigned char input_class;
+ unsigned char event_type_base;
+} XInputClassInfo;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+A client program can determine the event
+type and event class for a given event by using macros defined by the
+input extension. The name of the macro corresponds to the desired event,
+and the macro is passed the structure that describes the device from which
+input is desired, for example:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+ DeviceKeyPress(XDevice *device, event_type, event_class)
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The macro will fill in the values of the event class to be used in an
+<function>XSelectExtensionEvent</function>
+request to select the event and the event type to be used in comparing
+with the event types of events received via
+<function>XNextEvent .</function>
+</para>
+<para>
+<!-- .LP -->
+<function>XOpenDevice</function>
+can generate
+<function>BadDevice</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+Before terminating, the client program should request that the server close
+the device by calling the
+<function>XCloseDevice</function>
+function.
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XCloseDevice</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device to be closed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XCloseDevice</function>
+closes the device for the requesting client and frees the associated
+<function>XDevice</function>
+structure.
+</para>
+<para>
+<!-- .LP -->
+A client may open the same extension device more than once. Requests
+after the first successful one return an additional
+<function>XDevice</function>
+structure
+with the same information as the first, but otherwise have no effect.
+A single
+<function>XCloseDevice</function>
+request will terminate that client's access to the device.
+</para>
+<para>
+<!-- .LP -->
+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, any queued events are released.
+</para>
+<para>
+<!-- .LP -->
+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>
+<!-- .LP -->
+<function>XCloseDevice</function>
+can generate
+<function>BadDevice</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Changing_the_Mode_of_a_Device">
+<title>Changing the Mode of a Device</title>
+<!-- .XS -->
+<!-- (SN Changing the Mode of a Device -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Some devices are capable of reporting either relative or absolute motion
+data.
+To change the mode of a device from relative to absolute, use
+<function>XSetDeviceMode .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XSetDeviceMode</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>int<parameter> mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device whose mode should be changed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mode. You can pass
+<function>Absolute</function>
+or
+<function>Relative .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetDeviceMode</function>
+allows a client to request the server to change the mode of a
+device that is capable of reporting either absolute positional data or relative
+motion data. If the device is invalid or if the client has not previously
+requested that the server open the device via an
+<function>XOpenDevice</function>
+request, this request will fail with a
+<function>BadDevice</function>
+error.
+If the device does not support input class
+<function>Valuators</function>
+or if it is not capable of reporting the specified mode,
+the request will fail with a
+<function>BadMatch</function>
+error.
+</para>
+<para>
+<!-- .LP -->
+This request will fail and return
+<function>DeviceBusy</function>
+if another client has already opened the device and requested a different mode.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetDeviceMode</function>
+can generate
+<function>BadDevice ,</function>
+<function>BadMatch ,</function>
+<function>BadMode ,</function>
+and
+<function>DeviceBusy</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Initializing_Valuators_on_an_Input_Device">
+<title>Initializing Valuators on an Input Device</title>
+<!-- .XS -->
+<!-- (SN Initializing Valuators on an Input Device -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+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
+<function>Absolute .</function>
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To initialize the valuators on such a device, use
+<function>XSetDeviceValuators .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Status <function> XSetDeviceValuators</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>int*valuators,first_valuator,<parameter> num_valuators</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device whose valuators should be initialized.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>valuators</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the values to which each valuator should be set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>first_valuator</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the first valuator to be set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_valuators</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of valuators to be set.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetDeviceValuators</function>
+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.
+A
+<function>BadValue</function>
+error results if the number of valuators supported by the device
+is less than the following expression:
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+ first_valuator + num_valuators
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+If the request succeeds,
+<function>Success</function>
+is returned. If the specified device is grabbed by some other client,
+the request will fail and a status of
+<function>AlreadyGrabbed</function>
+will be returned.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetDeviceValuators</function>
+can generate
+<function>BadDevice ,</function>
+<function>BadLength ,</function>
+<function>BadMatch ,</function>
+and
+<function>BadValue</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Getting_Input_Device_Controls">
+<title>Getting Input Device Controls</title>
+<!-- .XS -->
+<!-- (SN Getting Input Device Controls -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Some input devices support various configuration controls
+that can be queried or changed by clients. The set of supported
+controls will vary from one input device to another. Requests
+to manipulate these controls will fail if either the target
+X server or the target input device does not support the
+requested device control.
+</para>
+<para>
+<!-- .LP -->
+Each device control has a unique identifier. Information
+passed with each device control varies in length and is mapped
+by data structures unique to that device control.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To query a device control, use
+<function>XGetDeviceControl .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>XDeviceControl * <function> XGetDeviceControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>int<parameter> control</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device whose configuration control status is to be returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>control</emphasis>
+ </term>
+ <listitem>
+ <para>
+Identifies the specific device control to be queried.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetDeviceControl</function>
+returns the current state of the specified device control.
+If the target X server does not support that device control, a
+<function>BadValue</function>
+error is returned.
+If the specified device does not support that device control, a
+<function>BadMatch</function>
+error
+is returned.
+</para>
+<para>
+<!-- .LP -->
+If the request is successful, a pointer to a generic
+<function>XDeviceState</function>
+structure is returned. The information returned varies according
+to the specified control and is mapped by a structure appropriate
+for that control.
+The first two members are common to all device controls
+and are defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID control;
+ int length;
+} XDeviceState;
+\fP
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The control may be compared to constants defined in the file
+<function>&lt; X11/extensions/XI.h &gt;.</function>
+Currently defined device controls include DEVICE_RESOLUTION.
+</para>
+<para>
+<!-- .LP -->
+The information returned for the DEVICE_RESOLUTION control is
+defined in the
+<function>XDeviceResolutionState</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID control;
+ int length;
+ int num_valuators;
+ int *resolutions;
+ int *min_resolutions;
+ int *max_resolutions;
+} XDeviceResolutionState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+This device control returns a list of valuators and the range of
+valid resolutions allowed for each. Valuators are numbered
+beginning with zero (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>
+<!-- .LP -->
+When this control is specified,
+<function>XGetDeviceControl</function>
+fails with a
+<function>BadMatch</function>
+error if the specified device has no valuators.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetDeviceControl</function>
+can generate
+<function>BadMatch</function>
+and
+<function>BadValue</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Changing_Input_Device_Controls">
+<title>Changing Input Device Controls</title>
+<!-- .XS -->
+<!-- (SN Changing Input Device Controls -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Some input devices support various configuration controls
+that can be changed by clients. Typically, this would be
+done to initialize the device to a known state or configuration.
+The set of supported controls will vary from one input device
+to another. Requests to manipulate these controls will fail if
+either the target X server or the target input device does not
+support the requested device control. Setting the device control
+will also fail if the target input device is grabbed by another
+client or is open by another client and has been set to a conflicting
+state.
+</para>
+<para>
+<!-- .LP -->
+Each device control has a unique identifier. Information
+passed with each device control varies in length and is mapped
+by data structures unique to that device control.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To change a device control, use
+<function>XChangeDeviceControl .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Status <function> XChangeDeviceControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>int<parameter> control</parameter></paramdef>
+ <paramdef>XDeviceControl<parameter> *value</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device whose configuration control status is to be modified.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>control</emphasis>
+ </term>
+ <listitem>
+ <para>
+Identifies the specific device control to be changed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to an
+<function>XDeviceControl</function>
+structure that describes which control is to be changed
+and how it is to be changed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XChangeDeviceControl</function>
+changes the current state of the specified device control.
+If the target X server does not support that device control, a
+<function>BadValue</function>
+error is returned.
+If the specified device does not support that device control, a
+<function>BadMatch</function>
+error is returned.
+If another client has the target device grabbed, a status of
+<function>AlreadyGrabbed</function>
+is returned.
+If another client has the device open and has set it to a
+conflicting state, a status of
+<function>DeviceBusy</function>
+is returned.
+If the request fails for any reason, the device control will not
+be changed.
+</para>
+<para>
+<!-- .LP -->
+If the request is successful, the device control will be changed
+and a status of
+<function>Success</function>
+is returned.
+The information passed varies according to the specified control
+and is mapped by a structure appropriate for that control.
+The first two members are common to all device controls:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID control;
+ int length;
+} XDeviceControl;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The control may be set using constants defined in the
+<function>&lt; X11/extensions/XI.h &gt;</function>
+header file.
+Currently defined device controls include DEVICE_RESOLUTION.
+</para>
+<para>
+<!-- .LP -->
+The information that can be changed by the DEVICE_RESOLUTION
+control is defined in the
+<function>XDeviceResolutionControl</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ XID control;
+ int length;
+ int first_valuator;
+ int num_valuators;
+ int *resolutions;
+} XDeviceResolutionControl;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+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. The num_valuators member
+specifies the number of valuators in the resolutions list.
+</para>
+<para>
+<!-- .LP -->
+When this control is specified,
+<function>XChangeDeviceControl</function>
+fails with a
+<function>BadMatch</function>
+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
+<function>XGetDeviceControl ),</function>
+<function>XChangeDeviceControl</function>
+fails with a
+<function>BadValue</function>
+error.
+A
+<function>BadValue</function>
+error results if the number of valuators supported by the device
+is less than the following expression:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+ first_valuator + num_valuators,
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeDeviceControl</function>
+can generate
+<function>BadMatch</function>
+and
+<function>BadValue</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Selecting_Extension_Device_Events">
+<title>Selecting Extension Device Events</title>
+<!-- .XS -->
+<!-- (SN Selecting Extension Device Events -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To select device input events, use
+<function>XSelectExtensionEvent .</function>
+The parameters passed are a pointer to
+a list of classes that define the desired event types and devices, a count
+of the number of elements in the list, and the ID of the window from which
+events are desired.
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XSelectExtensionEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> window</parameter></paramdef>
+ <paramdef>XEventClass<parameter> *event_list</parameter></paramdef>
+ <paramdef>int<parameter> event_count</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ID of the window from which the client wishes to receive events.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to an array of event classes
+that specify which events are desired.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of elements in the event_list.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSelectExtensionEvent</function>
+requests the server to send events that match the events and
+devices described by the event list and that come from the requested
+window.
+The elements of the
+<function>XEventClass</function>
+array are the event_class values
+obtained by invoking a macro with the pointer to an
+<function>XDevice</function>
+structure returned by the
+<function>XOpenDevice</function>
+request.
+For example, the
+<function>DeviceKeyPress</function>
+macro would return the
+<function>XEventClass</function>
+for
+<function>DeviceKeyPress</function>
+events from the specified device if it were invoked in the following form:
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+ DeviceKeyPress (XDevice *device, event_type, event_class)
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Macros are defined for the following event classes:
+<literallayout class="monospaced">
+<function>DeviceKeyPress</function>
+<function>DeviceKeyRelease</function>
+<function>DeviceButtonPress</function>
+<function>DeviceButtonRelease</function>
+<function>DeviceMotionNotify</function>
+<function>DeviceFocusIn</function>
+<function>DeviceFocusOut</function>
+<function>ProximityIn</function>
+<function>ProximityOut</function>
+<function>DeviceStateNotify</function>
+<function>DeviceMappingNotify</function>
+<function>ChangeDeviceNotify</function>
+<function>DevicePointerMotionHint</function>
+<function>DeviceButton1Motion </function>
+<function>DeviceButton2Motion</function>
+<function>DeviceButton3Motion, </function>
+<function>DeviceButton4Motion</function>
+<function>DeviceButton5Motion</function>
+<function>DeviceButtonMotion,</function>
+<function>DeviceOwnerGrabButton</function>
+<function>DeviceButtonPressGrab</function>
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+To get the next available event from within a client program, use the core
+<function>XNextEvent</function>
+function. This returns the next event whether it
+came from a core device or an extension device.
+</para>
+<para>
+<!-- .LP -->
+Succeeding
+<function>XSelectExtensionEvent</function>
+requests using event classes
+for the same device as was specified on a previous request will replace
+the previous set of selected events from that device with the new set.
+</para>
+<para>
+<!-- .LP -->
+<function>XSelectExtensionEvent</function>
+can generate
+<function>BadAccess , </function>
+<function>BadClass ,</function>
+<function>BadLength ,</function>
+and
+<function>BadWindow</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Determining_Selected_Device_Events">
+<title>Determining Selected Device Events</title>
+<!-- .XS -->
+<!-- (SN Determining Selected Device Events -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To determine which extension events are currently selected from a given
+window, use
+<function>XGetSelectedExtensionEvents .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XGetSelectedExtensionEvents</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> window</parameter></paramdef>
+ <paramdef>int<parameter> *this_client_count</parameter></paramdef>
+ <paramdef>XEventClass<parameter> **this_client</parameter></paramdef>
+ <paramdef>int<parameter> *all_clients_count</parameter></paramdef>
+ <paramdef>XEventClass<parameter> **all_clients</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ID of the window from which the client wishes to receive events.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>this_client_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of elements in the this_client list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>this_client</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns a list of
+<function>XEventClasses</function>
+that specify which events are
+selected by this client.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>all_clients_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of elements in the all_clients list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>all_clients</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns a list of
+<function>XEventClasses</function>
+that specify which events are
+selected by all clients.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetSelectedExtensionEvents</function>
+returns pointers to two event class arrays.
+One lists the extension events selected by this client from
+the specified window. The other lists the extension events selected by
+all clients from the specified window. This information is analogous
+to that returned in your_event_mask and all_event_masks of the
+<function>XWindowAttributes</function>
+structure when an
+<function>XGetWindowAttributes</function>
+request is made.
+To free the two arrays returned by this function, use
+<function>XFree .</function>
+</para>
+<para>
+<!-- .LP -->
+<function>XGetSelectedExtensionEvents</function>
+can generate
+<function>BadWindow</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Controlling_Event_Propagation">
+<title>Controlling Event Propagation</title>
+<!-- .XS -->
+<!-- (SN Controlling Event Propagation -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+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>
+<!-- .LP -->
+Client programs may control event propagation through the use
+of the following two functions:
+<function>XChangeDeviceDontPropagateList</function>
+and
+<function>XGetDeviceDontPropagateList . </function>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XChangeDeviceDontPropagateList</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> window</parameter></paramdef>
+ <paramdef>int<parameter> event_count</parameter></paramdef>
+ <paramdef>XEventClass<parameter> *events</parameter></paramdef>
+ <paramdef>int<parameter> mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of elements in the events list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>events</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the list of XEventClasses.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mode. You can pass
+<function>AddToList</function>
+or
+<function>DeleteFromList .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XChangeDeviceDontPropagateList</function>
+adds an event to or deletes an event from the do_not_propagate list
+of extension events for the specified window.
+There is one list per window, and the list remains for the life of the window.
+The list is not altered if a client that changed the list terminates.
+</para>
+<para>
+<!-- .LP -->
+Suppression of event propagation is not allowed for all events. If a
+specified
+<function>XEventClass</function>
+is invalid because suppression of that event is not allowed, a
+<function>BadClass</function>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeDeviceDontPropagateList</function>
+can generate
+<function>BadClass ,</function>
+<function>BadMode ,</function>
+and
+<function>BadWindow</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>XEventClass * <function> XGetDeviceDontPropagateList</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> window</parameter></paramdef>
+ <paramdef>int<parameter> *event_count</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of elements in the array returned by this function.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetDeviceDontPropagateList</function>
+allows a client to determine the do_not_propagate list of extension events
+for the specified window.
+It returns an array of
+<function>XEventClass ,</function>
+each
+<function>XEventClass</function>
+representing a device/event type pair.
+To free the data returned by this function, use
+<function>XFree .</function>
+</para>
+<para>
+<!-- .LP -->
+<function>XGetDeviceDontPropagateList</function>
+can generate
+<function>BadWindow</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Sending_an_Event">
+<title>Sending an Event</title>
+<!-- .XS -->
+<!-- (SN Sending an Event -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To send an extension event to another client, use
+<function>XSendExtensionEvent .</function>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function> XSendExtensionEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>Window<parameter> window</parameter></paramdef>
+ <paramdef>Bool<parameter> propagate</parameter></paramdef>
+ <paramdef>int<parameter> event_count</parameter></paramdef>
+ <paramdef>XEventClass<parameter> *event_list</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device whose ID is recorded in the event.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the destination window ID. You can pass a window ID,
+<function>PointerWindow</function>
+or
+<function>InputFocus .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>propagate</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a boolean value that is either
+<function>True</function>
+or
+<function>False .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of elements in the event_list array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to an array of
+<function>XEventClass .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the event that is to be sent.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSendExtensionEvent</function>
+identifies the destination window, determines which clients should receive
+the specified event, and ignores any active grabs.
+It requires a list of
+<function>XEventClass</function>
+to be specified.
+These are obtained by opening an input device with the
+<function>XOpenDevice</function>
+request.
+</para>
+<para>
+<!-- .LP -->
+<function>XSendExtensionEvent</function>
+uses the window argument to identify the destination window as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If you pass
+<function>PointerWindow ,</function>
+the destination window is the window that contains the pointer.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If you pass
+<function>InputFocus</function>
+and if the focus window contains the pointer,
+the destination window is the window that contains the pointer.
+If the focus window does not contain the pointer,
+the destination window is the focus window.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+To determine which clients should receive the specified events,
+<function>XSendExtensionEvent</function>
+uses the propagate argument as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If propagate is
+<function>False ,</function>
+the event is sent to every client selecting
+from the destination window
+any of the events specified in the event_list array.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If propagate is
+<function>True </function>
+and no clients have selected from the destination window
+any of the events specified in the event_list array, the destination is
+replaced with the closest ancestor of destination for which some client
+has selected one of the specified events and for which no intervening
+window has that event in its do_not_propagate mask.
+If no such window exists,
+or if the window is an ancestor of the focus window, and
+<function>InputFocus</function>
+was originally specified as the destination,
+the event is not sent to any clients. Otherwise, the event is reported to every
+client selecting on the final destination any of the events specified
+in event_list.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The event in the
+<function>XEvent</function>
+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
+<function>True</function>
+in the forwarded event and to set the sequence number in the event correctly.
+</para>
+<para>
+<!-- .LP -->
+<function>XSendExtensionEvent</function>
+returns zero if the conversion-to-wire protocol failed;
+otherwise, it returns nonzero.
+</para>
+<para>
+<!-- .LP -->
+<function>XSendExtensionEvent</function>
+can generate
+<function>BadClass ,</function>
+<function>BadDevice ,</function>
+<function>BadValue ,</function>
+and
+<function>BadWindow</function>
+errors.
+</para>
+</sect3>
+<sect3 id="Getting_Motion_History">
+<title>Getting Motion History</title>
+<!-- .XS -->
+<!-- (SN Getting Motion History -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>XDeviceTimeCoord * <function> XGetDeviceMotionEvents</function></funcdef>
+ <paramdef><parameter> axis_count_return)</parameter></paramdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XDevice<parameter> *device</parameter></paramdef>
+ <paramdef>Timestart,<parameter> stop</parameter></paramdef>
+ <paramdef>int<parameter> *nevents_return</parameter></paramdef>
+ <paramdef>int<parameter> *mode_return</parameter></paramdef>
+ <paramdef>int<parameter> *axis_count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>device</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the desired device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>start</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the start time.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>stop</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the stop time.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nevents_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of positions in the motion buffer returned
+for this request.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the mode of the nevents information.
+The mode will be one of the following:
+<function>Absolute</function>
+or
+<function>Relative .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>axis_count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of axes reported in each of the positions returned.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XGetDeviceMotionEvents</function>
+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>
+<!-- .LP -->
+The return type for this function is an
+<function>XDeviceTimeCoord</function>
+structure, which is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ Time time;
+ unsigned int *data;
+} XDeviceTimeCoord;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The data member is a pointer to an array of data items.
+Each item is of type int, 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>
+<!-- .LP -->
+The value of the data items depends on the mode of the device.
+The mode is returned in the mode variable. If the
+mode is
+<function>Absolute ,</function>
+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 value for each axis is reported in
+the max_val member of the
+<function>XAxisInfo</function>
+structure, which is part of the information returned by the
+<function>XListInputDevices</function>
+request.
+</para>
+<para>
+<!-- .LP -->
+If the mode is
+<function>Relative ,</function>
+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>
+<para>
+<!-- .LP -->
+Consecutive calls to
+<function>XGetDeviceMotionEvents</function>
+can return data of different modes, that is, if
+some client program has changed the mode of the device via an
+<function>XSetDeviceMode</function>
+request.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetDeviceMotionEvents</function>
+can generate
+<function>BadDevice</function>
+and
+<function>BadMatch</function>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To free the data returned by
+<function>XGetDeviceMotionEvents ,</function>
+use
+<function>XFreeDeviceMotionEvents .</function>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>void <function> XFreeDeviceMotionEvents</function></funcdef>
+ <paramdef>XDeviceTimeCoord<parameter> *events</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>events</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pointer to the
+<function>XDeviceTimeCoord</function>
+array returned by a previous call to
+<function>XGetDeviceMotionEvents .</function>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XFreeDeviceMotionEvents</function>
+frees the specified array of motion information.
+<!-- .\" -->
+<!-- .\" -->
+<!-- .\" Appendicies -->
+<!-- .\" -->
+<!-- .\" -->
+<!-- .bp -->
+<!-- .ds Ch ~ -->
+<!-- .sp 1 -->
+<!-- .ce 3 -->
+<function>Appendix A</function>
+<!-- .XS -->
+<!-- (SN Appendix A -->
+<!-- .XE -->
+</para>
+<para>
+<!-- .LP -->
+The following information is contained in the <function>&lt;X11/extensions/XInput.h&gt;</function>
+and <function>&lt;X11/extensions/XI.h&gt;</function> header files:
+<literallayout class="monospaced">
+<!-- .cs CW 20 -->
+
+<!-- .ps 8 -->
+/* Definitions used by the library and client */
+
+#ifndef _XINPUT_H_
+#define _XINPUT_H_
+
+#ifndef _XLIB_H_
+#include &lt;X11/Xlib.h&gt;
+#endif
+
+#ifndef _XI_H_
+#include "XI.h"
+#endif
+
+#define _deviceKeyPress 0
+#define _deviceKeyRelease 1
+
+#define _deviceButtonPress 0
+#define _deviceButtonRelease 1
+
+#define _deviceMotionNotify 0
+
+#define _deviceFocusIn 0
+#define _deviceFocusOut 1
+
+#define _proximityIn 0
+#define _proximityOut 1
+
+#define _deviceStateNotify 0
+#define _deviceMappingNotify 1
+#define _changeDeviceNotify 2
+
+#define FindTypeAndClass(d, type, class, classid, offset) \
+ { int i; XInputClassInfo *ip; \
+ type = 0; class = 0; \
+ for (i=0, ip= ((XDevice *) d)-&gt;classes; \
+ i&lt; ((XDevice *) d)-&gt;num_classes; \
+ i++, ip++) \
+ if (ip-&gt;input_class == classid) \
+ {type = ip-&gt;event_type_base + offset; \
+ class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | type;}}
+
+#define DeviceKeyPress(d, type, class) \
+ FindTypeAndClass(d, type, class, KeyClass, _deviceKeyPress)
+
+#define DeviceKeyRelease(d, type, class) \
+ FindTypeAndClass(d, type, class, KeyClass, _deviceKeyRelease)
+
+#define DeviceButtonPress(d, type, class) \
+ FindTypeAndClass(d, type, class, ButtonClass, _deviceButtonPress)
+
+#define DeviceButtonRelease(d, type, class) \
+ FindTypeAndClass(d, type, class, ButtonClass, _deviceButtonRelease)
+
+#define DeviceMotionNotify(d, type, class) \
+ FindTypeAndClass(d, type, class, ValuatorClass, _deviceMotionNotify)
+
+#define DeviceFocusIn(d, type, class) \
+ FindTypeAndClass(d, type, class, FocusClass, _deviceFocusIn)
+
+#define DeviceFocusOut(d, type, class) \
+ FindTypeAndClass(d, type, class, FocusClass, _deviceFocusOut)
+
+#define ProximityIn(d, type, class) \
+ FindTypeAndClass(d, type, class, ProximityClass, _proximityIn)
+
+#define ProximityOut(d, type, class) \
+ FindTypeAndClass(d, type, class, ProximityClass, _proximityOut)
+
+#define DeviceStateNotify(d, type, class) \
+ FindTypeAndClass(d, type, class, OtherClass, _deviceStateNotify)
+
+#define DeviceMappingNotify(d, type, class) \
+ FindTypeAndClass(d, type, class, OtherClass, _deviceMappingNotify)
+
+#define ChangeDeviceNotify(d, type, class) \
+ FindTypeAndClass(d, type, class, OtherClass, _changeDeviceNotify)
+
+#define DevicePointerMotionHint(d, type, class) \
+ { class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | _devicePointerMotionHint;}
+
+#define DeviceButton1Motion(d, type, class) \
+ { class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | _deviceButton1Motion;}
+
+#define DeviceButton2Motion(d, type, class) \
+ { class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | _deviceButton2Motion;}
+
+#define DeviceButton3Motion(d, type, class) \
+ { class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | _deviceButton3Motion;}
+
+#define DeviceButton4Motion(d, type, class) \
+ { class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | _deviceButton4Motion;}
+
+#define DeviceButton5Motion(d, type, class) \
+ { class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | _deviceButton5Motion;}
+
+#define DeviceButtonMotion(d, type, class) \
+ { class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | _deviceButtonMotion;}
+
+#define DeviceOwnerGrabButton(d, type, class) \
+ { class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | _deviceOwnerGrabButton;}
+
+#define DeviceButtonPressGrab(d, type, class) \
+ { class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | _deviceButtonGrab;}
+
+#define NoExtensionEvent(d, type, class) \
+ { class = ((XDevice *) d)-&gt;device_id &lt;&lt; 8 | _noExtensionEvent;}
+
+#define BadDevice(dpy, error) _xibaddevice(dpy, &amp;error)
+
+#define BadClass(dpy, error) _xibadclass(dpy, &amp;error)
+
+#define BadEvent(dpy, error) _xibadevent(dpy, &amp;error)
+
+#define BadMode(dpy, error) _xibadmode(dpy, &amp;error)
+
+#define DeviceBusy(dpy, error) _xidevicebusy(dpy, &amp;error)
+
+/***************************************************************
+ *
+ * DeviceKey events. These events are sent by input devices that
+ * support input class Keys.
+ * The location of the X pointer is reported in the coordinate
+ * fields of the x,y and x_root,y_root fields.
+ *
+ */
+
+typedef struct
+ {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed */
+ Bool send_event; /* true if from SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window reported relative to */
+ XID deviceid;
+ Window root; /* root window event occured on */
+ Window subwindow; /* child window */
+ Time time; /* milliseconds */
+ int x, y; /* x, y coordinates in event window */
+ int x_root; /* coordinates relative to root */
+ int y_root; /* coordinates relative to root */
+ unsigned int state; /* key or button mask */
+ unsigned int keycode; /* detail */
+ Bool same_screen; /* same screen flag */
+ unsigned int device_state; /* device key or button mask */
+ unsigned char axes_count;
+ unsigned char first_axis;
+ int axis_data[6];
+ } XDeviceKeyEvent;
+
+typedef XDeviceKeyEvent XDeviceKeyPressedEvent;
+typedef XDeviceKeyEvent XDeviceKeyReleasedEvent;
+
+/*******************************************************************
+ *
+ * DeviceButton events. These events are sent by extension devices
+ * that support input class Buttons.
+ *
+ */
+
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window reported relative to */
+ XID deviceid;
+ Window root; /* root window that the event occured on */
+ Window subwindow; /* child window */
+ Time time; /* milliseconds */
+ int x, y; /* x, y coordinates in event window */
+ int x_root; /* coordinates relative to root */
+ int y_root; /* coordinates relative to root */
+ unsigned int state; /* key or button mask */
+ unsigned int button; /* detail */
+ Bool same_screen; /* same screen flag */
+ unsigned int device_state; /* device key or button mask */
+ unsigned char axes_count;
+ unsigned char first_axis;
+ int axis_data[6];
+ } XDeviceButtonEvent;
+
+typedef XDeviceButtonEvent XDeviceButtonPressedEvent;
+typedef XDeviceButtonEvent XDeviceButtonReleasedEvent;
+
+/*******************************************************************
+ *
+ * DeviceMotionNotify event. These events are sent by extension devices
+ * that support input class Valuators.
+ *
+ */
+
+typedef struct
+ {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window reported relative to */
+ XID deviceid;
+ Window root; /* root window that the event occured on */
+ Window subwindow; /* child window */
+ Time time; /* milliseconds */
+ int x, y; /* x, y coordinates in event window */
+ int x_root; /* coordinates relative to root */
+ int y_root; /* coordinates relative to root */
+ unsigned int state; /* key or button mask */
+ char is_hint; /* detail */
+ Bool same_screen; /* same screen flag */
+ unsigned int device_state; /* device key or button mask */
+ unsigned char axes_count;
+ unsigned char first_axis;
+ int axis_data[6];
+ } XDeviceMotionEvent;
+
+/*******************************************************************
+ *
+ * DeviceFocusChange events. These events are sent when the focus
+ * of an extension device that can be focused is changed.
+ *
+ */
+
+typedef struct
+ {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* "event" window reported relative to */
+ XID deviceid;
+ int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */
+ int detail;
+ /*
+ * NotifyAncestor, NotifyVirtual, NotifyInferior,
+ * NotifyNonLinear,NotifyNonLinearVirtual, NotifyPointer,
+ * NotifyPointerRoot, NotifyDetailNone
+ */
+ Time time;
+ } XDeviceFocusChangeEvent;
+
+typedef XDeviceFocusChangeEvent XDeviceFocusInEvent;
+typedef XDeviceFocusChangeEvent XDeviceFocusOutEvent;
+
+/*******************************************************************
+ *
+ * ProximityNotify events. These events are sent by those absolute
+ * positioning devices that are capable of generating proximity information.
+ *
+ */
+
+typedef struct
+ {
+ int type; /* ProximityIn or ProximityOut */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ XID deviceid;
+ Window root;
+ Window subwindow;
+ Time time;
+ int x, y;
+ int x_root, y_root;
+ unsigned int state;
+ Bool same_screen;
+ unsigned int device_state; /* device key or button mask */
+ unsigned char axes_count;
+ unsigned char first_axis;
+ int axis_data[6];
+ } XProximityNotifyEvent;
+typedef XProximityNotifyEvent XProximityInEvent;
+typedef XProximityNotifyEvent XProximityOutEvent;
+
+/*******************************************************************
+ *
+ * DeviceStateNotify events are generated on EnterWindow and FocusIn
+ * for those clients who have selected DeviceState.
+ *
+ */
+
+typedef struct
+ {
+ unsigned char class;
+ unsigned char length;
+ } XInputClass;
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window;
+ XID deviceid;
+ Time time;
+ int num_classes;
+ char data[64];
+} XDeviceStateNotifyEvent;
+
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ unsigned char num_valuators;
+ unsigned char mode;
+ int valuators[6];
+} XValuatorStatus;
+
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ short num_keys;
+ char keys[32];
+} XKeyStatus;
+
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ short num_buttons;
+ char buttons[32];
+} XButtonStatus;
+
+/*******************************************************************
+ *
+ * DeviceMappingNotify event. This event is sent when the key mapping,
+ * modifier mapping, or button mapping of an extension device is changed.
+ *
+ */
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* unused */
+ XID deviceid;
+ Time time;
+ int request; /* one of MappingModifier, MappingKeyboard,
+ MappingPointer */
+ int first_keycode;/* first keycode */
+ int count; /* defines range of change w. first_keycode*/
+} XDeviceMappingEvent;
+
+/*******************************************************************
+ *
+ * ChangeDeviceNotify event. This event is sent when an
+ * XChangeKeyboard or XChangePointer request is made.
+ *
+ */
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* unused */
+ XID deviceid;
+ Time time;
+ int request; /* NewPointer or NewKeyboard */
+} XChangeDeviceNotifyEvent;
+
+/*******************************************************************
+ *
+ * Control structures for input devices that support input class
+ * Feedback. These are used by the XGetFeedbackControl and
+ * XChangeFeedbackControl functions.
+ *
+ */
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+} XFeedbackState;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int click;
+ int percent;
+ int pitch;
+ int duration;
+ int led_mask;
+ int global_auto_repeat;
+ char auto_repeats[32];
+} XKbdFeedbackState;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int accelNum;
+ int accelDenom;
+ int threshold;
+} XPtrFeedbackState;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int resolution;
+ int minVal;
+ int maxVal;
+} XIntegerFeedbackState;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int max_symbols;
+ int num_syms_supported;
+ KeySym *syms_supported;
+} XStringFeedbackState;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int percent;
+ int pitch;
+ int duration;
+} XBellFeedbackState;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int led_values;
+ int led_mask;
+} XLedFeedbackState;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+} XFeedbackControl;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int accelNum;
+ int accelDenom;
+ int threshold;
+} XPtrFeedbackControl;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int click;
+ int percent;
+ int pitch;
+ int duration;
+ int led_mask;
+ int led_value;
+ int key;
+ int auto_repeat_mode;
+} XKbdFeedbackControl;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int num_keysyms;
+ KeySym *syms_to_display;
+} XStringFeedbackControl;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int int_to_display;
+} XIntegerFeedbackControl;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int percent;
+ int pitch;
+ int duration;
+} XBellFeedbackControl;
+
+typedef struct {
+ XID class;
+ int length;
+ XID id;
+ int led_mask;
+ int led_values;
+} XLedFeedbackControl;
+
+/*******************************************************************
+ *
+ * Device control structures.
+ *
+ */
+
+typedef struct {
+ XID control;
+ int length;
+} XDeviceControl;
+
+typedef struct {
+ XID control;
+ int length;
+ int first_valuator;
+ int num_valuators;
+ int *resolutions;
+} XDeviceResolutionControl;
+
+typedef struct {
+ XID control;
+ int length;
+ int num_valuators;
+ int *resolutions;
+ int *min_resolutions;
+ int *max_resolutions;
+} XDeviceResolutionState;
+
+/*******************************************************************
+ *
+ * An array of XDeviceList structures is returned by the
+ * XListInputDevices function. Each entry contains information
+ * about one input device. Among that information is an array of
+ * pointers to structures that describe the characteristics of
+ * the input device.
+ *
+ */
+
+typedef struct _XAnyClassinfo *XAnyClassPtr;
+
+typedef struct _XAnyClassinfo {
+ XID class;
+ int length;
+ } XAnyClassInfo;
+
+typedef struct _XDeviceInfo *XDeviceInfoPtr;
+
+typedef struct _XDeviceInfo
+ {
+ XID id;
+ Atom type;
+ char *name;
+ int num_classes;
+ int use;
+ XAnyClassPtr inputclassinfo;
+ } XDeviceInfo;
+
+typedef struct _XKeyInfo *XKeyInfoPtr;
+
+typedef struct _XKeyInfo
+ {
+ XID class;
+ int length;
+ unsigned short min_keycode;
+ unsigned short max_keycode;
+ unsigned short num_keys;
+ } XKeyInfo;
+
+typedef struct _XButtonInfo *XButtonInfoPtr;
+
+typedef struct _XButtonInfo {
+ XID class;
+ int length;
+ short num_buttons;
+ } XButtonInfo;
+
+typedef struct _XAxisInfo *XAxisInfoPtr;
+
+typedef struct _XAxisInfo {
+ int resolution;
+ int min_value;
+ int max_value;
+ } XAxisInfo;
+
+typedef struct _XValuatorInfo *XValuatorInfoPtr;
+
+typedef struct _XValuatorInfo
+ {
+ XID class;
+ int length;
+ unsigned char num_axes;
+ unsigned char mode;
+ unsigned long motion_buffer;
+ XAxisInfoPtr axes;
+ } XValuatorInfo;
+
+
+/*******************************************************************
+ *
+ * An XDevice structure is returned by the XOpenDevice function.
+ * It contains an array of pointers to XInputClassInfo structures.
+ * Each contains information about a class of input supported by the
+ * device, including a pointer to an array of data for each type of event
+ * the device reports.
+ *
+ */
+
+
+typedef struct {
+ unsigned char input_class;
+ unsigned char event_type_base;
+} XInputClassInfo;
+
+typedef struct {
+ XID device_id;
+ int num_classes;
+ XInputClassInfo *classes;
+} XDevice;
+
+
+/*******************************************************************
+ *
+ * The following structure is used to return information for the
+ * XGetSelectedExtensionEvents function.
+ *
+ */
+
+typedef struct {
+ XEventClass event_type;
+ XID device;
+} XEventList;
+
+/*******************************************************************
+ *
+ * The following structure is used to return motion history data from
+ * an input device that supports the input class Valuators.
+ * This information is returned by the XGetDeviceMotionEvents function.
+ *
+ */
+
+typedef struct {
+ Time time;
+ int *data;
+} XDeviceTimeCoord;
+
+
+/*******************************************************************
+ *
+ * Device state structure.
+ * This is returned by the XQueryDeviceState request.
+ *
+ */
+
+typedef struct {
+ XID device_id;
+ int num_classes;
+ XInputClass *data;
+} XDeviceState;
+
+/*******************************************************************
+ *
+ * Note that the mode field is a bitfield that reports the Proximity
+ * status of the device as well as the mode. The mode field should
+ * be OR'd with the mask DeviceMode and compared with the values
+ * Absolute and Relative to determine the mode, and should be OR'd
+ * with the mask ProximityState and compared with the values InProximity
+ * and OutOfProximity to determine the proximity state.
+ *
+ */
+
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ unsigned char num_valuators;
+ unsigned char mode;
+ int *valuators;
+} XValuatorState;
+
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ short num_keys;
+ char keys[32];
+} XKeyState;
+
+typedef struct {
+ unsigned char class;
+ unsigned char length;
+ short num_buttons;
+ char buttons[32];
+} XButtonState;
+
+/*******************************************************************
+ *
+ * Function definitions.
+ *
+ */
+
+_XFUNCPROTOBEGIN
+
+extern int XChangeKeyboardDevice(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */
+#endif
+);
+
+extern int XChangePointerDevice(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ int /* xaxis */,
+ int /* yaxis */
+#endif
+);
+
+extern int XGrabDevice(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ Window /* grab_window */,
+ Bool /* ownerEvents */,
+ int /* event count */,
+ XEventClass* /* event_list */,
+ int /* this_device_mode */,
+ int /* other_devices_mode */,
+ Time /* time */
+#endif
+);
+
+extern int XUngrabDevice(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ Time /* time */
+#endif
+);
+
+extern int XGrabDeviceKey(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ unsigned int /* key */,
+ unsigned int /* modifiers */,
+ XDevice* /* modifier_device */,
+ Window /* grab_window */,
+ Bool /* owner_events */,
+ unsigned int /* event_count */,
+ XEventClass* /* event_list */,
+ int /* this_device_mode */,
+ int /* other_devices_mode */
+#endif
+);
+
+extern int XUngrabDeviceKey(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ unsigned int /* key */,
+ unsigned int /* modifiers */,
+ XDevice* /* modifier_dev */,
+ Window /* grab_window */
+#endif
+);
+
+extern int XGrabDeviceButton(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ unsigned int /* button */,
+ unsigned int /* modifiers */,
+ XDevice* /* modifier_device */,
+ Window /* grab_window */,
+ Bool /* owner_events */,
+ unsigned int /* event_count */,
+ XEventClass* /* event_list */,
+ int /* this_device_mode */,
+ int /* other_devices_mode */
+#endif
+);
+
+extern int XUngrabDeviceButton(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ unsigned int /* button */,
+ unsigned int /* modifiers */,
+ XDevice* /* modifier_dev */,
+ Window /* grab_window */
+#endif
+);
+
+extern int XAllowDeviceEvents(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ int /* event_mode */,
+ Time /* time */
+#endif
+);
+
+extern int XGetDeviceFocus(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ Window* /* focus */,
+ int* /* revert_to */,
+ Time* /* time */
+#endif
+);
+
+extern int XSetDeviceFocus(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ Window /* focus */,
+ int /* revert_to */,
+ Time /* time */
+#endif
+);
+
+extern XFeedbackState *XGetFeedbackControl(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ int* /* num_feedbacks */
+#endif
+);
+
+extern int XFreeFeedbackList(
+#if NeedFunctionPrototypes
+ XFeedbackState* /* list */
+#endif
+);
+
+extern int XChangeFeedbackControl(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ unsigned long /* mask */,
+ XFeedbackControl* /* f */
+#endif
+);
+
+extern int XDeviceBell(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ XID /* feedbackclass */,
+ XID /* feedbackid */,
+ int /* percent */
+#endif
+);
+
+extern KeySym *XGetDeviceKeyMapping(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+#if NeedWidePrototypes
+ unsigned int /* first */,
+#else
+ KeyCode /* first */,
+#endif
+ int /* keycount */,
+ int* /* syms_per_code */
+#endif
+);
+
+extern int XChangeDeviceKeyMapping(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ int /* first */,
+ int /* syms_per_code */,
+ KeySym* /* keysyms */,
+ int /* count */
+#endif
+);
+
+extern XModifierKeymap *XGetDeviceModifierMapping(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */
+#endif
+);
+
+extern int XSetDeviceModifierMapping(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ XModifierKeymap* /* modmap */
+#endif
+);
+
+extern int XSetDeviceButtonMapping(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ unsigned char* /* map[] */,
+ int /* nmap */
+#endif
+);
+
+extern int XGetDeviceButtonMapping(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ unsigned char* /* map[] */,
+ unsigned int /* nmap */
+#endif
+);
+
+extern XDeviceState *XQueryDeviceState(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */
+#endif
+);
+
+extern int XFreeDeviceState(
+#if NeedFunctionPrototypes
+ XDeviceState* /* list */
+#endif
+);
+
+extern XExtensionVersion *XGetExtensionVersion(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ _Xconst char* /* name */
+#endif
+);
+
+extern XDeviceInfo *XListInputDevices(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ int* /* ndevices */
+#endif
+);
+
+extern int XFreeDeviceList(
+#if NeedFunctionPrototypes
+ XDeviceInfo* /* list */
+#endif
+);
+
+extern XDevice *XOpenDevice(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XID /* id */
+#endif
+);
+
+extern int XCloseDevice(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */
+#endif
+);
+
+extern int XSetDeviceMode(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ int /* mode */
+#endif
+);
+
+extern int XSetDeviceValuators(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ int* /* valuators */,
+ int /* first_valuator */,
+ int /* num_valuators */
+#endif
+);
+
+extern XDeviceControl *XGetDeviceControl(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ int /* control */
+#endif
+);
+
+extern int XChangeDeviceControl(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ int /* control */,
+ XDeviceControl* /* d */
+#endif
+);
+
+extern int XSelectExtensionEvent(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ Window /* w */,
+ XEventClass* /* event_list */,
+ int /* count */
+#endif
+);
+
+extern int XGetSelectedExtensionEvents(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ Window /* w */,
+ int* /* this_client_count */,
+ XEventClass** /* this_client_list */,
+ int* /* all_clients_count */,
+ XEventClass** /* all_clients_list */
+#endif
+);
+
+extern int XChangeDeviceDontPropagateList(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ Window /* window */,
+ int /* count */,
+ XEventClass* /* events */,
+ int /* mode */
+#endif
+);
+
+extern XEventClass *XGetDeviceDontPropagateList(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ Window /* window */,
+ int* /* count */
+#endif
+);
+
+extern Status XSendExtensionEvent(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ Window /* dest */,
+ Bool /* prop */,
+ int /* count */,
+ XEventClass* /* list */,
+ XEvent* /* event */
+#endif
+);
+
+extern XDeviceTimeCoord *XGetDeviceMotionEvents(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XDevice* /* device */,
+ Time /* start */,
+ Time /* stop */,
+ int* /* nEvents */,
+ int* /* mode */,
+ int* /* axis_count */
+#endif
+);
+
+extern int XFreeDeviceMotionEvents(
+#if NeedFunctionPrototypes
+ XDeviceTimeCoord* /* events */
+#endif
+);
+
+extern int XFreeDeviceControl(
+#if NeedFunctionPrototypes
+ XDeviceControl* /* control */
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XINPUT_H_ */
+
+/* Definitions used by the server, library and client */
+
+#ifndef _XI_H_
+
+#define _XI_H_
+
+#define sz_xGetExtensionVersionReq 8
+#define sz_xGetExtensionVersionReply 32
+#define sz_xListInputDevicesReq 4
+#define sz_xListInputDevicesReply 32
+#define sz_xOpenDeviceReq 8
+#define sz_xOpenDeviceReply 32
+#define sz_xCloseDeviceReq 8
+#define sz_xSetDeviceModeReq 8
+#define sz_xSetDeviceModeReply 32
+#define sz_xSelectExtensionEventReq 12
+#define sz_xGetSelectedExtensionEventsReq 8
+#define sz_xGetSelectedExtensionEventsReply 32
+#define sz_xChangeDeviceDontPropagateListReq 12
+#define sz_xGetDeviceDontPropagateListReq 8
+#define sz_xGetDeviceDontPropagateListReply 32
+#define sz_xGetDeviceMotionEventsReq 16
+#define sz_xGetDeviceMotionEventsReply 32
+#define sz_xChangeKeyboardDeviceReq 8
+#define sz_xChangeKeyboardDeviceReply 32
+#define sz_xChangePointerDeviceReq 8
+#define sz_xChangePointerDeviceReply 32
+#define sz_xGrabDeviceReq 20
+#define sz_xGrabDeviceReply 32
+#define sz_xUngrabDeviceReq 12
+#define sz_xGrabDeviceKeyReq 20
+#define sz_xGrabDeviceKeyReply 32
+#define sz_xUngrabDeviceKeyReq 16
+#define sz_xGrabDeviceButtonReq 20
+#define sz_xGrabDeviceButtonReply 32
+#define sz_xUngrabDeviceButtonReq 16
+#define sz_xAllowDeviceEventsReq 12
+#define sz_xGetDeviceFocusReq 8
+#define sz_xGetDeviceFocusReply 32
+#define sz_xSetDeviceFocusReq 16
+#define sz_xGetFeedbackControlReq 8
+#define sz_xGetFeedbackControlReply 32
+#define sz_xChangeFeedbackControlReq 12
+#define sz_xGetDeviceKeyMappingReq 8
+#define sz_xGetDeviceKeyMappingReply 32
+#define sz_xChangeDeviceKeyMappingReq 8
+#define sz_xGetDeviceModifierMappingReq 8
+#define sz_xSetDeviceModifierMappingReq 8
+#define sz_xSetDeviceModifierMappingReply 32
+#define sz_xGetDeviceButtonMappingReq 8
+#define sz_xGetDeviceButtonMappingReply 32
+#define sz_xSetDeviceButtonMappingReq 8
+#define sz_xSetDeviceButtonMappingReply 32
+#define sz_xQueryDeviceStateReq 8
+#define sz_xQueryDeviceStateReply 32
+#define sz_xSendExtensionEventReq 16
+#define sz_xDeviceBellReq 8
+#define sz_xSetDeviceValuatorsReq 8
+#define sz_xSetDeviceValuatorsReply 32
+#define sz_xGetDeviceControlReq 8
+#define sz_xGetDeviceControlReply 32
+#define sz_xChangeDeviceControlReq 8
+#define sz_xChangeDeviceControlReply 32
+
+#define INAME "XInputExtension"
+
+#define XI_KEYBOARD "KEYBOARD"
+#define XI_MOUSE "MOUSE"
+#define XI_TABLET "TABLET"
+#define XI_TOUCHSCREEN "TOUCHSCREEN"
+#define XI_TOUCHPAD "TOUCHPAD"
+#define XI_BARCODE "BARCODE"
+#define XI_BUTTONBOX "BUTTONBOX"
+#define XI_KNOB_BOX "KNOB_BOX"
+#define XI_ONE_KNOB "ONE_KNOB"
+#define XI_NINE_KNOB "NINE_KNOB"
+#define XI_TRACKBALL "TRACKBALL"
+#define XI_QUADRATURE "QUADRATURE"
+#define XI_ID_MODULE "ID_MODULE"
+#define XI_SPACEBALL "SPACEBALL"
+#define XI_DATAGLOVE "DATAGLOVE"
+#define XI_EYETRACKER "EYETRACKER"
+#define XI_CURSORKEYS "CURSORKEYS"
+#define XI_FOOTMOUSE "FOOTMOUSE"
+
+#define Dont_Check 0
+#define XInput_Initial_Release 1
+#define XInput_Add_XDeviceBell 2
+#define XInput_Add_XSetDeviceValuators 3
+#define XInput_Add_XChangeDeviceControl 4
+
+#define XI_Absent 0
+#define XI_Present 1
+
+#define XI_Initial_Release_Major 1
+#define XI_Initial_Release_Minor 0
+
+#define XI_Add_XDeviceBell_Major 1
+#define XI_Add_XDeviceBell_Minor 1
+
+#define XI_Add_XSetDeviceValuators_Major 1
+#define XI_Add_XSetDeviceValuators_Minor 2
+
+#define XI_Add_XChangeDeviceControl_Major 1
+#define XI_Add_XChangeDeviceControl_Minor 3
+
+#define DEVICE_RESOLUTION 1
+
+#define NoSuchExtension 1
+
+#define COUNT 0
+#define CREATE 1
+
+#define NewPointer 0
+#define NewKeyboard 1
+
+#define XPOINTER 0
+#define XKEYBOARD 1
+
+#define UseXKeyboard 0xFF
+
+#define IsXPointer 0
+#define IsXKeyboard 1
+#define IsXExtensionDevice 2
+
+#define AsyncThisDevice 0
+#define SyncThisDevice 1
+#define ReplayThisDevice 2
+#define AsyncOtherDevices 3
+#define AsyncAll 4
+#define SyncAll 5
+
+#define FollowKeyboard 3
+#define RevertToFollowKeyboard 3
+
+#define DvAccelNum (1L &lt;&lt; 0)
+#define DvAccelDenom (1L &lt;&lt; 1)
+#define DvThreshold (1L &lt;&lt; 2)
+
+#define DvKeyClickPercent (1L&lt;&lt;0)
+#define DvPercent (1L&lt;&lt;1)
+#define DvPitch (1L&lt;&lt;2)
+#define DvDuration (1L&lt;&lt;3)
+#define DvLed (1L&lt;&lt;4)
+#define DvLedMode (1L&lt;&lt;5)
+#define DvKey (1L&lt;&lt;6)
+#define DvAutoRepeatMode (1L&lt;&lt;7)
+
+#define DvString (1L &lt;&lt; 0)
+
+#define DvInteger (1L &lt;&lt; 0)
+
+#define DeviceMode (1L &lt;&lt; 0)
+#define Relative 0
+#define Absolute 1
+
+#define ProximityState (1L &lt;&lt; 1)
+#define InProximity (0L &lt;&lt; 1)
+#define OutOfProximity (1L &lt;&lt; 1)
+
+#define AddToList 0
+#define DeleteFromList 1
+
+#define KeyClass 0
+#define ButtonClass 1
+#define ValuatorClass 2
+#define FeedbackClass 3
+#define ProximityClass 4
+#define FocusClass 5
+#define OtherClass 6
+
+#define KbdFeedbackClass 0
+#define PtrFeedbackClass 1
+#define StringFeedbackClass 2
+#define IntegerFeedbackClass 3
+#define LedFeedbackClass 4
+#define BellFeedbackClass 5
+
+#define _devicePointerMotionHint 0
+#define _deviceButton1Motion 1
+#define _deviceButton2Motion 2
+#define _deviceButton3Motion 3
+#define _deviceButton4Motion 4
+#define _deviceButton5Motion 5
+#define _deviceButtonMotion 6
+#define _deviceButtonGrab 7
+#define _deviceOwnerGrabButton 8
+#define _noExtensionEvent 9
+
+#define XI_BadDevice 0
+#define XI_BadEvent 1
+#define XI_BadMode 2
+#define XI_DeviceBusy 3
+#define XI_BadClass 4
+
+typedef unsigned long XEventClass;
+
+/*******************************************************************
+ *
+ * Extension version structure.
+ *
+ */
+
+typedef struct {
+ int present;
+ short major_version;
+ short minor_version;
+} XExtensionVersion;
+
+#endif /* _XI_H_ */
+
+</literallayout>
+<!-- .\" print Table of Contents -->
+<!-- .if o .bp \" blank page to make count even -->
+<!-- .bp 1 -->
+<!-- .af PN i -->
+<!-- .PX -->
+
+
+</para>
+</sect3>
+</sect2>
+</sect1>
+</chapter>