2446 lines
96 KiB
Plaintext
2446 lines
96 KiB
Plaintext
|
The X Input Extension 2.x
|
|||
|
=========================
|
|||
|
:toc:
|
|||
|
:numbered:
|
|||
|
|
|||
|
Authors:
|
|||
|
|
|||
|
- Peter Hutterer (Red Hat) <peter.hutterer@redhat.com>
|
|||
|
- Daniel Stone (Collabora Ltd.) <daniel@fooishbar.org>
|
|||
|
- Chase Douglas (Canonical, Ltd.) <chase.douglas@canonical.com>
|
|||
|
|
|||
|
[[history]]
|
|||
|
History
|
|||
|
-------
|
|||
|
|
|||
|
- v2.2, March 2012: Multitouch support added
|
|||
|
- v2.1, December 2011: new raw event behaviour, smooth scrolling support
|
|||
|
added
|
|||
|
- v2.0, October 2009: Initial release of XI2 protocol
|
|||
|
|
|||
|
[[intro-xi20]]
|
|||
|
Introduction
|
|||
|
------------
|
|||
|
|
|||
|
The X Input Extension version 2.0 (XI2) is the second major release of the X
|
|||
|
Input Extension.
|
|||
|
|
|||
|
XI2 provides a number of enhancements over version 1.5, including:
|
|||
|
|
|||
|
- use of XGE and GenericEvents. GenericEvents are of flexible length with a
|
|||
|
minimum length of 32 bytes.
|
|||
|
- explicit device hierarchy of master and slave devices. See Section
|
|||
|
<<hierarchy,The Master/Slave device hierarchy>>.
|
|||
|
- use of multiple independent master devices (Multi-Poiner X or MPX).
|
|||
|
- the ability for devices to change capabilities at runtime.
|
|||
|
- raw device events
|
|||
|
|
|||
|
XI2's intent is to replace both core input processing and prior versions of
|
|||
|
the X Input Extension. Historically, the majority of applications employed the
|
|||
|
core protocol requests and events to handle user input. The core protocol does
|
|||
|
not provide information about which device generated the event. The X Input
|
|||
|
Extension version up to 1.5 requires the differentiation between core and
|
|||
|
extended devices. Extended devices may not be core devices and thus cannot be
|
|||
|
used on applications employing the core protocol. XI2 addresses both of these
|
|||
|
issues by enabling devices to be both extended and core devices and providing
|
|||
|
device information in each event (with the exception of core events).
|
|||
|
|
|||
|
Changes in version 2.1
|
|||
|
----------------------
|
|||
|
|
|||
|
- RawEvents are sent regardless of the grab state.
|
|||
|
- Addition of the ScrollClass for smooth scrolling
|
|||
|
|
|||
|
Changes in version 2.2
|
|||
|
----------------------
|
|||
|
|
|||
|
- Multitouch support added
|
|||
|
|
|||
|
|
|||
|
// ❧❧❧❧❧❧❧❧❧❧❧
|
|||
|
|
|||
|
Notations used in this document
|
|||
|
-------------------------------
|
|||
|
|
|||
|
Notation for requests:
|
|||
|
|
|||
|
┌───
|
|||
|
Name of request
|
|||
|
name of request field: type of request field
|
|||
|
name of request field: type of request field
|
|||
|
▶
|
|||
|
name of reply field: type of reply field
|
|||
|
└───
|
|||
|
|
|||
|
Notation for events:
|
|||
|
|
|||
|
┌───
|
|||
|
Name of event
|
|||
|
name of field: type of field
|
|||
|
name of field: type of field
|
|||
|
└───
|
|||
|
|
|||
|
Complex fields are specified in the following notation:
|
|||
|
|
|||
|
name of field: COMPLEXFIELDTYPE
|
|||
|
|
|||
|
or, if multiple of these fields exist:
|
|||
|
|
|||
|
name of field: LISTofCOMPLEXFIELDTYPE
|
|||
|
|
|||
|
COMPLEXFIELDTYPE: { name of subfield: type of subfield,
|
|||
|
name of subfield: type of subfield }
|
|||
|
|
|||
|
// ❧❧❧❧❧❧❧❧❧❧❧
|
|||
|
|
|||
|
Interoperability between version 1.x and 2.0
|
|||
|
--------------------------------------------
|
|||
|
|
|||
|
There is little interaction between 1.x and 2.x versions of the X Input
|
|||
|
Extension. Clients are requested to avoid mixing XI1.x and XI2 code as much as
|
|||
|
possible. Several direct incompatibilities are observable:
|
|||
|
|
|||
|
[[interop-xi1-limitations]]
|
|||
|
Limitations resulting from different variable ranges
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
XI2 provides a larger range for some fields than XI1. As a result, XI1 clients
|
|||
|
may not receive data an XI2 client receives.
|
|||
|
These fields include:
|
|||
|
|
|||
|
- devices with a deviceid of greater than 127 are invisible to XI1 clients.
|
|||
|
- key events and key grabs featuring larger than 255 can only be sent to XI2
|
|||
|
clients.
|
|||
|
- no subpixel information is available to XI1 clients. If motion events are in
|
|||
|
a subpixel range only, the server may omit these events and an XI 1.x client
|
|||
|
will not receive events until the pixel boundary is crossed.
|
|||
|
|
|||
|
|
|||
|
[[interop-xi1-grabs]]
|
|||
|
Blocking of grabs
|
|||
|
~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
XI1 grabs are different to XI2 grab and a device may not be grabbed through an
|
|||
|
XI2 grab if an XI1 grab is currently active on this device or vice versa.
|
|||
|
Likewise, a keycode or button already grabbed by an XI 1.x or XI2 client may
|
|||
|
not be grabbed with the same modifier combination by an XI2 or XI 1.x client,
|
|||
|
respectively.
|
|||
|
|
|||
|
[[interop-xi1-device-list]]
|
|||
|
Invisibility of Master Devices
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
XI 1.x was not designed with support for multiple master devices. As a
|
|||
|
result, only the first master pointer and master keyboard are visible to XI
|
|||
|
1.x clients; all other master devices are invisible and cannot be accessed
|
|||
|
from XI 1.x calls.
|
|||
|
|
|||
|
Smooth scrolling
|
|||
|
~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
Historically, X implemented scrolling events by using button press events:
|
|||
|
button 4 was one “click” of the scroll wheel upwards, button 5 was downwards,
|
|||
|
button 6 was one unit of scrolling left, and button 7 was one unit of scrolling
|
|||
|
right. This is insufficient for e.g. touchpads which are able to provide
|
|||
|
scrolling events through multi-finger drag gestures, or simply dragging your
|
|||
|
finger along a designated strip along the side of the touchpad.
|
|||
|
|
|||
|
Newer X servers may provide scrolling information through valuators to
|
|||
|
provide clients with more precision than the legacy button events. This
|
|||
|
scrolling information is part of the valuator data in device events.
|
|||
|
Scrolling events do not have a specific event type.
|
|||
|
|
|||
|
Valuators for axes sending scrolling information must have one
|
|||
|
ScrollClass for each scrolling axis. If scrolling valuators are present on a
|
|||
|
device, the server must provide two-way emulation between these valuators
|
|||
|
and the legacy button events for each delta unit of scrolling.
|
|||
|
|
|||
|
One unit of scrolling in either direction is considered to be equivalent to
|
|||
|
one button event, e.g. for a unit size of 1.0, -2.0 on an valuator type
|
|||
|
Vertical sends two button press/release events for button 4. Likewise, a
|
|||
|
button press event for button 7 generates an event on the Horizontal
|
|||
|
valuator with a value of +1.0. The server may accumulate deltas of less than
|
|||
|
one unit of scrolling.
|
|||
|
|
|||
|
Any server providing this behaviour marks emulated button or valuator events
|
|||
|
with the XIPointerEmulated flag for DeviceEvents, and the XIRawEmulated flag
|
|||
|
for raw events, to hint at applications which event is a hardware event.
|
|||
|
|
|||
|
If more than one scroll valuator of the same type is present on a device,
|
|||
|
the valuator marked with Preferred for the same scroll direction is used to
|
|||
|
convert legacy button events into scroll valuator events. If no valuator is
|
|||
|
marked Preferred or more than one valuator is marked with Preferred for this
|
|||
|
scroll direction, this should be considered a driver bug and the behaviour
|
|||
|
is implementation-dependent.
|
|||
|
|
|||
|
[[hierarchy]]
|
|||
|
The Master/Slave device hierarchy
|
|||
|
---------------------------------
|
|||
|
|
|||
|
XI2 introduces a device hierarchy split up into so-called Master Devices (MD)
|
|||
|
and Slave Devices (SD).
|
|||
|
|
|||
|
[[hierarchy-master]]
|
|||
|
Master devices
|
|||
|
~~~~~~~~~~~~~~
|
|||
|
An MD is a virtual device created and managed by the server. MDs may send core
|
|||
|
events and XI events. However, an MD does not represent a physical device and
|
|||
|
relies on SDs for event generation. MDs come in two forms: as master pointers
|
|||
|
or as master keyboards. A master pointer is represented by a visible cursor on
|
|||
|
the screen. A master keyboard is represented by a keyboard focus.
|
|||
|
|
|||
|
Each master pointer is paired with the respective master keyboard and vice
|
|||
|
versa, and this pairing is constant for the lifetime of both input devices.
|
|||
|
Clients can use this pairing behaviour to implement input paradigms that
|
|||
|
require pointer and keyboard interation (e.g. SHIFT + Click).
|
|||
|
|
|||
|
[[hierarchy-slave]]
|
|||
|
Slave devices
|
|||
|
~~~~~~~~~~~~~
|
|||
|
An SD is usually a physical device configured in the server. SDs are not
|
|||
|
represented by a cursor or keyboard focus and may be attached to a master
|
|||
|
pointer or master keyboard. SDs can only be attached to any master of the same
|
|||
|
type (e.g. a physical pointer device can be attached to any master pointer).
|
|||
|
|
|||
|
If an event is generated by an SD
|
|||
|
|
|||
|
- if the SD is attached to a master pointer, it changes the position and/or
|
|||
|
button state of the master pointer.
|
|||
|
- if the SD is attached to a master keyboard, it sends events to this
|
|||
|
keyboard's focus window (if applicable) and/or changes the modifier state of
|
|||
|
this keyboard.
|
|||
|
- if the SD is not attached to an MD ("floating"), it does not change
|
|||
|
any master device. The SD has its own (invisible) sprite and its own focus.
|
|||
|
Both the sprite and the focus must be managed explicitly by the client
|
|||
|
program.
|
|||
|
|
|||
|
[[hierarchy-dcce]]
|
|||
|
Event processing for attached slave devices
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
Whenever an SD changes its logical state,
|
|||
|
|
|||
|
- the event is delivered as an XI event to any interested clients. If the
|
|||
|
device is floating, event processing stops.
|
|||
|
Otherwise, if the device is attached,
|
|||
|
- the master device changes its classes to reflect the SD's capabilities. All
|
|||
|
interested clients are notified of this device change.
|
|||
|
- then, the event is delivered as an XI event from the MD to any interested
|
|||
|
clients. If the event has been delivered, event processing stops.
|
|||
|
Otherwise,
|
|||
|
- the event is delivered as a core event to any interested clients.
|
|||
|
|
|||
|
Given that W is the event window, and P the parent window of W, event delivery
|
|||
|
to P is only attempted if neither the XI event, nor the core event has been
|
|||
|
delivered on W. Once an event has been delivered as either XI or core event,
|
|||
|
event processing stops.
|
|||
|
|
|||
|
[[clientpointer]]
|
|||
|
The ClientPointer principle
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
Many core protocol and some extension requests are ambiguous when multiple
|
|||
|
master devices are available (e.g. QueryPointer does not specify which pointer).
|
|||
|
The X server does not have the knowledge to chose the contextually correct
|
|||
|
master device. For each client, one master pointer is designated as this
|
|||
|
clients's "ClientPointer". Whenever a client sends an ambiguous request (e.g.
|
|||
|
QueryPointer), the ClientPointer or the keyboard paired with the ClientPointer
|
|||
|
is chosen to provide the data for this request.
|
|||
|
|
|||
|
This ClientPointer may be explicitly assigned to a client with the
|
|||
|
SetClientPointer call. If no ClientPointer is set when a client issues an
|
|||
|
ambiguous request, the server choses one device as the ClientPointer. The
|
|||
|
method of chosing a ClientPointer from the available master pointers is
|
|||
|
implementation-specific.
|
|||
|
|
|||
|
If the master pointer currently set as ClientPointer for one or more clients is
|
|||
|
removed, the server may either unset the ClientPointer setting or change the
|
|||
|
ClientPointer to a different master pointer.
|
|||
|
|
|||
|
[[multitouch]]
|
|||
|
Touch device support
|
|||
|
--------------------
|
|||
|
|
|||
|
XI 2.2 introduces support for multi-touch devices. The traditional
|
|||
|
pointer/keyboard approach enforced by XI 2.0 with the master/slave device
|
|||
|
hierarchy is not always suitable for multi-touch devices that can provide a
|
|||
|
dynamic number of touchpoints per physical device; it is not known without
|
|||
|
client-specific interpretation whether the touchpoints must be considered
|
|||
|
separately or grouped together.
|
|||
|
|
|||
|
The additions in XI 2.2 aim to:
|
|||
|
|
|||
|
- support a dynamic number of simultaneous touch points,
|
|||
|
- support devices that are both multi-touch and traditional pointer devices,
|
|||
|
- allow touchpoints to be either grouped together or handled separately,
|
|||
|
- be backwards-compatible to pre-XI 2.2 clients through emulation of XI 2.x/XI 1.x and core
|
|||
|
pointer events.
|
|||
|
|
|||
|
Touch events are only available to clients supporting version 2.2 or later of
|
|||
|
the X Input Extension. Clients must use the XIQueryVersion request to announce
|
|||
|
support for this version. Touch devices may generate emulated pointer events
|
|||
|
alongside XI 2.2 touch events to support older clients; see Section
|
|||
|
<<multitouch-processing,Touch event delivery>>.
|
|||
|
|
|||
|
Touch event processing differs from normal event processing in a few ways.
|
|||
|
The most notable differences are that touch events are processed partially
|
|||
|
out-of-band from pointer and keyboard events, and that touch events may be
|
|||
|
sent to multiple clients simultaneously. For more details see Section
|
|||
|
<<multitouch-processing, Touch event delivery>>.
|
|||
|
|
|||
|
[[multitouch-lifecycle]]
|
|||
|
Touch event sequences
|
|||
|
~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
Touch input follows a three-stage cycle:
|
|||
|
|
|||
|
begin - update - update - ... - end
|
|||
|
|
|||
|
i.e. “begin” the sequence by touching the device, “update” the current
|
|||
|
touch location or properties any number of times, and finally “end” the
|
|||
|
sequence by ceasing to touch the device. Within this document, the term
|
|||
|
"touch sequence" is used to describe the above sequence of events.
|
|||
|
In the protocol, the three stages are represented with the event
|
|||
|
types TouchBegin, TouchUpdate, and TouchEnd, respectively. A touch sequence
|
|||
|
always generates TouchBegin and TouchEnd events, and may also generate
|
|||
|
TouchUpdate events. Clients must select for all three of these events
|
|||
|
simultaneously.
|
|||
|
|
|||
|
When a touch starts, clients are sent a TouchBegin event
|
|||
|
detailing the position of the touchpoint, as well as the
|
|||
|
initial properties of the touchpoint. Note that the logical state of the
|
|||
|
device (as seen through the input protocol) may lag the physical state if event
|
|||
|
processing is affected by grabs. Multiple touchpoints may be active on the
|
|||
|
same device at any time, potentially owned by and/or delivered to a different
|
|||
|
set of clients.
|
|||
|
|
|||
|
Whenever the touch position or any other property of the touchpoint changes,
|
|||
|
a TouchUpdate event is sent to all clients listening
|
|||
|
to events for that touchpoint with the updated information.
|
|||
|
|
|||
|
When the touch has physically ended, or a client will otherwise not receive
|
|||
|
any more events for a given touchpoint, a TouchEnd event will be sent to
|
|||
|
that client.
|
|||
|
|
|||
|
Passive touch grabs are similar to standard input event grabs in that they
|
|||
|
take precedence over event selections and are searched from the root window
|
|||
|
to the child window (as opposed to selections, which start their search at the
|
|||
|
child window and continue up to the root window). When a touch grab activates,
|
|||
|
the client whose grab activates becomes the “owner” of this touch sequence,
|
|||
|
and must decide what to do with it, as per Section
|
|||
|
<<multitouch-ownership,Ownership of touch sequences>>. See the
|
|||
|
<<requests-passivegrabdevice,XIPassiveGrabDevice>> request
|
|||
|
documentation for more information on passive grab activation.
|
|||
|
|
|||
|
Only one client may select for touch events from a given device on a window.
|
|||
|
|
|||
|
[[multitouch-ownership]]
|
|||
|
Ownership of touch sequences
|
|||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|||
|
|
|||
|
Once a grabbing client becomes the owner of a touch, it must either “accept” or
|
|||
|
"reject" the touch sequence using the XIAllowEvents request. If a touch sequence
|
|||
|
is rejected, a TouchEnd event is sent to the rejecting client, and it will not
|
|||
|
receive any more events for this touch. The server then looks to the next
|
|||
|
window in the stack for another passive grab, and attempts to pass ownership
|
|||
|
on to the next candidate for a passive grab (i.e. the next window towards
|
|||
|
the final child window with a matching grab), or to the first applicable
|
|||
|
event selection if there are no more grabs.
|
|||
|
|
|||
|
If a touch sequence is accepted by its owner, all other clients receive
|
|||
|
TouchEnd events, and the touch sequence is exclusively delivered to the
|
|||
|
owner from that point on.
|
|||
|
|
|||
|
If the touch sequence physically ends while the owner of the touch sequence
|
|||
|
has not yet accepted or rejected ownership, the owner receives a TouchEnd
|
|||
|
event and all other clients receive a TouchUpdate event with the
|
|||
|
TouchPendingEnd flag set. The owner must still accept or reject the sequence
|
|||
|
nonetheless. If the owner rejects the touch sequence, the server will still
|
|||
|
attempt to exhaust all other passive grabs and/or event selections looking
|
|||
|
for a final owner.
|
|||
|
|
|||
|
If the touch sequence has not physically ended yet and the owner of the
|
|||
|
touch sequence rejects, the owner receives a TouchEnd event and ownership is
|
|||
|
passed to the next client.
|
|||
|
|
|||
|
Clients may opt for touch events to be delivered before they become the
|
|||
|
owner of the touch sequence. In this case, the logical state of the device (as
|
|||
|
seen by means of the protocol) always matches the physical state of the device.
|
|||
|
Clients must use caution if they opt for this feature; any action taken must be
|
|||
|
undone if the touch sequence ends without the client becoming the owner.
|
|||
|
|
|||
|
To select for touch events regardless of ownership, a client must set the
|
|||
|
TouchOwnership event mask in addition to the
|
|||
|
TouchBegin, TouchUpdate and TouchEnd mask. When selected, a client will receive
|
|||
|
touch events as they occur on the device. If and when the client
|
|||
|
becomes the owner of a touch sequence, a TouchOwnership event is sent to the
|
|||
|
client. If the client is the initial owner of the sequence, the TouchBegin is
|
|||
|
immediately followed by the TouchOwnership event. Otherwise, TouchUpdate events
|
|||
|
may preceed a TouchOwnership event. A client is not guaranteed to become the
|
|||
|
owner of any given touch sequence.
|
|||
|
|
|||
|
The server delivers touch events to all clients that have selected for
|
|||
|
TouchOwnership and to the current owner of the sequence in parallel.
|
|||
|
|
|||
|
If a client has selected for TouchOwnership and is not the current owner of
|
|||
|
the sequence and the current owner accepts the sequence, the client receives
|
|||
|
a TouchEnd event and no further events from this sequence are sent to this
|
|||
|
client.
|
|||
|
|
|||
|
If a client has selected for TouchOwnership and the physical touch ends
|
|||
|
before the current owner has accepted or rejected the sequence, the client
|
|||
|
receives a TouchUpdate event with the TouchPendingEnd flag set. No further
|
|||
|
TouchUpdate events will be sent for this sequence. If the current owner
|
|||
|
accepts the sequence, the client receives a TouchEnd event. Otherwise, if
|
|||
|
the current owner rejects the sequence, the client may become
|
|||
|
the owner of the touch sequence and receive a TouchOwnership event and a
|
|||
|
TouchEnd event.
|
|||
|
|
|||
|
[[multitouch-device-modes]]
|
|||
|
Touch device modes
|
|||
|
~~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
Touch devices come in many different forms with varying capabilities. The
|
|||
|
following device modes are defined for this protocol:
|
|||
|
|
|||
|
'DirectTouch':
|
|||
|
These devices map their input region to a subset of the screen region. Touch
|
|||
|
events are delivered to window at the location of the touch. "direct"
|
|||
|
here refers to the user manipulating objects at their screen location.
|
|||
|
An example of a DirectTouch device is a touchscreen.
|
|||
|
|
|||
|
'DependentTouch':
|
|||
|
These devices do not have a direct correlation between a touch location and
|
|||
|
a position on the screen. Touch events are delivered according to the
|
|||
|
location of the device's cursor and often need to be interpreted
|
|||
|
relative to the current position of that cursor. Such interactions are
|
|||
|
usually the result of a gesture performed on the device, rather than
|
|||
|
direct manipulation. An example of a DependentTouch device is a
|
|||
|
trackpad.
|
|||
|
|
|||
|
A device is identified as only one of the device modes above at any time, and
|
|||
|
the touch mode may change at any time. If a device's touch mode changes, an
|
|||
|
XIDeviceChangedEvent is generated.
|
|||
|
|
|||
|
[[multitouch-processing]]
|
|||
|
Touch event delivery
|
|||
|
~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
For direct touch devices, the window set for event propagation is the set of
|
|||
|
windows from the root window to the topmost window lying at the co-ordinates
|
|||
|
of the touch.
|
|||
|
|
|||
|
For dependent devices, the window set for event propagation is the set of
|
|||
|
windows from the root window to the window that contains the device's
|
|||
|
pointer. A dependent device may only have one window set at a time, for all
|
|||
|
touches. Any future touch sequence will use the same window set. The window set
|
|||
|
is cleared when all touch sequences on the device end.
|
|||
|
|
|||
|
A window set is calculated on TouchBegin and remains constant until the end
|
|||
|
of the sequence. Modifications to the window hierarchy, new grabs or changed
|
|||
|
event selection do not affect the window set.
|
|||
|
|
|||
|
Pointer control of dependent devices
|
|||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|||
|
On a dependent device, the device may differ between a pointer-controlling
|
|||
|
touch and a non-pointer-controlling touch. For example, on a touchpad the
|
|||
|
first touch is pointer-controlling (i.e. serves only to move the visible
|
|||
|
pointer). Multi-finger gestures on a touchpad cause all touches to be
|
|||
|
non-pointer-controlling.
|
|||
|
|
|||
|
For pointer-controlling touches, no touch events are sent; the touch
|
|||
|
generates regular pointer events instead. Non-pointer-controlling touches
|
|||
|
send touch events. A touch may change from pointer-controlling to
|
|||
|
non-pointer-controlling, or vice versa.
|
|||
|
|
|||
|
- If a touch changes from pointer-controlling to non-pointer-controlling,
|
|||
|
a new touch ID is assigned and a TouchBegin is sent for the last known
|
|||
|
position of the touch. Further events are sent as TouchUpdate events, or as
|
|||
|
TouchEnd event if the touch terminates.
|
|||
|
|
|||
|
- If a touch changes from non-pointer-controlling to pointer-controlling, a
|
|||
|
TouchEnd is sent for that touch at the last known position of the touch.
|
|||
|
Further events are sent as pointer events.
|
|||
|
|
|||
|
The conditions to switch from pointer-controlling to non-pointer-controlling
|
|||
|
touch is implementation-dependent. A device may support touches that are
|
|||
|
both pointer-controlling and a touch event.
|
|||
|
|
|||
|
In the dependent touch example event sequence below, touches are marked when
|
|||
|
switching to pointer-controlling (pc) or to non-pointer-controlling (np).
|
|||
|
|
|||
|
.Dependent touch example event sequence on a touchpad
|
|||
|
[width="50%", options="header"]
|
|||
|
|====================================================
|
|||
|
| Finger 1 | Finger 2 | Event generated(touchid)
|
|||
|
| down | | Motion
|
|||
|
| move | | Motion
|
|||
|
| move | | Motion
|
|||
|
| (np) | down | TouchBegin(0), TouchBegin(1)
|
|||
|
| move | -- | TouchUpdate(0)
|
|||
|
| -- | move | TouchUpdate(1)
|
|||
|
| up | (pc) | TouchEnd(0), TouchEnd(1)
|
|||
|
| | move | Motion
|
|||
|
| down | (np) | TouchBegin(2), TouchBegin(3)
|
|||
|
| move | -- | TouchUpdate(2)
|
|||
|
| up | (pc) | TouchEnd(2), TouchEnd(3)
|
|||
|
| | up | Motion
|
|||
|
| down | | Motion
|
|||
|
| (np) | down | TouchBegin(4), TouchBegin(5)
|
|||
|
| (pc) | up | TouchEnd(4), TouchEnd(5)
|
|||
|
| move | | Motion
|
|||
|
| up | | Motion
|
|||
|
|====================================================
|
|||
|
|
|||
|
|
|||
|
[[multitouch-emulation]]
|
|||
|
Pointer emulation from multitouch events
|
|||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|||
|
|
|||
|
Touch sequences from direct touch devices may emulate pointer events. Only one
|
|||
|
touch sequence from a device may emulate pointer events at a time; which touch
|
|||
|
sequence emulates pointer events is implementation-dependent.
|
|||
|
|
|||
|
Pointer events are emulated as follows:
|
|||
|
|
|||
|
- A TouchBegin event generates a pointer motion event to the location of the
|
|||
|
touch with the same axis values of the touch event, followed by a button press
|
|||
|
event for button 1.
|
|||
|
- A TouchUpdate event generates a pointer motion event to the location of the
|
|||
|
touch and/or to update axis values of the pointer device. The button state
|
|||
|
as seen from the protocol includes button 1 set.
|
|||
|
- A TouchEnd event generates a pointer motion event to the location of the touch
|
|||
|
and/or to update the axis values if either have changed, followed by a button
|
|||
|
release event for button 1. The button state as seen from the protocol
|
|||
|
includes button 1 set.
|
|||
|
|
|||
|
If a touch sequence emulates pointer events and an emulated pointer event
|
|||
|
triggers the activation of a passive grab, the grabbing client becomes the
|
|||
|
owner of the touch sequence.
|
|||
|
|
|||
|
The touch sequence is considered to have been accepted if
|
|||
|
|
|||
|
- the grab mode is asynchronous, or
|
|||
|
- the grab mode is synchronous and the device is thawed as a result of
|
|||
|
AllowEvents with AsyncPointer or AsyncDevice
|
|||
|
|
|||
|
Otherwise, if the button press is replayed by the client, the touch sequence
|
|||
|
is considered to be rejected.
|
|||
|
|
|||
|
Touch event delivery precedes pointer event delivery. A touch event emulating
|
|||
|
pointer events is delivered:
|
|||
|
|
|||
|
- as a touch event to the top-most window of the current window set if a
|
|||
|
client has a touch grab on this window,
|
|||
|
- otherwise, as a pointer event to the top-most window of the current window
|
|||
|
set if a client has a pointer grab on this window,
|
|||
|
- otherwise, to the next child window in the window set until a grab has been
|
|||
|
found.
|
|||
|
|
|||
|
If no touch or pointer grab on any window is active and the last window in the
|
|||
|
window set has been reached, the event is delivered:
|
|||
|
|
|||
|
- as a touch event to the window if a client has selected for touch events
|
|||
|
on this window
|
|||
|
- otherwise, as a pointer event to the window if a client has selected for
|
|||
|
pointer events.
|
|||
|
- otherwise, to the next parent window in the window set until a selection has
|
|||
|
been found.
|
|||
|
|
|||
|
Emulated pointer events will have the PointerEmulated flag set. A touch
|
|||
|
event that emulates pointer events has the TouchEmulatingPointer flag set.
|
|||
|
|
|||
|
[[glossary-notations]]
|
|||
|
Notations used in this document
|
|||
|
-------------------------------
|
|||
|
|
|||
|
Notation for requests:
|
|||
|
|
|||
|
┌───
|
|||
|
Name of request
|
|||
|
name of request field: type of request field
|
|||
|
name of request field: type of request field
|
|||
|
▶
|
|||
|
name of reply field: type of reply field
|
|||
|
└───
|
|||
|
|
|||
|
Notation for events:
|
|||
|
|
|||
|
┌───
|
|||
|
Name of event
|
|||
|
name of field: type of field
|
|||
|
name of field: type of field
|
|||
|
└───
|
|||
|
|
|||
|
Complex fields are specified in the following notation:
|
|||
|
|
|||
|
name of field: COMPLEXFIELDTYPE
|
|||
|
|
|||
|
or, if multiple of these fields exist:
|
|||
|
|
|||
|
name of field: LISTofCOMPLEXFIELDTYPE
|
|||
|
|
|||
|
COMPLEXFIELDTYPE: { name of subfield: type of subfield,
|
|||
|
name of subfield: type of subfield }
|
|||
|
|
|||
|
|
|||
|
[[glossary-datatypes]]
|
|||
|
Data types
|
|||
|
----------
|
|||
|
|
|||
|
BUTTONMASK
|
|||
|
A binary mask defined as (1 << button number).
|
|||
|
A SETofBUTTONMASK is a binary OR of zero or more BUTTONMASK.
|
|||
|
|
|||
|
DEVICE { DEVICEID, AllDevices, AllMasterDevices }
|
|||
|
A DEVICE specifies either a DEVICEID or AllDevices or
|
|||
|
AllMasterDevices.
|
|||
|
|
|||
|
DEVICEID { CARD16 }
|
|||
|
A DEVICEID is a numerical ID for a device currently available in the
|
|||
|
server. The server may re-use a device ID after a device's removal.
|
|||
|
The device IDs 0 and 1 are reserved.
|
|||
|
AllDevices ........ 0
|
|||
|
AllMasterDevices .. 1
|
|||
|
|
|||
|
DEVICEUSE { MasterPointer, MasterKeyboard, SlavePointer,
|
|||
|
SlaveKeyboard, FloatingSlave }
|
|||
|
A DEVICEUSE field specifies the current use of a device in the MD/SD
|
|||
|
device hierarchy. See Section "The Master/Slave device hierarchy"
|
|||
|
for more information.
|
|||
|
|
|||
|
EVENTMASK
|
|||
|
An EVENTMASK is a binary mask defined as (1 << event type).
|
|||
|
A SETofEVENTMASK is a binary OR of zero or more EVENTMASK.
|
|||
|
|
|||
|
FP1616
|
|||
|
Fixed point decimal in 16.16 format as one INT16 and one CARD16.
|
|||
|
The INT16 contains the integral part, the CARD32 the decimal fraction
|
|||
|
shifted by 16.
|
|||
|
|
|||
|
FP3232
|
|||
|
Fixed point decimal in 32.32 format as one INT32 and one CARD32.
|
|||
|
The INT32 contains the integral part, the CARD32 the decimal fraction
|
|||
|
shifted by 32.
|
|||
|
|
|||
|
VALUATORMASK
|
|||
|
A binary mask defined as (1 << valuator number).
|
|||
|
A SETofVALUATORMASK is a binary OR of zero or more VALUATORMASK.
|
|||
|
|
|||
|
|
|||
|
[[errors]]
|
|||
|
Errors
|
|||
|
------
|
|||
|
|
|||
|
Errors are sent using core X error reports.
|
|||
|
|
|||
|
Device
|
|||
|
A value for a DEVICE argument does not specify a valid DEVICE.
|
|||
|
|
|||
|
|
|||
|
[[requests]]
|
|||
|
Requests:
|
|||
|
---------
|
|||
|
|
|||
|
The server does not guarantee that the length of a reply remains constant in
|
|||
|
future revisions of XI2. A client must always retrieve the exact length of the
|
|||
|
protocol reply from the connection, even if the reply is longer than defined
|
|||
|
for the XI2 version supported by the client.
|
|||
|
Additional bytes in a request may include data supported in later versions of
|
|||
|
XI2. Clients should ignore this data. Padding bytes in XI2 protocol requests
|
|||
|
are required to be 0.
|
|||
|
|
|||
|
[[requests-xi20]]
|
|||
|
Requests introduced in version 2.0
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
[[requests-queryversion]]
|
|||
|
┌───
|
|||
|
XIQueryVersion
|
|||
|
major_version: CARD16
|
|||
|
minor_version: CARD16
|
|||
|
▶
|
|||
|
major_version: CARD16
|
|||
|
minor_version: CARD16
|
|||
|
└───
|
|||
|
|
|||
|
The client sends the highest supported version to the server and the
|
|||
|
server sends the highest version it supports, but no higher than the
|
|||
|
requested version. Major versions changes can introduce incompatibilities
|
|||
|
in existing functionality, minor version changes introduce only backward
|
|||
|
compatible changes. It is the client's responsibility to ensure that the
|
|||
|
server supports a version which is compatible with its expectations.
|
|||
|
|
|||
|
major_version
|
|||
|
Major XI2 version.
|
|||
|
minor_version
|
|||
|
Minor XI2 version.
|
|||
|
|
|||
|
If major_version is less than 2, a BadValue error occurs.
|
|||
|
|
|||
|
[[requests-querydevice]]
|
|||
|
┌───
|
|||
|
XIQueryDevice
|
|||
|
DEVICE deviceid
|
|||
|
▶
|
|||
|
num_devices: CARD16
|
|||
|
deviceinfo: LISTofDEVICEINFO
|
|||
|
└───
|
|||
|
|
|||
|
DEVICEINFO { deviceid: DEVICEID
|
|||
|
use: DEVICEUSE
|
|||
|
attachment: DEVICEID
|
|||
|
enabled: BOOL
|
|||
|
num_classes: CARD16
|
|||
|
name_len: CARD16
|
|||
|
name: LISTofCHAR8
|
|||
|
classes: LISTofCLASS }
|
|||
|
|
|||
|
CLASS { BUTTONCLASS, KEYCLASS, AXISCLASS, SCROLLCLASS, TOUCHCLASS }
|
|||
|
|
|||
|
BUTTONCLASS { type: ButtonClass
|
|||
|
length: CARD16
|
|||
|
sourceid: CARD16
|
|||
|
buttons_len: CARD16
|
|||
|
state: SETofBUTTONMASK
|
|||
|
labels: LISTofATOM }
|
|||
|
|
|||
|
KEYCLASS { type: KeyClass
|
|||
|
length: CARD16
|
|||
|
sourceid: CARD16
|
|||
|
num_keys: CARD16
|
|||
|
keys: LISTofCARD32 }
|
|||
|
|
|||
|
AXISCLASS { type: AxisClass
|
|||
|
length: CARD16
|
|||
|
sourceid: CARD16
|
|||
|
axisnumber: CARD16
|
|||
|
label: ATOM
|
|||
|
min: FP3232
|
|||
|
max: FP3232
|
|||
|
value: FP3232
|
|||
|
resolution: CARD32
|
|||
|
mode: CARD8 }
|
|||
|
|
|||
|
SCROLLCLASS¹ {type: ScrollClass
|
|||
|
length: CARD16
|
|||
|
sourceid: CARD16
|
|||
|
axisnumber: CARD16
|
|||
|
scroll_type: SCROLLTYPE
|
|||
|
flags: SETofSCROLLFLAGS
|
|||
|
increment: FP3232 }
|
|||
|
|
|||
|
SCROLLTYPE { Vertical, Horizontal }
|
|||
|
|
|||
|
SCROLLFLAGS { NoEmulation, Preferred }
|
|||
|
|
|||
|
TOUCHCLASS² { type: TouchClass
|
|||
|
length: CARD16
|
|||
|
sourceid: CARD16
|
|||
|
mode: TOUCHMODE
|
|||
|
num_touches: CARD16 }
|
|||
|
|
|||
|
TOUCHMODE { DirectTouch, DependentTouch }
|
|||
|
|
|||
|
¹ since XI 2.1
|
|||
|
² since XI 2.2
|
|||
|
|
|||
|
XIQueryDevice details information about the requested input devices.
|
|||
|
|
|||
|
devices
|
|||
|
The device to list. If devices is AllDevices, all enabled and
|
|||
|
disabled devices are listed. If devices is AllMasterDevices, all
|
|||
|
enabled and disabled master devices are listed. If devices is a
|
|||
|
valid DEVICE, only this DEVICE is listed and num_devices is 1.
|
|||
|
num_devices
|
|||
|
The number of deviceinfos returned.
|
|||
|
|
|||
|
Each deviceinfo is detailed as follows:
|
|||
|
|
|||
|
deviceid
|
|||
|
The unique ID of the device. Device IDs may get re-used when a device
|
|||
|
is removed.
|
|||
|
use
|
|||
|
If the device is a master pointer, use is MasterPointer.
|
|||
|
If the device is a master keyboard, use is MasterKeyboard.
|
|||
|
If the device is a slave pointer, use is SlavePointer.
|
|||
|
If the device is a slave keyboard, use is SlaveKeyboard.
|
|||
|
If the device is a floating slave, use is FloatingSlave.
|
|||
|
attachment
|
|||
|
If the device is a master pointer or a master keyboard, attachment
|
|||
|
specifies the paired master keyboard, or the paired master pointer,
|
|||
|
respectively. If the device is a non-floating slave device
|
|||
|
attachment specifies the master device this device is attached to.
|
|||
|
If the device is a floating slave, attachment is undefined.
|
|||
|
enabled
|
|||
|
Zero if the device is disabled, non-zero otherwise.
|
|||
|
num_classes
|
|||
|
Number of classes provided.
|
|||
|
name_len
|
|||
|
Length of the name in bytes not including padding.
|
|||
|
classes
|
|||
|
Details the available classes provided by the device in an undefined
|
|||
|
order.
|
|||
|
name
|
|||
|
The device's name. padded to a multiple of 4 bytes.
|
|||
|
|
|||
|
For all classes, type specifies the device class. Clients are required
|
|||
|
to ignore unknown device classes. The length field specifies the length
|
|||
|
of the class in 4 byte units.
|
|||
|
The following classes may occur only once: ButtonClass, KeyClass
|
|||
|
|
|||
|
ButtonClass:
|
|||
|
type
|
|||
|
Always ButtonClass.
|
|||
|
length
|
|||
|
Length in 4 byte units.
|
|||
|
sourceid
|
|||
|
The device this class originates from.
|
|||
|
num_buttons
|
|||
|
Number of buttons provided by the device.
|
|||
|
labels
|
|||
|
List of Atoms specifying the label for each button. An Atom of None
|
|||
|
specifies an unlabeled button. Buttons are listed in the device-native
|
|||
|
order regardless of the current button mapping.
|
|||
|
state
|
|||
|
The current button mask for this device after button mapping is
|
|||
|
applied. Each bit representing a button is 1 if this button is
|
|||
|
logically down, or 0 otherwise. State is a multiple of 4-byte units
|
|||
|
and always contains at least num_buttons bits.
|
|||
|
|
|||
|
KeyClass:
|
|||
|
type
|
|||
|
Always KeyClass.
|
|||
|
length
|
|||
|
Length in 4 byte units.
|
|||
|
sourceid
|
|||
|
The device this class originates from.
|
|||
|
num_keys
|
|||
|
Number of keycodes provided by the device.
|
|||
|
keys
|
|||
|
List of keycodes provided.
|
|||
|
|
|||
|
AxisClass:
|
|||
|
type
|
|||
|
Always AxisClass.
|
|||
|
length
|
|||
|
Length in 4 byte units.
|
|||
|
sourceid
|
|||
|
The device this class originates from.
|
|||
|
axisnumber
|
|||
|
Axis number of this axis. The axis number is in device-native
|
|||
|
order and potential axis mappings are ignored.
|
|||
|
label
|
|||
|
Atom specifying the axis name. An Atom of None specifies an unlabeled
|
|||
|
axis.
|
|||
|
min
|
|||
|
Minimum value.
|
|||
|
max
|
|||
|
Minimum value.
|
|||
|
resolution
|
|||
|
Resolution in counts/meter.
|
|||
|
mode
|
|||
|
Relative or Absolute.
|
|||
|
value
|
|||
|
Last published axis value (if mode is absolute).
|
|||
|
|
|||
|
An axis in Relative mode may specify min and max as a hint to the
|
|||
|
client. If no min and max information is available, both must be 0.
|
|||
|
|
|||
|
ScrollClass:
|
|||
|
type
|
|||
|
Always ScrollClass.
|
|||
|
axisnumber
|
|||
|
Axis number that is referred to. This axis number must be listed in
|
|||
|
the ValuatorClassInfo.
|
|||
|
scroll_type:
|
|||
|
Vertical for a vertical scrolling axis, Horizontal for a horizontal
|
|||
|
scrolling axis.
|
|||
|
flags:
|
|||
|
A set of flags that apply to this scroll axis.
|
|||
|
NoEmulation: no legacy scroll button events are generated for events
|
|||
|
on this scrolling axis.
|
|||
|
Preferred: This axis is the preferred axis for emulating valuator
|
|||
|
events from legacy scroll button events.
|
|||
|
increment:
|
|||
|
The valuator delta equivalent to one positive unit of scrolling.
|
|||
|
|
|||
|
A ScrollClass may only exist if the device has at least one ValuatorClass
|
|||
|
and each axisnumber listed in any ScrollClass. Only one ScrollClass may
|
|||
|
exist per ValuatorClass.
|
|||
|
|
|||
|
TouchClass:
|
|||
|
type
|
|||
|
Always TouchClass.
|
|||
|
length
|
|||
|
Length in 4 byte units.
|
|||
|
sourceid
|
|||
|
The device this class originates from.
|
|||
|
mode
|
|||
|
The device type of the touch device. This mode may change at runtime.
|
|||
|
num_touches
|
|||
|
The maximum number of simultaneous touchpoints the device may send.
|
|||
|
If num_touches is 0, the number of supported touches is unknown or
|
|||
|
unlimited.
|
|||
|
|
|||
|
Devices with a TouchClass emit touch events with the same axes as pointer
|
|||
|
events.
|
|||
|
|
|||
|
[[requests-selectevents]]
|
|||
|
┌───
|
|||
|
XISelectEvents
|
|||
|
window: Window
|
|||
|
num_masks: CARD16
|
|||
|
masks: LISTofEVENTMASK
|
|||
|
|
|||
|
└───
|
|||
|
|
|||
|
EVENTMASK { deviceid: DEVICE,
|
|||
|
mask_len: CARD16,
|
|||
|
mask: SETofEVENTMASK
|
|||
|
|
|||
|
window
|
|||
|
The window to select the events on.
|
|||
|
num_masks
|
|||
|
Number of items in masks.
|
|||
|
deviceid
|
|||
|
Numerical deviceid, or AllDevices, or AllMasterDevices.
|
|||
|
mask_len
|
|||
|
Length of mask in 4 byte units.
|
|||
|
mask
|
|||
|
Event mask. An event mask for an event type T is defined as (1 << T).
|
|||
|
|
|||
|
XISelectEvents selects for XI2 events on window.
|
|||
|
|
|||
|
If num_masks is 0, a BadValue error occurs.
|
|||
|
|
|||
|
Each mask sets the (and overwrites a previous) event mask for the DEVICE
|
|||
|
specified through deviceid. The device AllDevices or
|
|||
|
AllMasterDevices is treated as a separate device by server. A client's
|
|||
|
event mask is the union of AllDevices, AllMasterDevices and the
|
|||
|
per-device event mask.
|
|||
|
The removal of device from the server unsets the event masks for the
|
|||
|
device. If an event mask is set for AllDevices or AllMasterDevices, the
|
|||
|
event mask is not cleared on device removal and affects all future
|
|||
|
devices.
|
|||
|
|
|||
|
If mask_len is 0, the event mask for the given device is cleared.
|
|||
|
|
|||
|
The mask for XIHierarchyEvents may only be selected for XIAllDevices.
|
|||
|
Setting it for any other device results in a BadValue error.
|
|||
|
|
|||
|
A client selecting for any of XI_TouchBegin, XI_TouchUpdate, or XI_TouchEnd
|
|||
|
must select for all three events at the same time, else a BadValue error
|
|||
|
will be generated. A client selecting for XI_TouchOwnership must select for
|
|||
|
all three of the other touch events. If the selection for these touch events
|
|||
|
overlaps a current selection by another client (e.g. selecting for a
|
|||
|
specific device when another client has a selection for XIAllDevices), a
|
|||
|
BadAccess error occurs.
|
|||
|
|
|||
|
[[requests-getselectedevents]]
|
|||
|
┌───
|
|||
|
XIGetSelectedEvents
|
|||
|
window: Window
|
|||
|
▶
|
|||
|
num_masks: CARD16
|
|||
|
masks: LISTofEVENTMASK
|
|||
|
└───
|
|||
|
|
|||
|
window
|
|||
|
The window to select the events on.
|
|||
|
num_masks
|
|||
|
Number of items in masks.
|
|||
|
masks
|
|||
|
Selected event masks by this client.
|
|||
|
|
|||
|
Masks are returned on a per-device basis, with masks for AllDevices and
|
|||
|
AllMasterDevices returned separately. A client can calculate the
|
|||
|
effective mask for a device with a bitwise OR of the AllDevices, the
|
|||
|
AllMasterDevices and the device-specific mask.
|
|||
|
|
|||
|
If num_masks is 0, no events have been selected by this client on the
|
|||
|
given window.
|
|||
|
|
|||
|
[[requests-querypointer]]
|
|||
|
┌───
|
|||
|
XIQueryPointer
|
|||
|
window: Window
|
|||
|
deviceid: DEVICEID
|
|||
|
▶
|
|||
|
root: Window
|
|||
|
child: Window
|
|||
|
root_x: FP1616
|
|||
|
root_y: FP1616
|
|||
|
win_x: FP1616
|
|||
|
win_y: FP1616
|
|||
|
same_screen: BOOL
|
|||
|
mods: MODIFIERINFO
|
|||
|
group: GROUPINFO
|
|||
|
buttons_len: CARD16
|
|||
|
buttons: SETofBUTTONMASK
|
|||
|
└───
|
|||
|
|
|||
|
Query a master pointer device for its current position.
|
|||
|
|
|||
|
root
|
|||
|
The root window the pointer is logically on.
|
|||
|
child
|
|||
|
The child window of window that contains the pointer or None.
|
|||
|
root_x
|
|||
|
root_y
|
|||
|
Pointer position relative to the root window's origin.
|
|||
|
win_x
|
|||
|
win_y
|
|||
|
Pointer position relative to window or 0 if same_screen is false.
|
|||
|
same_screen
|
|||
|
True if window is on the same screen as the pointer.
|
|||
|
mods
|
|||
|
XKB modifier state on the paired device.
|
|||
|
group
|
|||
|
XKB group state on the paired device.
|
|||
|
buttons_len
|
|||
|
The length of buttons in 4 byte units.
|
|||
|
buttons
|
|||
|
Button state.
|
|||
|
|
|||
|
If the device is not a master pointer device or not a floating slave
|
|||
|
pointer, a BadDevice error results.
|
|||
|
|
|||
|
[[requests-warppointer]]
|
|||
|
┌───
|
|||
|
XIWarpPointer
|
|||
|
src_win: Window
|
|||
|
dst_win: Window
|
|||
|
src_x: FP1616
|
|||
|
src_y: FP1616
|
|||
|
src_width: INT16
|
|||
|
src_height: INT16
|
|||
|
dst_x: FP1616
|
|||
|
dst_y: FP1616
|
|||
|
deviceid: DEVICEID
|
|||
|
└───
|
|||
|
|
|||
|
WarpPointer moves the pointer of deviceid as if the user had moved
|
|||
|
the pointer. WarpPointer can only be called for MasterPointer and
|
|||
|
FloatingSlave devices.
|
|||
|
|
|||
|
src_win
|
|||
|
If src_window is not None, the move only takes place if src_window
|
|||
|
contains the pointer and the pointer is contained in the specified
|
|||
|
rectangle of src_window.
|
|||
|
dst_win
|
|||
|
If dst_win is None, this request moves the pointer by offsets
|
|||
|
dst_x/dst_y relative to the current position of the pointer. If
|
|||
|
dst_window is a window, this request moves the pointer to
|
|||
|
dst_x/dst_y relative to dst_win's origin.
|
|||
|
src_x
|
|||
|
src_y
|
|||
|
src_width
|
|||
|
src_height
|
|||
|
Specifies the source window rectangle.
|
|||
|
dst_x
|
|||
|
dst_y
|
|||
|
The relative coordinates to move the pointer if dst_win is None, or
|
|||
|
the absolute coordinates if dst_win is a window.
|
|||
|
deviceid
|
|||
|
The device to warp.
|
|||
|
|
|||
|
This request cannot be used to move the pointer outside the confine-to
|
|||
|
window of an active pointer grab. An attempt will only move the pointer as
|
|||
|
far as the closest edge of the confine-to window.
|
|||
|
|
|||
|
This request will generate events just as if the user had instantaneously
|
|||
|
moved the pointer.
|
|||
|
|
|||
|
[[requests-changecursor]]
|
|||
|
┌───
|
|||
|
XIChangeCursor
|
|||
|
win: Window
|
|||
|
cursor: Cursor
|
|||
|
deviceid: DEVICEID
|
|||
|
└───
|
|||
|
|
|||
|
Change a master pointer's cursor on the specified window.
|
|||
|
|
|||
|
window
|
|||
|
The window.
|
|||
|
cursor
|
|||
|
The new cursor or None.
|
|||
|
deviceid
|
|||
|
The master pointer device.
|
|||
|
|
|||
|
Whenever device enters a window W, the cursor shape is selected in the
|
|||
|
following order:
|
|||
|
|
|||
|
- if the current window has a device cursor C(d) defined for device,
|
|||
|
display this cursor C(d).
|
|||
|
- otherwise, if the current window has a cursor C(w) defined in the core
|
|||
|
protocol's window attributes, display cursor C(w).
|
|||
|
- repeat on parent window until a cursor has been found.
|
|||
|
|
|||
|
The device cursor for a given window is reset once the window is destroyed
|
|||
|
or the device is removed, whichever comes earlier.
|
|||
|
|
|||
|
If deviceid does not specify a master pointer, a BadDevice error
|
|||
|
is returned.
|
|||
|
|
|||
|
[[requests-changehierarchy]]
|
|||
|
┌───
|
|||
|
XIChangeHierarchy
|
|||
|
num_changes: CARD8
|
|||
|
changes: LISTofHIERARCHYCHANGES
|
|||
|
└───
|
|||
|
|
|||
|
HIERARCHYCHANGE { ADDMASTER, REMOVEMASTER, ATTACHSLAVE, DETACHSLAVE }
|
|||
|
|
|||
|
HIERARCHYCHANGETYPE { AddMaster, RemoveMaster, AttachSlave, DetachSlave }
|
|||
|
|
|||
|
CHANGEMODE { Float, Attach }
|
|||
|
|
|||
|
ADDMASTER { type: HIERARCHYCHANGETYPE
|
|||
|
length: CARD16
|
|||
|
name_len: CARD16
|
|||
|
send_core: BOOL
|
|||
|
enable: BOOL
|
|||
|
name: LISTofCHAR8 }
|
|||
|
|
|||
|
REMOVEMASTER { type: HIERARCHYCHANGETYPE
|
|||
|
length: CARD16
|
|||
|
deviceid: DEVICEID
|
|||
|
return_mode: CHANGEMODE
|
|||
|
return_pointer: DEVICEID
|
|||
|
return_keyboard: DEVICEID }
|
|||
|
|
|||
|
ATTACHSLAVE { type: HIERARCHYCHANGETYPE
|
|||
|
length: CARD16
|
|||
|
deviceid: DEVICEID
|
|||
|
master: DEVICEID }
|
|||
|
|
|||
|
DETACHSLAVE { type: HIERARCHYCHANGETYPE
|
|||
|
length: CARD16
|
|||
|
deviceid: DEVICEID }
|
|||
|
|
|||
|
XIChangeHierarchy allows a client to modify the
|
|||
|
<<hierarchy,Master/Slave device hierarchy>>.
|
|||
|
|
|||
|
num_changes
|
|||
|
The number of changes to apply to the current hierarchy.
|
|||
|
changes
|
|||
|
The list of changes.
|
|||
|
|
|||
|
The server processes the changes in the order received from the client and
|
|||
|
applies each requested change immediately. If an error occurs, processing
|
|||
|
stops at the current change and returns the number of successfully applied
|
|||
|
changes in the error.
|
|||
|
|
|||
|
ADDMASTER creates a pair of master devices.
|
|||
|
type
|
|||
|
Always AddMaster.
|
|||
|
length
|
|||
|
Length in 4 byte units.
|
|||
|
name_len
|
|||
|
Length of name in bytes.
|
|||
|
send_core
|
|||
|
True if the device should send core events.
|
|||
|
enable
|
|||
|
True if the device is to be enabled immediately.
|
|||
|
name
|
|||
|
The name for the new master devices. The master pointer's name is
|
|||
|
automatically appended with " pointer", the master keyboard's name is
|
|||
|
automatically appended with " keyboard".
|
|||
|
|
|||
|
REMOVEMASTER removes an existing master device.
|
|||
|
type
|
|||
|
Always RemoveMaster.
|
|||
|
length
|
|||
|
Length in 4 byte units.
|
|||
|
deviceid
|
|||
|
The device to remove.
|
|||
|
return_mode
|
|||
|
Return mode for attached slave devices.
|
|||
|
If return_mode is Float, all slave devices are set to floating.
|
|||
|
If return_mode is Attach, slave pointers are attached to
|
|||
|
return_pointer and slave keyboards are attached to
|
|||
|
return_keyboard.
|
|||
|
return_pointer
|
|||
|
return_keyboard
|
|||
|
The master pointer and master keyboard to attach slave devices to, if
|
|||
|
return_mode is Attach. If return_mode is Float, return_pointer
|
|||
|
and return_keyboard are undefined.
|
|||
|
|
|||
|
Removing a master pointer removes the paired master keyboard and vice
|
|||
|
versa.
|
|||
|
|
|||
|
ATTACHSLAVE attaches a slave device to a given master device.
|
|||
|
type
|
|||
|
Always ChangeAttachment.
|
|||
|
length
|
|||
|
Length in 4 byte units.
|
|||
|
deviceid
|
|||
|
Deviceid of the slave device.
|
|||
|
master
|
|||
|
The new master device to attach this slave device to.
|
|||
|
|
|||
|
If any clients are selecting for touch events from the slave device, their
|
|||
|
selection will be canceled.
|
|||
|
|
|||
|
DETACHSLAVE detaches a slave device from its current master device.
|
|||
|
type
|
|||
|
Always ChangeAttachment.
|
|||
|
length
|
|||
|
Length in 4 byte units.
|
|||
|
deviceid
|
|||
|
Deviceid of the slave device.
|
|||
|
|
|||
|
[[requests-setclientpointer]]
|
|||
|
┌───
|
|||
|
XISetClientPointer
|
|||
|
win: Window
|
|||
|
deviceid: DEVICEID
|
|||
|
└───
|
|||
|
|
|||
|
Set the ClientPointer for the client owning win to the given device.
|
|||
|
|
|||
|
win
|
|||
|
Window or client ID.
|
|||
|
deviceid
|
|||
|
The master pointer or master keyboard that acts as ClientPointer.
|
|||
|
|
|||
|
Some protocol requests are ambiguous and the server has to choose a device
|
|||
|
to provide data for a request or a reply. By default, the server will
|
|||
|
choose a client's ClientPointer device to provide the data, unless the
|
|||
|
client currently has a grab on another device. See section
|
|||
|
<<clientpointer,The ClientPointer principle>> for more details.
|
|||
|
|
|||
|
If win is None, the ClientPointer for this client is set to the given
|
|||
|
device. Otherwise, if win is a valid window, the ClientPointer for the
|
|||
|
client owning this window is set to the given device. Otherwise, if win is
|
|||
|
not a valid window but a client with the client mask equal to win exists,
|
|||
|
this client's ClientPointer is set to the given device.
|
|||
|
|
|||
|
If deviceid does not specify a master pointer or master keyboard, a
|
|||
|
BadDevice error is returned.
|
|||
|
|
|||
|
If window does not specify a valid window or client ID and is not None, a
|
|||
|
BadWindow error is returned.
|
|||
|
|
|||
|
[[requests-getclientpointer]]
|
|||
|
┌───
|
|||
|
XIGetClientPointer
|
|||
|
win: Window
|
|||
|
▶
|
|||
|
set: BOOL
|
|||
|
deviceid: DEVICEID
|
|||
|
└───
|
|||
|
|
|||
|
Query the ClientPointer for the client owning win.
|
|||
|
|
|||
|
win
|
|||
|
The window or client ID.
|
|||
|
set
|
|||
|
True if the client has a ClientPointer set.
|
|||
|
deviceid
|
|||
|
The master pointer that acts as a ClientPointer if set is True.
|
|||
|
|
|||
|
No difference is made between a ClientPointer set explicitly through
|
|||
|
XISetClientPointer and a ClientPointer implicitly assigned by the server
|
|||
|
in response to an ambiguous request.
|
|||
|
|
|||
|
[[requests-setfocus]]
|
|||
|
┌───
|
|||
|
XISetFocus
|
|||
|
focus: Window
|
|||
|
deviceid: DEVICEID
|
|||
|
time: Time
|
|||
|
└───
|
|||
|
|
|||
|
Set the focus for the given device to the given window. Future key events
|
|||
|
from this device are sent to this window.
|
|||
|
This request generates FocusIn and FocusOut events.
|
|||
|
|
|||
|
focus
|
|||
|
A viewable window or None.
|
|||
|
deviceid
|
|||
|
The device to modify the focus window for.
|
|||
|
time
|
|||
|
Specifies the time to change the focus or CurrentTime.
|
|||
|
|
|||
|
If focus is None, key events from this device are discarded until a new
|
|||
|
focus window is set. If focus is a viewable window, key events from this
|
|||
|
device are sent to this window. If the window becomes unviewable, the
|
|||
|
window's first viewable ancestor automatically becomes the focus window
|
|||
|
and FocusIn and FocusOut events are sent as if a client had changed the
|
|||
|
focus window.
|
|||
|
This is equivalent to RevertToParent in the core XSetInputFocus window.
|
|||
|
|
|||
|
This request has no effect if the specified time is earlier than the
|
|||
|
current last-focus-change time or is later than the current X server time.
|
|||
|
Otherwise, the last-focus-change time is set to the specified time.
|
|||
|
|
|||
|
[[requests-getfocus]]
|
|||
|
┌───
|
|||
|
XIGetFocus
|
|||
|
deviceid: DEVICEID
|
|||
|
▶
|
|||
|
focus: Window
|
|||
|
└───
|
|||
|
|
|||
|
Return the current focus window for the given device.
|
|||
|
|
|||
|
[[requests-grabdevice]]
|
|||
|
┌───
|
|||
|
XIGrabDevice
|
|||
|
deviceid: DEVICEID
|
|||
|
grab_window: Window
|
|||
|
owner_events: BOOL
|
|||
|
grab_mode: { Synchronous, Asynchronous }
|
|||
|
paired_device_mode: { Synchronous, Asynchronous }
|
|||
|
time: TIMESTAMP or CurrentTime
|
|||
|
cursor: Cursor
|
|||
|
mask_len: CARD16
|
|||
|
masks: SETofEVENTMASK
|
|||
|
▶
|
|||
|
status: Success, AlreadyGrabbed, Frozen, InvalidTime, NotViewable
|
|||
|
└───
|
|||
|
|
|||
|
This request actively grabs control of the specified input device. Further
|
|||
|
input events from this device are reported only to the grabbing client.
|
|||
|
This request overides any previous active grab by this client for this
|
|||
|
device. This request does not affect the processing of XI 2.2
|
|||
|
touch events.
|
|||
|
|
|||
|
deviceid
|
|||
|
The device to grab.
|
|||
|
grab_window
|
|||
|
Events are reported relative to the grab window.
|
|||
|
owner_events
|
|||
|
Specifies whether event will be reported normally or relative to the
|
|||
|
grab window.
|
|||
|
grab_mode
|
|||
|
Specifies if this device will be frozen as a result of the grab.
|
|||
|
paired_device_mode
|
|||
|
Specifies if the master device paired with this device will be frozen
|
|||
|
as a result of the grab.
|
|||
|
time
|
|||
|
A valid server time or CurrentTime.
|
|||
|
cursor
|
|||
|
The cursor to display for the duration of the grab or None.
|
|||
|
mask_len
|
|||
|
Length of mask in 4 byte units.
|
|||
|
mask
|
|||
|
Event mask. An event mask for an event type T is defined as (1 << T).
|
|||
|
status
|
|||
|
Success or the reason why the grab could not be established.
|
|||
|
|
|||
|
The masks parameter specifies which events the client wishes to receive
|
|||
|
while the device is grabbed.
|
|||
|
|
|||
|
If owner-events is False, input events generated from this device are
|
|||
|
reported with respect to grab-window, and are only reported if selected by
|
|||
|
being included in the event-list. If owner-events is True, then if a
|
|||
|
generated event would normally be reported to this client, it is reported
|
|||
|
normally, otherwise the event is reported with respect to the grab-window,
|
|||
|
and is only reported if selected by being included in the event-list. For
|
|||
|
either value of owner-events, unreported events are discarded.
|
|||
|
|
|||
|
If grab-mode is Asynchronous, device event processing continues normally.
|
|||
|
If the device is currently frozen by this client, then processing of
|
|||
|
device events is resumed. If grab-mode is Synchronous, the state of the
|
|||
|
grabbed device (as seen by means of the protocol) appears to freeze,
|
|||
|
and no further device events are generated by the server until the
|
|||
|
grabbing client issues a releasing XIAllowEvents request or until the
|
|||
|
device grab is released. Actual device input events are not lost while the
|
|||
|
device is frozen; they are simply queued for later processing.
|
|||
|
|
|||
|
If the device is a slave device, the paired-device-mode is ignored.
|
|||
|
Otherwise, if this device is a master device and paired-device-mode is
|
|||
|
Asynchronous, event processing is unaffected by activation of the grab. If
|
|||
|
this device is a master device and paired-device-mode is Synchronous, the
|
|||
|
state of the master device paired with this device (as seen by means of the
|
|||
|
protocol) appears to freeze, and no further events are generated by the
|
|||
|
server until the grabbing client issues a releasing XIAllowEvents request
|
|||
|
or until the device grab is released. Actual events are not lost while the
|
|||
|
devices are frozen; they are simply queued for later processing.
|
|||
|
|
|||
|
If the cursor is not None and the device is a master pointer device, the
|
|||
|
cursor will be displayed until the device is ungrabbed.
|
|||
|
|
|||
|
This request fails and returns:
|
|||
|
|
|||
|
AlreadyGrabbed: If the device is actively grabbed by some other client.
|
|||
|
NotViewable: If grab-window is not viewable.
|
|||
|
InvalidTime: If the specified time is earlier than the last-grab-time for
|
|||
|
the specified device or later than the current X server time.
|
|||
|
Otherwise, the last-grab-time for the specified device is set
|
|||
|
to the specified time and CurrentTime is replaced by the
|
|||
|
current X server time.
|
|||
|
Frozen: If the device is frozen by an active grab of another client.
|
|||
|
|
|||
|
To release a grab of a device, use XIUngrabDevice.
|
|||
|
|
|||
|
[[requests-ungrabdevice]]
|
|||
|
┌───
|
|||
|
XIUngrabDevice
|
|||
|
deviceid: DEVICEID
|
|||
|
time: TIMESTAMP or CurrentTime
|
|||
|
└───
|
|||
|
|
|||
|
This request releases the device if this client has it actively grabbed
|
|||
|
(from either XIGrabDevice or XIPassiveGrabDevice) and
|
|||
|
releases any queued events. If any devices were frozen by the grab,
|
|||
|
XIUngrabDevice thaws them.
|
|||
|
|
|||
|
deviceid
|
|||
|
The device to grab.
|
|||
|
time
|
|||
|
A valid server time or CurrentTime.
|
|||
|
|
|||
|
The request has no effect if the specified time is earlier than the
|
|||
|
last-device-grab time or is later than the current server time.
|
|||
|
This request generates FocusIn and FocusOut events.
|
|||
|
An XIUngrabDevice is performed automatically if the event window for an
|
|||
|
active device grab becomes not viewable.
|
|||
|
|
|||
|
[[requests-allowevents]]
|
|||
|
┌───
|
|||
|
XIAllowEvents:
|
|||
|
deviceid: DEVICEID
|
|||
|
time: TIMESTAMP or CurrentTime
|
|||
|
event_mode: { AsyncDevice, SyncDevice,
|
|||
|
AsyncPairedDevice, SyncPairedDevice,
|
|||
|
ReplayDevice, AsyncPair, SyncPair,
|
|||
|
AcceptTouch¹, RejectTouch¹ }
|
|||
|
touchid¹: CARD32
|
|||
|
grab_window¹: Window
|
|||
|
└───
|
|||
|
|
|||
|
¹ since XI 2.2
|
|||
|
|
|||
|
The XIAllowEvents request releases some queued events if the client
|
|||
|
has caused a device to freeze. It also is used to handle touch grab and
|
|||
|
ownership processing.
|
|||
|
|
|||
|
deviceid
|
|||
|
The device to grab.
|
|||
|
time
|
|||
|
A valid server time or CurrentTime.
|
|||
|
event_mode
|
|||
|
Specifies whether a device is to be thawed and events are to be
|
|||
|
replayed, or how to handle a grabbed touch sequence.
|
|||
|
touchid
|
|||
|
The ID of the touch sequence to accept or reject. The value is undefined
|
|||
|
for event modes other than AcceptTouch and RejectTouch.
|
|||
|
grab_window
|
|||
|
The window on which to accept or reject a touch sequence grab. The value
|
|||
|
is undefined for event modes other than AcceptTouch and RejectTouch.
|
|||
|
|
|||
|
The request has no effect if the specified time is earlier than the last-grab
|
|||
|
time of the most recent active grab for the client, or if the specified time is
|
|||
|
later than the current X server time. The time parameter must be CurrentTime for
|
|||
|
requests with event modes of AcceptTouch and RejectTouch.
|
|||
|
|
|||
|
When event-mode is AcceptTouch, a BadValue error occurs if the touch ID is
|
|||
|
invalid. A BadAccess error occurs if this client is not the current or potential
|
|||
|
owner of the specified touch ID.
|
|||
|
|
|||
|
The following describes the processing that occurs depending on what constant
|
|||
|
you pass to the event-mode argument:
|
|||
|
|
|||
|
AsyncDevice:
|
|||
|
If the specified device is frozen by the client, event processing for that
|
|||
|
device continues as usual. If the device is frozen multiple times by the
|
|||
|
client on behalf of multiple separate grabs, AsyncDevice thaws for
|
|||
|
all.
|
|||
|
AsyncDevice has no effect if the specified device is not frozen by the
|
|||
|
client, but the device need not be grabbed by the client.
|
|||
|
SyncDevice:
|
|||
|
If the specified device is frozen and actively grabbed by the client,
|
|||
|
event processing for that device continues normally until the next
|
|||
|
event is reported to the client. At this time, the specified device
|
|||
|
again appears to freeze. However, if the reported event causes the
|
|||
|
grab to be released, the specified device does not freeze.
|
|||
|
SyncDevice has no effect if the specified device is not frozen by the
|
|||
|
client or is not grabbed by the client.
|
|||
|
ReplayDevice:
|
|||
|
If the specified device is actively grabbed by the client and is frozen
|
|||
|
as the result of an event having been sent to the client (either from
|
|||
|
the activation of a XIGrabButton or from a previous XIAllowEvents with
|
|||
|
mode SyncDevice, but not from a Grab), the grab is released and
|
|||
|
that event is completely reprocessed. This time, however, the request
|
|||
|
ignores any passive grabs at or above (towards the root) the
|
|||
|
grab-window of the grab just released.
|
|||
|
The request has no effect if the specified device is not grabbed by
|
|||
|
the client or if it is not frozen as the result of an event.
|
|||
|
AsyncPairedDevice
|
|||
|
If the paired master device is frozen by the client, event processing
|
|||
|
for it continues as usual. If the paired device is frozen multiple
|
|||
|
times by the client on behalf of multiple separate grabs,
|
|||
|
AsyncPairedDevice thaws for all.
|
|||
|
AsyncPairedDevice has no effect if the device is not frozen by the
|
|||
|
client, but those devices need not be grabbed by the client.
|
|||
|
AsyncPairedDevice has no effect if deviceid specifies a slave device.
|
|||
|
SyncPairedDevice
|
|||
|
If the paired master device is frozen by the client, event processing (for
|
|||
|
the paired master device) continues normally until the next button or key
|
|||
|
event is reported to the client for the grabbed device (button event for
|
|||
|
the grabbed device, key or motion event for the device), at which time
|
|||
|
the device again appears to freeze. However, if the reported event causes
|
|||
|
the grab to be released, then the device does not freeze.
|
|||
|
SyncPairedDevice has no effect if the specified device is not grabbed
|
|||
|
by the client or if it is no frozen as the result of an event.
|
|||
|
SyncPairedDevice has no effect if deviceid specifies a slave device.
|
|||
|
SyncPair
|
|||
|
If both the device and the paired master device are frozen by the
|
|||
|
client, event processing (for both devices) continues normally until
|
|||
|
the next XIButtonPress, XIButtonRelease, XIKeyPress, or XIKeyRelease
|
|||
|
event is reported to the client for a grabbed device (button event for
|
|||
|
a pointer, key event for a keyboard), at which time the devices again
|
|||
|
appear to freeze. However, if the reported event causes the grab to be
|
|||
|
released, then the devices do not freeze (but if the other device is
|
|||
|
still grabbed, then a subsequent event for it will still cause both
|
|||
|
devices to freeze).
|
|||
|
SyncPair has no effect unless both the device and the paired master
|
|||
|
device are frozen by the client. If the device or paired master device
|
|||
|
is frozen twice by the client on behalf of two separate grabs,
|
|||
|
SyncPair thaws for both (but a subsequent freeze for SyncPair will
|
|||
|
only freeze each device once).
|
|||
|
SyncPair has no effect if deviceid specifies a slave device.
|
|||
|
AsyncPair
|
|||
|
If the device and the paired master device are frozen by the client,
|
|||
|
event processing for both devices continues normally. If a device is
|
|||
|
frozen twice by the client on behalf of two separate grabs, AsyncBoth
|
|||
|
thaws for both. AsyncPair has no effect unless both the device and the
|
|||
|
paired master device frozen by the client.
|
|||
|
AsyncPair has no effect if deviceid specifies a slave device.
|
|||
|
AcceptTouch
|
|||
|
The client is deemed to have taken control of the touch sequence once it
|
|||
|
owns the sequence. TouchEnd events will be sent to all clients listening
|
|||
|
to the touch sequence that have either grabbed the touch sequence on a
|
|||
|
child window of the grab_window or have received events for the touch
|
|||
|
sequence through event selection. These clients will no longer receive
|
|||
|
any TouchUpdate events.
|
|||
|
RejectTouch
|
|||
|
The client is no longer interested in the touch sequence, and will
|
|||
|
receive a TouchEnd event. If the client is the current owner of the
|
|||
|
sequence, ownership will be passed on to the next listener.
|
|||
|
|
|||
|
[[requests-passivegrabdevice]]
|
|||
|
┌───
|
|||
|
XIPassiveGrabDevice
|
|||
|
deviceid: DEVICE
|
|||
|
detail: CARD32
|
|||
|
grab_type: GRABTYPE
|
|||
|
grab_window: Window
|
|||
|
cursor: Cursor
|
|||
|
owner_events: Bool
|
|||
|
grab_mode: { Synchronous, Asynchronous, Touch¹ }
|
|||
|
paired_device_mode: { Synchronous, Asynchronous }
|
|||
|
num_modifiers: INT16
|
|||
|
mask_len: CARD16
|
|||
|
masks: SETofEVENTMASK
|
|||
|
modifiers: CARD32 or GrabAnyModifier
|
|||
|
▶
|
|||
|
num_modifiers_return: INT16
|
|||
|
modifiers_return: GRABMODIFIERINFO
|
|||
|
└───
|
|||
|
|
|||
|
GRABTYPE { GrabtypeButton, GrabtypeKeycode, GrabtypeEnter,
|
|||
|
GrabtypeFocusIn, GrabtypeTouchBegin¹ }
|
|||
|
|
|||
|
GRABMODIFIERINFO { status: Access
|
|||
|
modifiers: CARD32 }
|
|||
|
|
|||
|
¹ since XI 2.2
|
|||
|
|
|||
|
Establish an explicit passive grab for a button or keycode
|
|||
|
on the specified input device.
|
|||
|
|
|||
|
cursor
|
|||
|
The cursor to display for the duration of the grab. If grab_type
|
|||
|
is not GrabtypeButton, this argument is ignored.
|
|||
|
deviceid
|
|||
|
The device to establish the passive grab on or AllDevices or
|
|||
|
AllMasterDevices.
|
|||
|
detail
|
|||
|
The button number, or key symbol to grab for.
|
|||
|
Must be 0 for GrabtypeEnter, GrabtypeFocusIn, and
|
|||
|
GrabtypeTouchBegin.
|
|||
|
grab_type
|
|||
|
The type of grab to establish.
|
|||
|
grab_window
|
|||
|
Events are reported relative to the grab window.
|
|||
|
grab_mode
|
|||
|
If grab-mode is Asynchronous, device event processing continues
|
|||
|
normally. If the device is currently frozen by this client, then
|
|||
|
processing of device events is resumed. If grab-mode is
|
|||
|
Synchronous, the state of the grabbed device (as seen by means of
|
|||
|
the protocol) appears to freeze, and no further device events are
|
|||
|
generated by the server until the grabbing client issues a
|
|||
|
releasing XIAllowEvents request or until the device grab is
|
|||
|
released. Actual device input events are not lost while the device
|
|||
|
is frozen; they are simply queued for later processing. If grab_type
|
|||
|
is GrabtypeTouchBegin, grab_mode must be set to Touch.
|
|||
|
mask_len
|
|||
|
Length of mask in 4 byte units.
|
|||
|
mask
|
|||
|
Event mask. An event mask for an event type T is defined as (1 << T).
|
|||
|
modifiers
|
|||
|
XKB modifier state to activate this passive grab.
|
|||
|
num_modifiers
|
|||
|
Number of elements in modifiers.
|
|||
|
owner_events
|
|||
|
Specifies whether event will be reported normally or relative to the
|
|||
|
grab window.
|
|||
|
num_modifiers_return
|
|||
|
Number of elements in modifiers_return
|
|||
|
modifiers_return
|
|||
|
XKB modifier state that could not be grabbed.
|
|||
|
|
|||
|
If owner-events is False, input events generated from this device are
|
|||
|
reported with respect to grab-window, and are only reported if
|
|||
|
selected by being included in the event-list. If owner-events is
|
|||
|
True, then if a generated event would normally be reported to this
|
|||
|
client, it is reported normally, otherwise the event is reported
|
|||
|
with respect to the grab-window, and is only reported if selected
|
|||
|
by being included in the event-list. For either value of
|
|||
|
owner-events, unreported events are discarded.
|
|||
|
|
|||
|
If deviceid specifies a master pointer, the modifiers of the paired
|
|||
|
master keyboard are used. If deviceid specifies a slave pointer
|
|||
|
the modifiers of the master keyboard paired with the attached master
|
|||
|
pointers are used. If deviceid specifies a slave keyboard, the
|
|||
|
modifiers of the attached master keyboard are used. Note that
|
|||
|
activating a grab on a slave device detaches the device from its
|
|||
|
master. In this case, the modifiers after activation of the grab are
|
|||
|
from the slave device only and may be different to the modifier state
|
|||
|
when the grab was triggered.
|
|||
|
|
|||
|
In the future, if grab_type is GrabtypeButton or GrabtypeKeyboard, the
|
|||
|
device is actively grabbed if:
|
|||
|
|
|||
|
- the device is not grabbed, and
|
|||
|
- the specified modifier keys are down, and
|
|||
|
- the grab_type is GrabtypeButton and the button specified in detail
|
|||
|
is logically pressed or the grab_type is GrabtypeKeycode and the
|
|||
|
keycode specified in detail is logically pressed, and
|
|||
|
- the grab_window contains the pointer, and
|
|||
|
- a passive grab on the same button/keycode + modifier
|
|||
|
combination does not exist on an ancestor of grab_window.
|
|||
|
|
|||
|
Otherwise, if grab_type is GrabtypeEnter or GrabtypeFocusIn, the
|
|||
|
device is actively grabbed if:
|
|||
|
|
|||
|
- the device is not actively grabbed, and
|
|||
|
- the specified modifier keys are down, and
|
|||
|
- the grab_type is GrabtypeEnter and the device's pointer has moved
|
|||
|
into grab_window or a descendant of grab_window, or the grab_type is
|
|||
|
GrabtypeFocusIn and the device's focus has been set to the
|
|||
|
grab_window or a descendant of grab_window, and
|
|||
|
- a passive grab of the same grab_type + modifier combination does not
|
|||
|
does not exist on an ancestor of grab_window.
|
|||
|
|
|||
|
Otherwise, if grab_type is GrabtypeTouchBegin, a touch grab begins if:
|
|||
|
|
|||
|
- the device is not actively grabbed, and
|
|||
|
- the specified modifier keys are down
|
|||
|
- a touch begins in grab_window or a descendant of grab_window, and
|
|||
|
- a passive grab of the same grab_type + modifier combination does not
|
|||
|
does not exist on an ancestor of grab_window.
|
|||
|
|
|||
|
Ownership of the touch sequence is granted to the grabbing client if:
|
|||
|
|
|||
|
- a TouchBegin or pointer grab for an emulated touch sequence of a
|
|||
|
direct touch device with the same modifier set does not exist on
|
|||
|
an ancestor of grab_window, or all applicable grabs have released
|
|||
|
ownership.
|
|||
|
|
|||
|
A modifier of GrabAnyModifier is equivalent to issuing the request for
|
|||
|
all possible modifier combinations (including no modifiers). A client
|
|||
|
may request a grab for GrabAnyModifier and explicit modifier
|
|||
|
combinations in the same request.
|
|||
|
|
|||
|
A GrabtypeButton or GrabtypeKeyboard grab is released when all buttons
|
|||
|
or keycode are released, independent of the state of modifier keys.
|
|||
|
A GrabtypeEnter or GrabtypeFocusIn grab is released when the
|
|||
|
pointer or focus leaves the window and all of its descendants,
|
|||
|
independent of the state of modifier keys.
|
|||
|
A GrabtypeTouchBegin grab is released when the touch sequence ends or
|
|||
|
the client uses XIAllowEvents with mode RejectTouch.
|
|||
|
Note that the logical state of a device (as seen by means of the
|
|||
|
protocol) may lag the physical state if device event processing is
|
|||
|
frozen.
|
|||
|
|
|||
|
This request overrides all previous passive grabs by the same
|
|||
|
client on the same button/key/enter/focus in + modifier combinations
|
|||
|
on the same window.
|
|||
|
|
|||
|
If some other client already has issued a XIPassiveGrabDevice request
|
|||
|
with the same button or keycode and modifier combination, the
|
|||
|
failed modifier combinations is returned in modifiers_return. If some
|
|||
|
other client already has issued an XIPassiveGrabDevice request of
|
|||
|
grab_type XIGrabtypeEnter, XIGrabtypeFocusIn, or
|
|||
|
XIGrabtypeTouchBegin with the same grab_window and the same
|
|||
|
modifier combination, the failed modifier combinations are returned
|
|||
|
in modifiers_return. If num_modifiers_return is zero, all passive
|
|||
|
grabs have been successful.
|
|||
|
|
|||
|
If a button grab or enter grab activates, EnterNotify and LeaveNotify
|
|||
|
events with mode Grab are generated as if the pointer were to suddenly
|
|||
|
warp from its current position some position in the grab_window.
|
|||
|
However, the pointer does not warp, and the pointer position is used
|
|||
|
as both the initial and final positions for the events.
|
|||
|
|
|||
|
If a keycode grab or focus grab activates, FocusIn and FocusOut events
|
|||
|
with mode Grab are generated as if the focus were to change from the
|
|||
|
current window to the grab_window.
|
|||
|
|
|||
|
If an enter or focus in grab activates, additional EnterNotify events
|
|||
|
with mode XIPassiveGrabNotify are generated as if the pointer or focus
|
|||
|
were to suddenly warp from its current position to some position in
|
|||
|
the grab window. These events are sent to the grabbing client only
|
|||
|
and only if the grab event mask has selected for it. If such a passive
|
|||
|
grab deactivates, addional LeaveNotify events with mode
|
|||
|
XIPassiveUngrabNotify are generated and sent to the grabbing client
|
|||
|
before the grab deactivates.
|
|||
|
|
|||
|
For GrabtypeTouchBegin, grab_mode must be Touch or a BadValue error
|
|||
|
is generated.
|
|||
|
|
|||
|
See section <<multitouch-ownership, Ownership of touch sequences>> for
|
|||
|
additional notes on touch grabs, as they do not behave like traditional
|
|||
|
grabs: in particular, they do not freeze the device, and delivery of touch
|
|||
|
events continues even if the device is frozen due to a grab by another
|
|||
|
client.
|
|||
|
|
|||
|
[[requests-passiveungrabdevice]]
|
|||
|
┌───
|
|||
|
XIPassiveUngrabDevice
|
|||
|
deviceid: DEVICEID
|
|||
|
detail: CARD32
|
|||
|
grab_type: GRABTYPE
|
|||
|
grab_window: Window
|
|||
|
num_modifiers: INT16
|
|||
|
modifiers: MODIFIERINFO
|
|||
|
└───
|
|||
|
|
|||
|
Release an explicit passive grab on the specified input device.
|
|||
|
|
|||
|
deviceid
|
|||
|
The device to establish the passive grab on.
|
|||
|
detail
|
|||
|
The button number or key symbol to ungrab.
|
|||
|
Must be 0 for GrabtypeEnter, GrabtypeFocusIn, and
|
|||
|
GrabtypeTouchBegin.
|
|||
|
grab_type
|
|||
|
The type of grab to establish.
|
|||
|
grab_window
|
|||
|
Events are reported relative to the grab window.
|
|||
|
modifiers
|
|||
|
XKB modifier state to activate this passive grab.
|
|||
|
num_modifiers
|
|||
|
Number of elements in modifiers.
|
|||
|
|
|||
|
This request has no effect if the client does not have a passive grab
|
|||
|
of the same type, same button or keycode (if applicable) and modifier
|
|||
|
combination on the grab_window.
|
|||
|
|
|||
|
[[requests-listproperties]]
|
|||
|
┌───
|
|||
|
XIListProperties
|
|||
|
deviceid: DEVICEID
|
|||
|
▶
|
|||
|
num_properties: INT16
|
|||
|
properties: LISTofATOM
|
|||
|
└───
|
|||
|
|
|||
|
List the properties associated with the given device.
|
|||
|
|
|||
|
deviceid
|
|||
|
The device to list the properties for.
|
|||
|
num_atoms
|
|||
|
Number of atoms in the reply
|
|||
|
atoms
|
|||
|
All properties on the device.
|
|||
|
|
|||
|
[[requests-changeproperty]]
|
|||
|
┌───
|
|||
|
XIChangeProperty
|
|||
|
deviceid: DEVICEID
|
|||
|
property: ATOM
|
|||
|
type: ATOM
|
|||
|
format: { 8, 16, 32 }
|
|||
|
mode: { Append, Prepend, Replace }
|
|||
|
num_items: CARD32
|
|||
|
data: LISTofINT8, or LISTofINT16, or LISTofINT32
|
|||
|
└───
|
|||
|
|
|||
|
Change the given property on the given device.
|
|||
|
|
|||
|
deviceid
|
|||
|
The device to change the property on.
|
|||
|
property
|
|||
|
The property to modify.
|
|||
|
type
|
|||
|
The property's type.
|
|||
|
mode
|
|||
|
One of Append, Prepend, or Replace
|
|||
|
num_items
|
|||
|
Number of items following this request.
|
|||
|
data
|
|||
|
Property data (nitems * format/8 bytes)
|
|||
|
|
|||
|
The type is uninterpreted by the server. The format specifies whether
|
|||
|
the data should be viewed as a list of 8-bit, 16-bit, or 32-bit
|
|||
|
quantities so that the server can correctly byte-swap as necessary.
|
|||
|
|
|||
|
If the mode is Replace, the previous propert y value is discarded. If
|
|||
|
the mode is Prepend or Append, then the type and format must match the
|
|||
|
existing property value (or a Match error results). If the property is
|
|||
|
undefined, it is treated as defined with the correct type and format
|
|||
|
with zero-length data. For Prepend, the data is tacked on to the
|
|||
|
beginning of the existing data, and for Append, it is tacked on to the
|
|||
|
end of the existing data.
|
|||
|
|
|||
|
The lifetime of a property is not tied to the storing client. Properties
|
|||
|
remain until explicitly deleted, until the device is removed, or
|
|||
|
until server reset.
|
|||
|
|
|||
|
A property cannot be deleted by setting nitems to zero. To delete a
|
|||
|
property, use XIDeleteProperty.
|
|||
|
|
|||
|
This request generates an XIPropertyEvent.
|
|||
|
|
|||
|
[[requests-deleteproperty]]
|
|||
|
┌───
|
|||
|
XIDeleteProperty
|
|||
|
deviceid: DEVICEID
|
|||
|
property: ATOM
|
|||
|
└───
|
|||
|
|
|||
|
Deletes the given property on the given device.
|
|||
|
|
|||
|
deviceid
|
|||
|
The device to delete the property on.
|
|||
|
property
|
|||
|
The property to delete.
|
|||
|
|
|||
|
If the property is deleted, an XIPropertyEvent is generated on the device.
|
|||
|
If the property does not exist, this request does nothing.
|
|||
|
|
|||
|
[[requests-getproperty]]
|
|||
|
┌───
|
|||
|
XIGetProperty
|
|||
|
deviceid: DEVICEID
|
|||
|
property: ATOM
|
|||
|
type: Atom or AnyPropertyType
|
|||
|
offset: CARD32
|
|||
|
len: CARD32
|
|||
|
delete: BOOL
|
|||
|
▶
|
|||
|
type: Atom
|
|||
|
bytes_after: CARD32
|
|||
|
num_items: CARD32
|
|||
|
format: { 8, 16, 32 }
|
|||
|
data: LISTofINT8, or LISTofINT16, or LISTofINT32
|
|||
|
└───
|
|||
|
|
|||
|
Get the data for the given property on the given device.
|
|||
|
|
|||
|
deviceid
|
|||
|
The device to retrieve the property data from.
|
|||
|
property
|
|||
|
The property to retrieve the data from..
|
|||
|
type
|
|||
|
The property type to retrieve or AnyPropertyType
|
|||
|
offset
|
|||
|
The offset in 4-byte units.
|
|||
|
len
|
|||
|
Number of bytes to receive in 4-byte units.
|
|||
|
delete
|
|||
|
Delete the property after retrieving the data.
|
|||
|
bytes_after
|
|||
|
Number of unread bytes in the stored property
|
|||
|
num_items
|
|||
|
Number of items in data
|
|||
|
format
|
|||
|
8, 16, or 32
|
|||
|
data
|
|||
|
Property data (nitems * format/8 bytes)
|
|||
|
|
|||
|
If the specified property does not exist for the specified device, then
|
|||
|
the return type is None, the format and bytes-after are zero, and the value is
|
|||
|
empty. The delete argument is ignored in this case. If the specified property
|
|||
|
exists but its type does not match the specified type, then the return
|
|||
|
type is the actual type of the property, the format is the actual format of the
|
|||
|
property (never zero), the bytes-after is the length of the property in bytes
|
|||
|
(even if the format is 16 or 32), and the value is empty. The delete
|
|||
|
argument is ignored in this case. If the specified property exists and
|
|||
|
either AnyPropertyType is specified or the specified type matches the actual
|
|||
|
type of the property, then the return type is the actual type of the property,
|
|||
|
the format is the actual format of the property
|
|||
|
(never zero), and the bytes-after and value are as follows, given:
|
|||
|
N = actual length of the stored property in bytes
|
|||
|
(even if the format is 16 or 32)
|
|||
|
I = 4 * long-offset
|
|||
|
T = N−I
|
|||
|
L = MINIMUM(T, 4 * long-length)
|
|||
|
A = N − (I + L)
|
|||
|
The returned value starts at byte index I in the property (indexing
|
|||
|
from 0), and its length in bytes is L. However, it is a Value error if
|
|||
|
offset is given such that L is negative. The value of bytes_after is A,
|
|||
|
giving the number of trailing unread bytes in the stored property. If
|
|||
|
delete is True and the bytes_after is zero, the property is also
|
|||
|
deleted from the device, and a XIPropertyNotify event is generated on
|
|||
|
the device.
|
|||
|
|
|||
|
[[events]]
|
|||
|
Events
|
|||
|
------
|
|||
|
|
|||
|
An event specifies its length in 4-byte units after the initial 32 bytes.
|
|||
|
Future versions of the protocol may provide additional information
|
|||
|
in the same event, thus increasing the event size. Clients are required to
|
|||
|
always read the number of bytes specified by the event, not the size of the
|
|||
|
event they may have been compiled against.
|
|||
|
|
|||
|
|
|||
|
The following event types are available in XI2.
|
|||
|
|
|||
|
Version 2.0:
|
|||
|
|
|||
|
- HierarchyChanged
|
|||
|
- DeviceChanged
|
|||
|
- KeyPress
|
|||
|
- KeyRelease
|
|||
|
- ButtonPress
|
|||
|
- ButtonRelease
|
|||
|
- Motion
|
|||
|
- RawKeyPress
|
|||
|
- RawKeyRelease
|
|||
|
- RawButtonPress
|
|||
|
- RawButtonRelease
|
|||
|
- RawMotion
|
|||
|
- Enter
|
|||
|
- Leave
|
|||
|
- FocusIn
|
|||
|
- FocusOut
|
|||
|
- PropertyEvent
|
|||
|
|
|||
|
Version 2.2:
|
|||
|
|
|||
|
- TouchBegin
|
|||
|
- TouchUpdate
|
|||
|
- TouchOwnership
|
|||
|
- TouchEnd
|
|||
|
- RawTouchBegin
|
|||
|
- RawTouchUpdate
|
|||
|
- RawTouchEnd
|
|||
|
|
|||
|
All events have a set of common fields specified as EVENTHEADER.
|
|||
|
|
|||
|
|
|||
|
EVENTHEADER { type: BYTE
|
|||
|
extension: BYTE
|
|||
|
sequenceNumber: CARD16
|
|||
|
length: CARD32
|
|||
|
evtype: CARD16
|
|||
|
deviceid: DEVICEID
|
|||
|
time: Time }
|
|||
|
|
|||
|
type
|
|||
|
Always GenericEvent.
|
|||
|
extension
|
|||
|
Always the X Input extension offset.
|
|||
|
sequenceNumber
|
|||
|
Sequence number of last request processed by the server.
|
|||
|
length
|
|||
|
Length in 4-byte units after the initial 32 bytes.
|
|||
|
evtype
|
|||
|
XI-specific event type.
|
|||
|
deviceid
|
|||
|
Numerical device id for a device.
|
|||
|
time
|
|||
|
Time in ms when the event occurred.
|
|||
|
|
|||
|
|
|||
|
[[events-xi20]]
|
|||
|
Events introduced in version 2.0
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
[[events-hierarchyevent]]
|
|||
|
┌───
|
|||
|
HierarchyEvent:
|
|||
|
EVENTHEADER
|
|||
|
flags: SETofHIERARCHYMASK
|
|||
|
num_info: CARD16
|
|||
|
info: LISTofHIERARCHYINFO
|
|||
|
└───
|
|||
|
|
|||
|
|
|||
|
HIERARCHYMASK { MasterAdded, MasterRemoved, SlaveAttached, SlaveDetached,
|
|||
|
SlaveAdded, SlaveRemoved, DeviceEnabled, DeviceDisabled }
|
|||
|
|
|||
|
HIERARCHYINFO { deviceid: DEVICEID,
|
|||
|
attachment: DEVICEID,
|
|||
|
type: DEVICEUSE
|
|||
|
enabled: BOOL
|
|||
|
flags: SETofHIERARCHYMASK}
|
|||
|
|
|||
|
flags
|
|||
|
Set of the changes that have occured, causing this event.
|
|||
|
num_info
|
|||
|
The number of device info structs following the request.
|
|||
|
info:
|
|||
|
The current hierarchy information.
|
|||
|
|
|||
|
An XIHierarchyEvent is sent whenever the device hierarchy been
|
|||
|
changed. The flags specify all types of hierarchy modifiations that have
|
|||
|
occured.
|
|||
|
For all devices, info details the hierarchy information after the
|
|||
|
modification of the hierarchy has occured. For each device specified with
|
|||
|
deviceid:
|
|||
|
|
|||
|
- if type is MasterPointer or MasterKeyboard, attachment decribes the
|
|||
|
pairing of this device.
|
|||
|
- if type is SlavePointer or SlaveKeyboard, attachment describes the
|
|||
|
master device this device is attached to.
|
|||
|
- if type is FloatingSlave device, attachment is undefined.
|
|||
|
|
|||
|
enabled
|
|||
|
True if the device is enabled and can send events. A disabled master
|
|||
|
device will not forward events from an attached, enabled slave
|
|||
|
device.
|
|||
|
|
|||
|
Note: Multiple devices may be affected in one hierarchy change,
|
|||
|
deviceid in an XIHierarchyEvent is always the first affected
|
|||
|
device. Clients should ignore deviceid and instead use the devices list.
|
|||
|
|
|||
|
[[events-devicechangedevent]]
|
|||
|
┌───
|
|||
|
DeviceChangedEvent:
|
|||
|
EVENTHEADER
|
|||
|
reason: CHANGEREASON
|
|||
|
source: DEVICEID
|
|||
|
num_classes: CARD16
|
|||
|
classes: LISTofCLASS
|
|||
|
└───
|
|||
|
|
|||
|
CHANGEREASON { SlaveSwitch, DeviceChange }
|
|||
|
|
|||
|
A DeviceChangeEvent is sent whenever a device changes it's capabilities.
|
|||
|
This can happen either by a new slave device sending events through a
|
|||
|
master device, or by a physical device changing capabilities at runtime.
|
|||
|
|
|||
|
reason
|
|||
|
The reason for generating this event.
|
|||
|
If reason is SlaveSwitch, the slave device sending events through
|
|||
|
this device has changed and source specifies the new slave device.
|
|||
|
A SlaveSwitch reason can only occur on a master device.
|
|||
|
If reason is DeviceChange, the device itself has changed through
|
|||
|
other means (e.g. a physical device change) and source is
|
|||
|
the device itself.
|
|||
|
source
|
|||
|
The source of the new classes.
|
|||
|
num_classes
|
|||
|
Number of classes provided.
|
|||
|
classes
|
|||
|
Details the available classes provided by the device. The order the
|
|||
|
classes are provided in is undefined.
|
|||
|
|
|||
|
For a detailed description of classes, see the XIQueryDevice request.
|
|||
|
|
|||
|
[[events-deviceevent]]
|
|||
|
┌───
|
|||
|
DeviceEvent:
|
|||
|
EVENTHEADER
|
|||
|
detail: CARD32
|
|||
|
root: Window
|
|||
|
event: Window
|
|||
|
child: Window
|
|||
|
root_x: FP1616
|
|||
|
root_y: FP1616
|
|||
|
event_x: FP1616
|
|||
|
event_y: FP1616
|
|||
|
buttons_len: CARD16
|
|||
|
valuators_len: CARD16
|
|||
|
sourceid: DEVICEID
|
|||
|
mods: MODIFIERINFO
|
|||
|
group: GROUPINFO
|
|||
|
flags: DEVICEEEVENTFLAGS
|
|||
|
buttons: SETofBUTTONMASK
|
|||
|
valuators: SETofVALUATORMASK
|
|||
|
axisvalues: LISTofFP3232
|
|||
|
└───
|
|||
|
|
|||
|
BUTTONBIT { (1 << Button1), (1 << Button2), ... , (1 << ButtonN) }
|
|||
|
VALUATORBIT { (1 << 1), ( 1 << 2), ... ( 1 << n) }
|
|||
|
|
|||
|
MODIFIERINFO { base_mods: CARD32,
|
|||
|
latched_mods: CARD32,
|
|||
|
locked_mods: CARD32,
|
|||
|
effective_mods: CARD32}
|
|||
|
GROUPINFO { base_group: CARD8,
|
|||
|
latched_group: CARD8,
|
|||
|
locked_group: CARD8,
|
|||
|
effective_group: CARD8}
|
|||
|
|
|||
|
DEVICEEVENTFLAGS (all events): none
|
|||
|
DEVICEEVENTFLAGS (key events only): { KeyRepeat }
|
|||
|
DEVICEEVENTFLAGS (pointer events only): { PointerEmulated }
|
|||
|
DEVICEEVENTFLAGS (touch events only): { TouchPendingEnd,
|
|||
|
TouchEmulatingPointer }
|
|||
|
|
|||
|
An XIDeviceEvent is generated whenever the logical state of a device
|
|||
|
changes in response to a button press, a button release, a motion, a key
|
|||
|
press or a key release. The event type may be one of KeyPress,
|
|||
|
KeyRelease, ButtonPress, ButtonRelease, Motion.
|
|||
|
|
|||
|
XI 2.2: The event type may also be TouchBegin, TouchUpdate, or TouchEnd.
|
|||
|
|
|||
|
detail
|
|||
|
The button number, key code, touch ID, or 0.
|
|||
|
root
|
|||
|
event
|
|||
|
child
|
|||
|
The root window, event window or subwindow, respectively. See core
|
|||
|
protocol specification for more detail.
|
|||
|
root_x
|
|||
|
root_y
|
|||
|
The position of the pointer in screen coordinates (16.16 fixed point).
|
|||
|
event_x
|
|||
|
event_y
|
|||
|
The position of the pointer in screen coordinates relative to the
|
|||
|
event window (16.16 fixed point).
|
|||
|
|
|||
|
buttons_len
|
|||
|
The length of buttons in 4 byte units.
|
|||
|
valuators_len
|
|||
|
The length of valuators in 4 byte units.
|
|||
|
sourceid
|
|||
|
The source device that originally generated the event.
|
|||
|
mods
|
|||
|
XKB modifier state before the event occured.
|
|||
|
group
|
|||
|
XKB group state before the event.
|
|||
|
buttons
|
|||
|
Button state before the event.
|
|||
|
valuators
|
|||
|
Bitmask of valuators provided in axisvalues.
|
|||
|
axisvalues
|
|||
|
Valuator data in device-native resolution.
|
|||
|
flags
|
|||
|
Miscellaneous information about this event; the union of the
|
|||
|
common flag set and either the key or pointer flag set,
|
|||
|
depending on the event type.
|
|||
|
KeyRepeat means that this event is for repeating purposes, and
|
|||
|
the physical state of the key has not changed. This is only
|
|||
|
valid for KeyPress events.
|
|||
|
PointerEmulated signals that the event has been emulated from another
|
|||
|
XI 2.x event for legacy client support, and that this event should
|
|||
|
be ignored if the client listens for these events. This flag is
|
|||
|
set on scroll ButtonPress and RawButtonPress events (buttons 4, 5, 6
|
|||
|
and 7) if a smooth-scrolling event on the Rel Vert Scroll or
|
|||
|
Rel Horiz Scroll axes was also generated. It is also set on Motion,
|
|||
|
ButtonPress, and ButtonRelease events generated by direct touch devices.
|
|||
|
TouchPendingEnd (for touch events only) means that the touch
|
|||
|
has physically ended, however another client still holds a grab, so the
|
|||
|
touch should be considered alive until all grabbing clients have
|
|||
|
accepted or passed on ownership. The touch will not generate any
|
|||
|
further TouchUpdate events once an event with TouchPendingEnd has been
|
|||
|
received.
|
|||
|
TouchEmulatingPointer is set on touch events that emulate pointer
|
|||
|
events.
|
|||
|
|
|||
|
Modifier state in mods is detailed as follows:
|
|||
|
|
|||
|
base_mods
|
|||
|
XKB base modifier state.
|
|||
|
latched_mods
|
|||
|
XKB latched modifier state.
|
|||
|
locked_mods
|
|||
|
XKB locked modifier state.
|
|||
|
|
|||
|
Group state in group is detailed as follows:
|
|||
|
base_group
|
|||
|
XKB base group state.
|
|||
|
latched_group
|
|||
|
XKB latched group state.
|
|||
|
locked_group
|
|||
|
XKB locked group state.
|
|||
|
|
|||
|
In servers supporting XI 2.2, a TouchBegin event is generated whenever a new
|
|||
|
touch sequence initializes.
|
|||
|
A TouchEnd event is generated whenever a touch sequence ceases. A
|
|||
|
TouchUpdate event is generated whenever a valuator value changes, or a flag
|
|||
|
flag (e.g. pending end) has changed for that touch sequence; this may result
|
|||
|
in a TouchUpdate event being sent with zero valuators.
|
|||
|
|
|||
|
The average finger size is significantly larger than one pixel. The
|
|||
|
selection of the hotspot of a touchpoint is implementation dependent and
|
|||
|
may not be the logical center of the touch.
|
|||
|
|
|||
|
Touch tracking IDs are provided in the detail field of touch events. Its
|
|||
|
value is always provided in every touch event. Tracking IDs are
|
|||
|
represented as unsigned 32-bit values and increase strictly monotonically in
|
|||
|
value for each new touch, wrapping back to 0 upon reaching the numerical limit
|
|||
|
of IDs. The increment between two touch IDs is indeterminate. Clients may not
|
|||
|
assume that any future touches will have specific touch IDs. IDs are globally
|
|||
|
unique.
|
|||
|
|
|||
|
The button state in touch events represents the state of the device's
|
|||
|
physical buttons only, even if that sequence is emulating pointer events.
|
|||
|
|
|||
|
Touch events do not generate enter/leave events.
|
|||
|
|
|||
|
[[events-rawevent]]
|
|||
|
┌───
|
|||
|
RawEvent
|
|||
|
EVENTHEADER
|
|||
|
detail: CARD32
|
|||
|
sourceid¹: DEVICEID
|
|||
|
flags: DEVICEEVENTFLAGS
|
|||
|
valuators_len: CARD16
|
|||
|
valuators: SETofVALUATORMASK
|
|||
|
axisvalues: LISTofFP3232
|
|||
|
axisvalues_raw: LISTofFP3232
|
|||
|
└───
|
|||
|
|
|||
|
¹ since XI 2.1
|
|||
|
|
|||
|
A RawEvent provides the information provided by the driver to the
|
|||
|
client. RawEvent provides both the raw data as supplied by the driver and
|
|||
|
transformed data as used in the server. Transformations include, but are
|
|||
|
not limited to, axis clipping and acceleration.
|
|||
|
Transformed valuator data may be equivalent to raw data. In this case,
|
|||
|
both raw and transformed valuator data is provided.
|
|||
|
RawEvents are sent exclusively to all root windows.
|
|||
|
Clients supporting XI 2.0 receive raw events when the device is not grabbed,
|
|||
|
or when the device is grabbed by the client but not when the device is
|
|||
|
grabbed by another client.
|
|||
|
Clients supporting XI 2.1 or later receive raw events at all times, even
|
|||
|
when the device is grabbed by another client.
|
|||
|
|
|||
|
|
|||
|
eventtype
|
|||
|
The type of event that occured on the device.
|
|||
|
detail
|
|||
|
The button number, keycode or touch ID¹.
|
|||
|
sourceid
|
|||
|
The source device that originally generated the event. The sourceid
|
|||
|
is undefined for clients not supporting XI 2.1.
|
|||
|
flags
|
|||
|
Flags as described in DeviceEvent.
|
|||
|
valuators_len
|
|||
|
The length of valuators in 4 byte units.
|
|||
|
valuators
|
|||
|
Bitmask of valuators provided in axisvalues and axisvalues_raw.
|
|||
|
axisvalues
|
|||
|
Valuator data in device-native resolution.
|
|||
|
axisvalues_raw
|
|||
|
Untransformed valuator data in device-native resolution.
|
|||
|
|
|||
|
¹ since XI 2.2
|
|||
|
|
|||
|
[[events-enterleave]]
|
|||
|
┌───
|
|||
|
Enter or Leave or FocusIn or FocusOut
|
|||
|
EVENTHEADER
|
|||
|
root: Window
|
|||
|
event: Window
|
|||
|
child: Window
|
|||
|
sourceid: DEVICEID
|
|||
|
root_x: FP1616
|
|||
|
root_y: FP1616
|
|||
|
event_x FP1616
|
|||
|
event_y: FP1616
|
|||
|
mode: NOTIFYMODE
|
|||
|
detail: NOTIFYDETAIL
|
|||
|
same_screen: BOOL
|
|||
|
focus: BOOL
|
|||
|
mods: MODIFIERINFO
|
|||
|
group: GROUPINFO
|
|||
|
buttons_len: CARD16
|
|||
|
buttons: SETofBUTTONMASK
|
|||
|
└───
|
|||
|
|
|||
|
NOTIFYMODE { Normal, Grab, Ungrab }
|
|||
|
NOTIFYDETAIL { Ancestor, Virtual, Inferior, Nonlinear, NonlinearVirtual,
|
|||
|
Pointer, PointerRoot, None }
|
|||
|
|
|||
|
Enter or Leave events are sent whenever a device's pointer enters or
|
|||
|
leaves a window.
|
|||
|
FocusIn or FocusOut events are sent whenever a device's focus is set to or
|
|||
|
away from a window.
|
|||
|
The enter/leave and focus in/out model is described in the core protocol
|
|||
|
specification, Section 11. (EnterNotify, LeaveNotify events).
|
|||
|
|
|||
|
For enter and leave events, the modifier and group state is the state of
|
|||
|
the paired master device if the device is a master device, or the state of
|
|||
|
the attached master keyboard if the device is an attached slave device, or
|
|||
|
zero if the device is a floating slave device.
|
|||
|
|
|||
|
For focus in and out events, the button state is the state of the paired
|
|||
|
master device if the device is a master device, or the state of the
|
|||
|
attached master keyboard if the device is an attached slave device, or
|
|||
|
zero if the device is a floating slave device.
|
|||
|
|
|||
|
root
|
|||
|
event
|
|||
|
child
|
|||
|
The root window, event window, and child window, respectively. See the
|
|||
|
core protocol specification for more detail.
|
|||
|
sourceid
|
|||
|
The device that caused the pointer to move.
|
|||
|
root_x
|
|||
|
root_y
|
|||
|
The pointer coordinates relative to the root window.
|
|||
|
event_x
|
|||
|
event_y
|
|||
|
The pointer coordinates relative to the event window.
|
|||
|
mode
|
|||
|
Normal pointer motion events have mode Normal. Pseudo-motion events
|
|||
|
when a grab activates have mode Grab, and pseudo-motion events when a
|
|||
|
grab deactivates have mode Ungrab. Pseudo-motion events caused by the
|
|||
|
activation or deactivation of a passive enter or focus in grab have mode
|
|||
|
XIPassiveGrabNotify or XIPassiveUngrabNotify.
|
|||
|
detail
|
|||
|
Specifies the relation of the event window to the window the pointer
|
|||
|
entered or left. See the core protocol spec for details.
|
|||
|
same_screen
|
|||
|
True if the event window is on the same screen as the pointer's root
|
|||
|
window.
|
|||
|
focus
|
|||
|
If the event window is the focus window or an inferior of the focus
|
|||
|
window, then focus is True. Otherwise, focus is False. This field is
|
|||
|
unspecified for focus in/out events.
|
|||
|
mods
|
|||
|
XKB modifier state before the event occured.
|
|||
|
group
|
|||
|
XKB group state before the event.
|
|||
|
buttons_len
|
|||
|
The length of buttons in 4 byte units.
|
|||
|
buttons
|
|||
|
Button state before the event.
|
|||
|
|
|||
|
[[events-propertyevent]]
|
|||
|
┌───
|
|||
|
XIPropertyEvent
|
|||
|
EVENTHEADER
|
|||
|
property: ATOM
|
|||
|
what: { PropertyCreated, PropertyDeleted, PropertyModified }
|
|||
|
└───
|
|||
|
|
|||
|
XIPropertyEvents are sent whenever a device property is created, deleted or
|
|||
|
modified by a client.
|
|||
|
|
|||
|
property
|
|||
|
The property that has been created, deleted, or modified
|
|||
|
what
|
|||
|
Specifies what has been changed.
|
|||
|
|
|||
|
[[events-xi22]]
|
|||
|
Events introduced in version 2.2
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
|||
|
[[events-touchownershipevent]]
|
|||
|
┌───
|
|||
|
TouchOwnershipEvent
|
|||
|
EVENTHEADER
|
|||
|
touchid: CARD32
|
|||
|
root: Window
|
|||
|
event: Window
|
|||
|
child: Window
|
|||
|
sourceid: DEVICEID
|
|||
|
flags: SETofTOUCHOWNERSHIPFLAGS
|
|||
|
└───
|
|||
|
|
|||
|
TOUCHOWNERSHIPFLAGS: (none currently defined)
|
|||
|
|
|||
|
A TouchOwnershipEvent indicates that ownership has changed, and the client
|
|||
|
is now the owner of the touch sequence specified by touchid.
|
|||
|
|
|||
|
touchid
|
|||
|
The identifier of the touch sequence.
|
|||
|
root
|
|||
|
event
|
|||
|
child
|
|||
|
The root window, event window, and child window, respectively. See the
|
|||
|
core protocol specification for more detail.
|
|||
|
sourceid
|
|||
|
The source device that originally generated the event.
|
|||
|
flags
|
|||
|
A bitmask of flags for this event.
|
|||
|
|
|||
|
|
|||
|
:numbered!:
|
|||
|
[[xi22-usecases]]
|
|||
|
[appendix]
|
|||
|
XI 2.2 Use-cases
|
|||
|
----------------
|
|||
|
|
|||
|
All use-cases that include the receiving and processing of touch events
|
|||
|
require the client to announce XI 2.2 support in the XIQueryVersion request.
|
|||
|
|
|||
|
Client C wants to process touch events from a device D on window W.
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
* C calls XISelectEvent for XI_Touch{Begin|Update|End} from D on W.
|
|||
|
* C receives TouchBegin whenever a touch sequence starts within W's borders.
|
|||
|
* C receives TouchUpdate events whenever an axis valuator value changes for a
|
|||
|
touch sequence it received a TouchBegin event for.
|
|||
|
* C receives TouchEnd whenever a touch it received a TouchBegin event for
|
|||
|
ceases.
|
|||
|
|
|||
|
While client I wants to pre-process touch events from device D on the parent window of W.
|
|||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|||
|
* C calls XISelectEvent for XI_Touch{Begin|Update|Ownership|End} from D on W.
|
|||
|
* I calls XIPassiveGrab for XI_Touch{Begin|Update|Ownership|End} from D on a
|
|||
|
parent window of W.
|
|||
|
* I receives TouchBegin whenever a touch begins within window W, as well as a
|
|||
|
TouchOwnership event indicating that it currently owns the touch sequence.
|
|||
|
C receives a TouchBegin event as well, but without TouchOwnership.
|
|||
|
* When an axis valuator changes in this touch sequence, both I and C receive a
|
|||
|
TouchUpdate event. I may process the event to determine if it is going to
|
|||
|
accept or reject the touch, whereas C may perform reversible processing.
|
|||
|
* If I decides it is going to claim the touch sequence for its exclusive
|
|||
|
processing, it calls XIAllowEvents with an event mode of XIAcceptTouch; at
|
|||
|
this point, C receives a TouchEnd event, and undoes any processing it has
|
|||
|
already performed due to the touch sequence. Further TouchUpdate events are
|
|||
|
delivered only to I.
|
|||
|
* Alternatively, if I decides it does not want to receive further events
|
|||
|
from this touch sequence, it calls XIAllowEvents with an event mode of
|
|||
|
XIRejectTouch; at this point, I receives a TouchEnd event confirming that it
|
|||
|
has rejected the touch. C receives a TouchOwnership event confirming that it
|
|||
|
is now the new owner of the touch, and further TouchUpdate events are
|
|||
|
delivered only to C. As C now owns the touch, it is free to perform
|
|||
|
irreversible processing of the sequence.
|
|||
|
* When the touch physically ceases, a TouchEnd event is sent to C.
|
|||
|
|
|||
|
While client I wants to process pointer events on window W's parent, window Y.
|
|||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|||
|
* I calls XIPassiveGrab for XI_{ButtonPress,MotionNotify,ButtonRelease} to
|
|||
|
create a synchronous pointer grab from D on Y.
|
|||
|
* C calls XISelectEvent for XI_Touch{Begin|Update|Ownership|End} from D on W.
|
|||
|
* I receives a ButtonPress event whenever a touch begins within W, and is
|
|||
|
considered the owner of the event. C receives a TouchBegin event, but does
|
|||
|
not receive a TouchOwnership event.
|
|||
|
* When the touchpoint moves, C will receive a TouchUpdate event. Event
|
|||
|
delivery to I is subject to the synchronous delivery mechanism. The
|
|||
|
emulated motion notify event is queued in the server while the device is
|
|||
|
frozen.
|
|||
|
* I may assert ownership by calling XIAllowEvents on Y with any mode other
|
|||
|
than ReplayDevice, which will cause all further events to be sent only to I,
|
|||
|
with a TouchEnd event being sent to C.
|
|||
|
* Alternatively, I may reject the touch sequence by calling XIAllowEvents on
|
|||
|
Y with mode ReplayDevice, which will cause no further events from that touch
|
|||
|
to be sent to I, and a TouchOwnership event to be sent to C, with subsequent
|
|||
|
motion events being sent as TouchUpdate events.
|
|||
|
|
|||
|
Driver DRV provides touch support from tracked device D:
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
* DRV initializes a TouchClass for the device.
|
|||
|
* DRV parses D's device protocol and selects one touch sequence to be emulated
|
|||
|
as pointer event.
|
|||
|
* DRV calls the respective input driver API with the touch sequence data. The
|
|||
|
touch sequence emulating a pointer has the respective flag set. DRV does not
|
|||
|
submit pointer data for any touchpoint.
|