diff options
Diffstat (limited to 'specs/XI2proto.txt')
-rw-r--r-- | specs/XI2proto.txt | 2715 |
1 files changed, 2715 insertions, 0 deletions
diff --git a/specs/XI2proto.txt b/specs/XI2proto.txt new file mode 100644 index 0000000..697dd89 --- /dev/null +++ b/specs/XI2proto.txt @@ -0,0 +1,2715 @@ +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. |