2716 lines
106 KiB
Plaintext
2716 lines
106 KiB
Plaintext
The X Input Extension 2.x
|
||
=========================
|
||
:toclevels: 3
|
||
: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.3, December 2012: Pointer barrier events added
|
||
- 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-Pointer 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
|
||
|
||
Changes in version 2.3
|
||
----------------------
|
||
|
||
- Pointer barrier events 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 has a keyboard focus other than None, the key event is sent to
|
||
the focus window.
|
||
- 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.
|
||
|
||
Note: the keyboard focus of an attached slave device is independent to that
|
||
of the master device. Two keyboard events are generated, once with deviceid
|
||
and sourceid set to the slave device. This keyboard event is sent to the
|
||
slave device's focus window. The second event has a deviceid of the master
|
||
and a sourceid of the slave device. This second event is delivered to the
|
||
master keyboard's focus window.
|
||
|
||
[[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.
|
||
|
||
|
||
[[barrier-events]]
|
||
Pointer barrier events
|
||
^^^^^^^^^^^^^^^^^^^^^^
|
||
If a master pointer moves against a pointer barrier blocking movement in
|
||
that pointer's direction, the movement of the pointer is clamped to the x or
|
||
y coordinate of the barrier, whichever applies. For a description of pointer
|
||
barriers and barrier creation and destruction see the XFixes protocol
|
||
specification v 5.0 or later.
|
||
http://cgit.freedesktop.org/xorg/proto/fixesproto/plain/fixesproto.txt
|
||
|
||
A pointer hitting a blocking barrier creates a new barrier event sequence,
|
||
identified by a unique event ID. A new event ID is assigned when the pointer
|
||
first hits a barrier. Subsequent movements against or along the pointer
|
||
barrier are assigned the same event ID. The event generated by the pointer
|
||
leaving the barrier, or being released by a client request, is the last
|
||
event with this event ID. Any future movements of this device blocked by
|
||
this barrier will be assigned a new event ID.
|
||
|
||
Pointer barrier events are delivered exclusively to the client that created
|
||
the barrier, and to the window specified in the CreatePointerBarrier
|
||
request (the "barrier window"). A pointer barrier blocks pointer movement
|
||
regardless of whether its window is mapped and/or viewable. If the pointer
|
||
barrier window is destroyed, the pointer barrier remains blocking but a
|
||
client will not receive further events.
|
||
|
||
If a device is actively grabbed by a client or a passive grab activated
|
||
for this client, and the pointer moves against a pointer barrier created by
|
||
this client and the grab-window is the barrier window, that client will
|
||
receive pointer barrier events if:
|
||
- owner-events is true or false and the grab's event mask includes
|
||
pointer barrier events, or
|
||
- owner-events is true and the client has selected for barrier events on the
|
||
barrier window.
|
||
|
||
If the grab-window is not the barrier window, the client will receive events
|
||
if:
|
||
- the client has selected for barrier events on the barrier window.
|
||
|
||
If the barrier is not owned by this client, no barrier events are sent to
|
||
this client. The client owning the barrier will receive events if:
|
||
- the client has pointer barrier events selected on the window associated
|
||
with the pointer barrier
|
||
|
||
The BarrierDeviceIsGrabbed flag is set whenever a pointer barrier event is
|
||
generated while the device is actively grabbed by any client or a passive
|
||
grab has activated for this device prior to the event.
|
||
|
||
[[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.
|
||
|
||
EVTYPEMASK
|
||
An EVTYPEMASK is a binary mask defined as (1 << event type).
|
||
A SETofEVTYPEMASK is a binary OR of zero or more EVTYPEMASK.
|
||
|
||
FP1616
|
||
Fixed point decimal in 16.16 format as one INT16 and one CARD16.
|
||
The INT16 contains the integral part, the CARD16 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.
|
||
|
||
MODIFIERMASK
|
||
A MODIFIERMASK is a binary mask defined as (1 << modifier map index).
|
||
A SETofMODIFIERMASK is a binary OR of zero or more MODIFIERMASK or
|
||
GrabAnyModifier.
|
||
|
||
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
|
||
^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^
|
||
┌───
|
||
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, VALUATORCLASS, SCROLLCLASS, TOUCHCLASS }
|
||
|
||
BUTTONCLASS { type: ButtonClass
|
||
length: CARD16
|
||
sourceid: CARD16
|
||
num_buttons: CARD16
|
||
state: SETofBUTTONMASK
|
||
labels: LISTofATOM }
|
||
|
||
KEYCLASS { type: KeyClass
|
||
length: CARD16
|
||
sourceid: CARD16
|
||
num_keys: CARD16
|
||
keys: LISTofCARD32 }
|
||
|
||
VALUATORCLASS { type: ValuatorClass
|
||
length: CARD16
|
||
sourceid: CARD16
|
||
number: CARD16
|
||
label: ATOM
|
||
min: FP3232
|
||
max: FP3232
|
||
value: FP3232
|
||
resolution: CARD32
|
||
mode: CARD8 }
|
||
|
||
SCROLLCLASS¹ { type: ScrollClass
|
||
length: CARD16
|
||
sourceid: CARD16
|
||
number: 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.
|
||
|
||
ValuatorClass:
|
||
type
|
||
Always ValuatorClass.
|
||
length
|
||
Length in 4 byte units.
|
||
sourceid
|
||
The device this class originates from.
|
||
number
|
||
Valuator number of this axis. The valuator 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.
|
||
number
|
||
Valuator number that is referred to. This valuator 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 valuator number 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
|
||
^^^^^^^^^^^^^^
|
||
┌───
|
||
XISelectEvents
|
||
window: Window
|
||
num_masks: CARD16
|
||
masks: LISTofEVENTMASK
|
||
|
||
└───
|
||
|
||
EVENTMASK { deviceid: DEVICE,
|
||
mask_len: CARD16,
|
||
mask: SETofEVTYPEMASK }
|
||
|
||
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
|
||
^^^^^^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^
|
||
┌───
|
||
XIGetFocus
|
||
deviceid: DEVICEID
|
||
▶
|
||
focus: Window
|
||
└───
|
||
|
||
Return the current focus window for the given device.
|
||
|
||
[[requests-grabdevice]]
|
||
XIGrabDevice
|
||
^^^^^^^^^^^^
|
||
┌───
|
||
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: SETofEVTYPEMASK
|
||
▶
|
||
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
|
||
^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^^^^^^^
|
||
┌───
|
||
XIPassiveGrabDevice
|
||
deviceid: DEVICE
|
||
detail: CARD32
|
||
grab_type: GRABTYPE
|
||
time: TIMESTAMP
|
||
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: SETofEVTYPEMASK
|
||
modifiers: LISTofSETofMODIFIERMASK
|
||
▶
|
||
num_modifiers_return: INT16
|
||
modifiers_return: LISTofGRABMODIFIERINFO
|
||
└───
|
||
|
||
GRABTYPE { GrabtypeButton, GrabtypeKeycode, GrabtypeEnter,
|
||
GrabtypeFocusIn, GrabtypeTouchBegin¹ }
|
||
|
||
GRABMODIFIERINFO { status: Access
|
||
modifiers: SETofMODIFIERMASK }
|
||
|
||
¹ 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.
|
||
time
|
||
This field is unused.
|
||
|
||
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
|
||
^^^^^^^^^^^^^^^^^^^^^
|
||
┌───
|
||
XIPassiveUngrabDevice
|
||
deviceid: DEVICEID
|
||
detail: CARD32
|
||
grab_type: GRABTYPE
|
||
grab_window: Window
|
||
num_modifiers: INT16
|
||
modifiers: LISTofSETofMODIFIERMASK
|
||
└───
|
||
|
||
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
|
||
^^^^^^^^^^^^^^^^
|
||
┌───
|
||
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_properties
|
||
Number of properties in the reply
|
||
properties
|
||
All properties on the device.
|
||
|
||
[[requests-changeproperty]]
|
||
XIChangeProperty
|
||
^^^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^
|
||
┌───
|
||
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.
|
||
|
||
[[requests-xi23]]
|
||
Requests introduced in version 2.3
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
[[requests-barrierreleasepointer]]
|
||
XIBarrierReleasePointer
|
||
^^^^^^^^^^^^^^^^^^^^^^^
|
||
┌───
|
||
XIBarrierReleasePointer
|
||
num_items: CARD32
|
||
▶
|
||
data: LISTofBARRIERRELEASEINFO
|
||
└───
|
||
|
||
BARRIERRELEASEINFO { deviceid: DEVICEID,
|
||
barrier: Barrier,
|
||
eventid: CARD32 }
|
||
|
||
Release a pointer currently blocked by a barrier. In the future, movement of
|
||
this pointer against the barrier will not be blocked.
|
||
|
||
deviceid
|
||
The device currently being blocked by a barrier
|
||
barrier
|
||
The barrier currently blocking the device
|
||
eventid
|
||
The unique event ID assigned to this barrier event sequence
|
||
|
||
If the barrier given does not currently block this device, or the eventid
|
||
is invalid, this request does nothing.
|
||
|
||
Releasing a pointer barrier is only valid during one barrier event sequence,
|
||
and only applies to the next movement of this device against this barrier.
|
||
If the pointer moves away from the barrier following a
|
||
XIBarrierReleasePointer request, the release request is discarded. In the
|
||
future, if the pointer moves against the barrier again, a new eventid is
|
||
assigned and the client must re-issue the XIBarrierReleasePointer request.
|
||
|
||
If the device is not a master pointer device, a BadDevice error results.
|
||
If the barrier does not name a valid barrier, a BadValue error results.
|
||
|
||
|
||
[[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
|
||
|
||
Version 2.3:
|
||
|
||
- BarrierHit
|
||
- BarrierLeave
|
||
|
||
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
|
||
^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^
|
||
┌───
|
||
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. This is a non-sparse
|
||
array, value N represents the axis corresponding to the Nth bit set
|
||
in valuators.
|
||
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
|
||
^^^^^^^^
|
||
┌───
|
||
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. This is a non-sparse
|
||
array, value N represents the axis corresponding to the Nth bit set
|
||
in valuators.
|
||
axisvalues_raw
|
||
Untransformed valuator data in device-native resolution. This is a
|
||
non-sparse array, value N represents the axis corresponding to the
|
||
Nth bit set in valuators.
|
||
|
||
¹ since XI 2.2
|
||
|
||
[[events-enterleave]]
|
||
Enter or Leave or FocusIn or FocusOut
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^^^
|
||
┌───
|
||
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
|
||
^^^^^^^^^^^^^^^^^^^
|
||
┌───
|
||
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.
|
||
|
||
[[events-xi23]]
|
||
Events introduced in version 2.3
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
[[events-barrierevent]]
|
||
BarrierEvent
|
||
^^^^^^^^^^^^
|
||
┌───
|
||
BarrierEvent
|
||
EVENTHEADER
|
||
eventid: CARD32
|
||
root: Window
|
||
event: Window
|
||
barrier: Barrier
|
||
dtime: CARD32
|
||
flags: SETofBARRIERFLAGS
|
||
sourceid: DEVICEID
|
||
root_x: FP1616
|
||
root_y: FP1616
|
||
dx: FP3232
|
||
dy: FP3232
|
||
└───
|
||
|
||
BARRIERFLAGS { PointerReleased, DeviceIsGrabbed }
|
||
|
||
A BarrierEvent indicates interaction between a barrier and a pointer device.
|
||
If the event type is BarrierHit, pointer movement has been blocked by a
|
||
barrier. If the event type is BarrierLeave, a pointer previously blocked
|
||
by a barrier has moved away from that barrier, or has moved
|
||
through the blocking barrier following an earlier XIBarrierReleasePointer
|
||
request.
|
||
|
||
eventid
|
||
The unique event ID for this barrier event sequence.
|
||
root
|
||
event
|
||
The root window or barrier window, respectively. The barrier window
|
||
is always the drawable specified in in the CreatePointerBarrier request.
|
||
barrier
|
||
The barrier blocking pointer movement.
|
||
dtime
|
||
The relative time in milliseconds between the last event and this
|
||
event.
|
||
flags
|
||
A set of flags that apply to this barrier event
|
||
PointerReleased:
|
||
The pointer has moved through the barrier following a
|
||
XIBarrierReleasePointer request (BarrierLeave only).
|
||
DeviceIsGrabbed:
|
||
The pointer device that generated this event is currently
|
||
grabbed.
|
||
sourceid
|
||
The source device that originally generated the event.
|
||
root_x
|
||
root_y
|
||
The position of the pointer in screen coordinates (16.16 fixed
|
||
point), after being constrained by barrier and/or screen extents.
|
||
dx
|
||
dy
|
||
The relative movement of the pointer from its previous position to
|
||
the new position if pointer movement were not constrained by this
|
||
barrier.
|
||
|
||
Root coordinates in barrier events represent the position of the cursor
|
||
after confinement by barriers, screens and RandR output extents.
|
||
|
||
Barrier event IDs are provided in the eventid field of barrier events. Its
|
||
value is always provided in every barrier event. Event IDs are
|
||
represented as unsigned 32-bit values and increase strictly monotonically in
|
||
value for each new barrier event sequence, wrapping back to 0 upon reaching
|
||
the numerical limit of IDs. The increment between two event IDs is
|
||
indeterminate. Clients may not assume that any future barrier constraints
|
||
will have specific event IDs. IDs are unique per device per barrier.
|
||
|
||
If a pointer is actively grabbed after a barrier event sequence has
|
||
initiated, future barrier events of this sequence continue to use the same
|
||
eventid, but all barrier events have the DeviceIsGrabbed flag set. If the
|
||
pointer is ungrabbed, future events of this sequence have the same eventid
|
||
and the DeviceIsGrabbed flag is unset.
|
||
|
||
The PointerReleased flag may only be set on a BarrierLeave event.
|
||
A BarrierLeave(PointerReleased) event is generated when the pointer moves
|
||
through the barrier following a XIBarrierReleasePointer request. The time
|
||
between the XIBarrierReleasePointer and the BarrierLeave event thus depends
|
||
on user input.
|
||
A BarrierLeave(PointerReleased) event is also generated if the barrier is
|
||
destroyed while pointer movement is constrained by the barrier, or the
|
||
master pointer blocked by the barrier is removed. This event
|
||
has a dx/dy of 0/0.
|
||
|
||
: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.
|