[RFC] Multitouch protocol specification v1

Peter Hutterer peter.hutterer at who-t.net
Thu Aug 5 17:27:45 PDT 2010


Below is the first public draft of the multitouch protocol specification,
part of the future X Input Extension version 2.1. Earlier versions of this
draft have been sent around in private and I'd like to thank Chase Douglas,
Carlos Garnacho, Rafi Rubin, Henrik Rydberg, and Daniel Stone for their
feedback during this cycle.

These additions to XI2 aim to:
- provide backwards compatible pointer emulation for single-touch
  interaction,
- support a dynamic number of simultaneous touch points,
- support devices that are both multi-touch and traditional pointer devices.

Below is a diff only, but the history of the spec over time is available
on the multitouch branch on my people.fdo repo.
    git://people.freedesktop.org/~whot/inputproto.git multitouch
Not overly useful though.

Though by no means complete, I think the spec below is good enough to be
reviewed in public and a starting point for the matching server
implementation. As usual, once we've got an implementation it's likely that
parts of the spec need to be changed.

If you can poke holes into the spec, come up with use-cases that are not
covered or have general questions that aren't answered, please point them
out. The sooner, the better.

Typos and similar issues please send to me privately to keep the noise on
the list down.

Cheers,
  Peter

diff --git a/XI2proto.txt b/XI2proto.txt
index 10f58c2..3ce6b81 100644
--- a/XI2proto.txt
+++ b/XI2proto.txt
@@ -1,6 +1,7 @@
 
                             The X Input Extension
                                 Version 2.0
+                                Version 2.1
 
                               Peter Hutterer
                          peter.hutterer at redhat.com
@@ -31,6 +32,40 @@ 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).
 
+1.1 X Input Extension version 2.1 (XI 2.1)
+XI 2.1 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 multiple independent input points per physical device.
+Furthermore, such devices are often direct input devices, the virtual
+abstraction of master devices is not necessary.
+
+The additions in XI 2.1 aim to:
+- provide backwards compatible pointer emulation for single-touch
+  interaction,
+- support a dynamic number of simultaneous touch points,
+- support devices that are both multi-touch and traditional pointer devices.
+
+XI 2.1 caters for two modes of touch input devices:
+- direct multi-touch input devices such as touch screens. These devices
+  provide independent touchpoints that can occur anywhere on the screen and
+  are usually the result of direct touch interaction.
+- indirect touch input devices such as multi-touch trackpads. These devices
+  provide independent touchpoints that may need to be interpreted
+  relative to the current position of the pointer on that same device. Such
+  interactions are usually the result of a gesture performed on the device.
+
+A device may change its touch mode at runtime. Clients are informed which
+type of touch device they are dealing with. See XIQueryDevice for more
+information.
+
+Touch device support is only available to clients supporting version 2.1 or
+later of the X Input Extension. Clients must use the XIQueryVersion request to
+announce support of this version.
+
+XI 2.1 requires devices to track touch points over time. Devices that cannot
+do so in hardware must employ software trackers to be useable with XI 2.1.
+
                               ❧❧❧❧❧❧❧❧❧❧❧
 
 2. Notations used in this document
@@ -149,7 +184,42 @@ 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.
 
-4.4. The ClientPointer principle
+4.4 Touch device support
+Touch event processing differs from normal event processing in ways, most
+notably in that touch events are processed partially out-of-band from
+pointer and keyboard events.
+
+Touch input follows a three-stage cycle: init - move - destroy, i.e.
+"init" the sequence by touching the device, "move" the current touch
+location, "destroy" the sequence by ceasing to touch the device.
+The init and destroy stage of this sequence are always present, the move
+stage is optional.
+Within this document, the term "touch sequence" is used to describe the
+above chain of events.
+
+For ease of understanding, it helps to think of a touch event sequence as a
+temporary input device that is automatically destroyed. Some grabs operate
+on a touch sequence only, not on the actual device.
+
+If a passive grab is activated in response to a touch sequence
+initialization, this grab is only active for the touch sequence and will be
+released once the touch sequence is destroyed.
+Meanwhile, other touch sequences by the same slave device may trigger
+additional passive grabs, or the device may otherwise deliver events to any
+client.
+
+A touch event is delivered according to the device hierarchy. A touch event is
+however not affected by pointer or keyboard grabs on the respective slave
+and/or master device. If a device is temporarily detached as a result of a
+slave device grab, touch events are still routed through the respective
+master device.
+
+A device that sends touch events may also generate pointer events on demand.
+The decision which touch events are converted into pointer events is
+implementation-specific. Emulated pointer/keyboard events follow the core
+and XI2 grab semantics.
+
+4.5. The ClientPointer principle
 
 Many core protocol and some extension requests are ambiguous when multiple
 master devices are available (e.g. QueryPointer does not specfy which pointer).
@@ -271,7 +341,7 @@ are required to be 0.
                  name:                  LISTofCHAR8
                  classes:               LISTofCLASS }
 
-    CLASS { BUTTONCLASS, KEYCLASS, AXISCLASS }
+    CLASS { BUTTONCLASS, KEYCLASS, AXISCLASS, TOUCHCLASS*, TOUCHAXISCLASS* }
 
     BUTTONCLASS { type:                 ButtonClass
                   length:               CARD16
@@ -296,6 +366,26 @@ are required to be 0.
                   value:                FP3232
                   resolution:           CARD32 }
 
+    TOUCHCLASS* { type:                 TouchClass
+                  length:               CARD16
+                  sourceid:             CARD16
+                  mode:                 TOUCHMODE
+                  num_touchpoints:      CARD16 }
+
+    TOUCHAXISCLASS* {
+                  type:                 TouchAxisClass
+                  length:               CARD16
+                  sourceid:             CARD16
+                  axisnumber:           CARD16
+                  label:                ATOM
+                  min:                  FP3232
+                  max:                  FP3232
+                  resolution:           CARD32 }
+
+    TOUCHMODE* { DirectTouch, DependentTouch }
+
+    * since XI 2.1
+
     XIQueryDevice details information about the requested input devices.
 
     devices
@@ -397,6 +487,54 @@ are required to be 0.
     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.
 
+    XI 2.1:
+
+    TouchClass:
+    type
+        Always TouchClass.
+    length
+        Length in 4 byte units.
+    sourceid
+        The device this class originates from.
+    touch_mode
+        The device type of the touch device. Touch sequences from a device
+        of type DirectTouch should be interpreted as directly occuring on
+        the position they are reported on. Touch sequences from a device of
+        type DependentTouch should be interpreted as dependent of the
+        current position of the pointer.
+    num_touchpoints
+        The number of touchpoints the device may be using at most.
+        If num_touchpoints is 0, the number of supported touchpoints is
+        unknown.
+
+    A device with a TouchClass must provide one or more TOUCHAXISCLASS
+    specifiers.
+
+    TouchAxisClass:
+    type
+        Always TouchAxisClass.
+    length
+        Length in 4 byte units.
+    sourceid
+        The device this class originates from.
+    axisnumber
+        Axis number of this axis. The axis number is in device-native
+        order and potential axis mappings are ignored.
+    label
+        Atom specifying the axis name. An Atom of None specifies an unlabeled
+        axis.
+    min
+        Minimum value.
+    max
+        Minimum value.
+    resolution
+        Resolution in counts/meter.
+
+    Devices generating touch events must provide exactly one TouchClass and
+    one or more TouchAxisClasses. TouchAxisClasses and AxisClasses are not
+    interchangable. A TouchAxisClass may only be part of a touch event,
+    whereas a AxisClass may only be part of a DeviceEvent.
+
     ┌───
         XISelectEvents
             window:         Window
@@ -864,12 +1002,34 @@ are required to be 0.
 
     To release a grab of a device, use XIUngrabDevice.
 
+    XI 2.1:
+    The delivery of touch events is unaffected by a grab unless the grab's
+    event mask specifies one or more of the XITouchDownEvent, the
+    XITouchUpEvent or the XITouchMoveEvent mask. Likewise, a device grab
+    selecting only touch events does not affect pointer and/or keyboard
+    event delivery.  A device may thus be actively grabbed by two clients
+    simultaneously.
+
+    A grab request with an event mask that is already grabbed by another
+    client returns AlreadyGrabbed. Once a client has grabbed a device with
+    either the XITouchDownEvent or the XITouchMoveEvent or the
+    XITouchUpEvent mask, all future touch sequences are sent to this client
+    only. For selective grabbing of touch sequences, use XIGrabTouches
+    instead.
+
+    A grab with the XITouchSequenceEvents mask set returns a BadValue error.
+
     ┌───
         XIUngrabDevice
             deviceid:        DEVICEID
             time:            TIMESTAMP or CurrentTime
+            mode*:           SETofUNGRABFLAGS
     └───
 
+    UNGRABFLAGS { UngrabPointerKeyboard, UngrabTouch }
+
+    * since XI 2.1
+
     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,
@@ -879,6 +1039,8 @@ are required to be 0.
         The device to grab.
     time
         A valid server time or CurrentTime.
+    mode
+        Specifies which type of grab to ungrab.
 
     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.
@@ -886,15 +1048,29 @@ are required to be 0.
     An XIUngrabDevice is performed automatically if the event window for an
     active device grab becomes not viewable.
 
+    XI 2.1:
+    A client must specify which part of the device to ungrab. If the client
+    ungrabs with a mode of UngrabPointerKeyboard, the device is ungrabbed
+    for pointer and keyboard events. If the client ungrabs with a mode of
+    UngrabTouch, the device is ungrabbed for touch events. If the client
+    ungrabs with both flags set, the device is fully ungrabbed.
+
+    A mode currently not grabbed on the device is ignored. For XI 2.0
+    clients, the mode is always UngrabPointerKeyboard.
+
     ┌───
         XIAllowEvents:
             deviceid:        DEVICEID
             time:            TIMESTAMP or CurrentTime
             event_mode:      { AsyncDevice, SyncDevice,
                                AsyncPairedDevice, SyncPairedDevice,
-                               ReplayDevice, AsyncPair, SyncPair }
+                               ReplayDevice, AsyncPair, SyncPair,
+                               ReplayOneTouch* }
+            tracking_id*:    CARD32
     └───
 
+    * since XI 2.1
+
     The XIAllowEvents request releases some queued events if the client
     has caused a device to freeze.
 
@@ -905,6 +1081,9 @@ are required to be 0.
     event_mode
         Specifies whether a device is to be thawed and events are to be
         replayed.
+    tracking_id
+        Specifies the touch tracking_id of the touch event to be replayed,
+        sync'd or async'd.
 
     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
@@ -919,6 +1098,15 @@ are required to be 0.
         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.
+
+        XI 2.1:
+        If tracking_id is None and the client has an active touch grab
+        on the device, the behaviour is as for pointer or keyboard events.
+
+        If tracking_id is not None and the client has an active grab on the
+        tracking_id as a result of XIGrabTouches, this touch sequence grab
+        is thawed.
+
     SyncDevice:
         If the specified device is frozen and actively grabbed by the client,
         event processing for that device continues normally until the next
@@ -927,6 +1115,14 @@ are required to be 0.
         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.
+
+        XI 2.1:
+        If tracking_id is None and the client has an active touch grab
+        on the device, the behaviour is as for pointer or keyboard events.
+
+        If tracking_id is not None and the client has an active grab on the
+        tracking_id as a result of XIGrabTouches, this touch sequence grab is
+        frozen.
      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
@@ -937,6 +1133,14 @@ are required to be 0.
         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.
+
+        XI 2.1:
+        If tracking_id is None and the client has an active touch grab
+        on the device, the behaviour is as for pointer or keyboard events.
+
+        If tracking_id is not None and the client has an active grab on the
+        tracking_id as a result of XIGrabTouches, this touch sequence grab is
+        released and that event is completely reprocessed.
      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
@@ -978,6 +1182,22 @@ are required to be 0.
         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.
+     ReplayOne:
+        If the specified device is actively grabbed by the client and is
+        frozen as the result of an touch event having been sent to the
+        client, 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.
+        Unlike ReplayDevice, this event mode does not release the grab on
+        the device and the next touch sequence on this device will be frozen
+        again.
+        If tracking_id is not None and this client has an active grab on the
+        tracking_id as a result of XIGrabTouches, this touch event is
+        replayed. Otherwise, if tracking_id is None, the first frozen touch
+        sequence in the queue will be replayed.
+        This mode is only available to clients supporting XI 2.1 and later.
 
     ┌───
         XIPassiveGrabDevice
@@ -999,11 +1219,13 @@ are required to be 0.
     └───
 
         GRABTYPE         { GrabtypeButton, GrabtypeKeycode, GrabtypeEnter,
-                           GrabtypeFocusIn}
+                           GrabtypeFocusIn, GrabtypeTouch* }
 
         GRABMODIFIERINFO {   status:    Access
                              modifiers: CARD32 }
 
+        * since XI 2.1
+
         Establish an explicit passive grab for a button or keycode
         on the specified input device.
 
@@ -1133,6 +1355,19 @@ are required to be 0.
         XIPassiveUngrabNotify are generated and sent to the grabbing client
         before the grab deactivates.
 
+        XI 2.1:
+        If grab_type is GrabTypeTouch, the device is actively grabbed if:
+        - the device is not actively grabbed, and
+        - the specified modifier keys are down, and
+        - the grab_type is Grabtype and a touch sequence has been
+          initialized inside 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.
+
+        A GrabtypeTouch grab is released when the touch sequences ends and
+        an XITouchUpEvent sent.
+
     ┌───
         XIPassiveUngrabDevice
             deviceid:        DEVICEID
@@ -1309,6 +1544,98 @@ are required to be 0.
         the device.  
      
 
+    ┌───
+        XIGrabTouches
+            deviceid:        DEVICEID
+            grab_window:     Window
+            owner_events:    BOOL
+            grab_mode:       { Synchronous, Asynchronous, Ungrab }
+            time:            TIMESTAMP
+            num_ids:         CARD16
+            tracking_id:     LISTofCARD32
+            ▶
+            status:          { Success, InvalidTime, NotViewable, BadMatch }
+            num_ids:         CARD16
+            grab_status:     LISTofGRABSTATUS
+    └───
+
+    GRABSTATUS {Success, AlreadyGrabbed, Frozen, BadMatch}
+
+    Grabs the device for the touches specified in tracking_id. Further events
+    from these touches are sent only to the client with the grab.
+
+    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. If
+        Ungrab is specified as device mode, the touches specified in
+        tracking_id will be ungrabbed.
+    time
+        A valid server time.
+    num_id
+        number of elements in touches
+    tracking_id
+        List of tracking_id
+    status
+        Success if all specified grabs have succeeded,
+        InvalidTime - the specified time is later than the current X server
+                      time,
+        NotViewable - the grab window is not viewable,
+        BadMatch - at least one grab has failed.
+    grab_status
+        The status code for each tracking_id.
+
+    This request issues an active grab on one or more touch event sequences.
+    If status is InvalidTime or NotViewable, all grabs have failed.
+    If status is Success, all grabs have succeeded and num_ids is 0.
+    If one or more grabs have failed, status is BadMatch and a grab status
+    is returned for each tracking_id in the order provided by the client.
+
+    Grab status codes are:
+        Success         - the client has successfully grabbed this touch
+                          point,
+        AlreadyGrabbed  - another client already has a grab on this
+                          touch point,
+        Frozen          - the touchpoint is frozen in result of a sync grab
+                          by another client,
+        BadMatch        - the tracking_id does not exist or has ceased to
+                          exist since.
+
+    Touchpoints initiated later than the specified time will not be grabbed
+    and a BadMatch is returned. The asynchronicity of the X protocol does
+    not guarantee that a tracking_id does not exist in case of a BadMatch
+    error. The tracking_id may have been re-used since the request was
+    issued.
+
+    A touch grab will automatically terminate once the touch sequence
+    is destroyed and all events have been processed. Otherwise, a client
+    must issue a XIGrabTouches request with mode Ungrab to remove the active
+    grab.
+
+    Multiple clients may grab different touch sequences from the same
+    device.  However, if one client has an active grab through XIGrabDevice
+    with a touch event mask, no touch events may be grabbed.
+
+    A grab on a touch does not affect event delivery for pointer and/or
+    keyboard events on this device and it does not affect future or current
+    touch sequences that do not match the tracking id.
+
+    A grab on an already grabbed touch point updates the grab on this
+    touch sequence. If a touch sequence is grabbed as a result of an active
+    or passive grab, XIGrabTouches updates the grab for this specific touch
+    sequence to be a touch sequence grab. Further XIAllowEvents requests do
+    not affect this touch sequence unless the tracking_id is given.
+
+    If the grab_mode is Ungrab, all touch sequences specified in tracking_id
+    that are grabbed by this client are ungrabbed and the touch sequence is
+    thawed. Touchpoints not grabbed or invalid tracking_ids are ignored.
+    This request always returns Success for a grab_mode of Ungrab.
+
 8. Events:
 
 An event specifies its length in 4-byte units after the initial 32 bytes.
@@ -1338,6 +1665,11 @@ Version 2.0:
         FocusIn
         FocusOut
         PropertyEvent
+Version 2.1:
+        TouchSequence
+        TouchUp
+        TouchMove
+        TouchDown
 
 All events have a set of common fields specified as EVENTHEADER.
 
@@ -1481,13 +1813,15 @@ EVENTHEADER { type:                       BYTE
 
     DEVICEEVENTFLAGS (all events): none
     DEVICEEVENTFLAGS (key events only): { KeyRepeat }
-    DEVICEEVENTFLAGS (pointer events only): none
+    DEVICEEVENTFLAGS (pointer events only): { TouchPointer }
 
     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.1: The event type may also be TouchUp, TouchMove, TouchDown.
+
     detail
         The button number or key code, or 0.
     root
@@ -1505,6 +1839,8 @@ EVENTHEADER { type:                       BYTE
 
     buttons_len
         The length of buttons in 4 byte units.
+        XI 2.1: For event types TouchUp, TouchMove, TouchDown, buttons_len
+                is zero.
     valuators_len
         The length of valuators in 4 byte units.
     sourceid
@@ -1517,8 +1853,12 @@ EVENTHEADER { type:                       BYTE
         Button state before the event.
     valuators
         Bitmask of valuators provided in axisvalues.
+        XI 2.1: For event types TouchUp, TouchMove, TouchDown, the valuators
+        are those specified as TouchAxisClass.
     axisvalues
         Valuator data in device-native resolution.
+        XI 2.1: For event types TouchUp, TouchMove, TouchDown, the valuators
+        are those specified as TouchAxisClass.
     flags
         Miscellaneous information about this event; the union of the
         common flag set and either the key or pointer flag set,
@@ -1526,6 +1866,10 @@ EVENTHEADER { type:                       BYTE
         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.
+        TouchPointer means that this event is an emulated pointer event caused
+        by a touch device. A client listening to touch events and pointer
+        events should ignore TouchPointer events to avoid duplicate
+        processing.
 
     Modifier state in mods is detailed as follows:
     base_mods
@@ -1543,6 +1887,25 @@ EVENTHEADER { type:                       BYTE
     locked_group
         XKB locked group state.
 
+    XI 2.1:
+
+    An XITouchDownEvent is generated whenever a new touch sequence
+    initializes. An XITouchUpEvent is generated whenever a touch sequence
+    ceases. An XITouchMoveEvent is generated whenever an existing touch
+    point changes position.
+    XITouchDownEvents do not trigger implicit passive grabs and are sent to
+    respective window underneath the touch location.
+
+    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.
+
+    A client interested in touch sequences should always register for
+    XITouchSequenceEvents. Otherwise, the client has no knowledge if the
+    tracking_id of a touch is being re-used.
+
+    Touch events do not generate enter/leave events.
+
     ┌───
         RawEvent
             EVENTHEADER
@@ -1673,5 +2036,156 @@ EVENTHEADER { type:                       BYTE
     what
         Specifies what has been changed.
      
+    ┌───
+        TouchSequenceEvent:
+            EVENTHEADER
+            tracking_id:                CARD32
+            sourceid:                   DEVICEID
+            flags:                      TOUCHSEQEVENTFLAGS
+    └───
+
+    TOUCHSEQEVENTFLAGS { TouchInit, TouchDestroyed }
+
+    An XITouchSequenceEvent is generated whenever a touch device initializes
+    or destroys a new touchpoint.
+
+    tracking_id
+        Unique tracking number for this touchpoint.
+    sourceid
+        The source device that originally generated the event.
+    flags
+        TouchInit - this tracking_id is now in use by a touch point.
+        TouchDestroy - this tracking_id is not in use by a touch point
+                       anymore.
+
+    The tracking_id is unique per device for the duration of the touch
+    sequence but may be re-used by the server once the touch has ceased.
+
+    An XITouchSequenceEvent with flag TouchInit is always sent before the
+    first XITouchDownEvent of that tracking id and signals (re)use of the
+    tracking id.
+    An XITouchSequenceEvent with flag TouchDestroy is always sent after the
+    last XITouchUpEvent of that tracking id and signals discontinuation of
+    this tracking id.
+
+    XITouchSequenceEvents are sent to all clients and cannot be grabbed.
 
                               ❧❧❧❧❧❧❧❧❧❧❧
+
+
+Appendix A: XI 2.1 Use-cases
+
+All use-cases that include the receiving and processing of touch events
+require the client to announce XI 2.1 support in the XIQueryVersion request.
+
+∙ Client C wants to process touch events from a device D on window W.
+    ⊳ C registers for XITouchSequenceEvents from D on the root window R.
+    ⊳ C registers for XITouch{Down|Move|Up}Event from D on W.
+    ⊳ C receives an XITouchSequenceEvent with flag TouchInit when a new
+      touch sequence initializes.
+    ⊳ C receives XITouchDownEvent whenever a touch sequence starts within
+      W's borders.
+    ⊳ C receives XITouchMoveEvents whenever the touch events are within the
+      borders of W.
+    ⊳ C receives XITouchUpEvent whenever a touch sequence ceases within
+      W's borders.
+    ⊳ C receives XITouchSequenceEvent with TouchDestroyed is sent when the
+      touch sequence stops.
+
+∙ Client C wants temporary exclusive access to all touch events from a
+  device D.
+    ⊳ C registers for XITouchSequenceEvents from D on the root window R.
+    ⊳ C grabs the device with an XIGrabDevice request and the
+      XITouch{Down|Move|Up}Event mask set.
+    ⊳ C receives an XITouchSequenceEvent with flag TouchInit when a new
+      touch sequence initializes.
+    ⊳ C receives an XITouchDownEvent and subsequent XITouchMoveEvents and a
+      XITouchUpEvent for this touch sequence.
+    ⊳ Repeat the above two step until the need for exclusive access is gone.
+    ⊳ C ungrabs the device with an XIUngrabDevice request and the
+      XITouch{Down|Move|Up}Event mask set.
+
+    Comments:
+    - extended asynchronous grabs on a touch device is considered impolite
+      as it blocks others from receiving touch events.
+
+∙ Client C wants temporary exclusive access to intercept certain touch
+  events from a device D.
+    ⊳ C registers for XITouchSequenceEvents from D on the root window R.
+    ⊳ C grabs the device with an XIGrabDevice request and the XITouchDownEvent
+      mask set. The grab mode is Synchronous.
+    ⊳ C receives an XITouchSequenceEvent with flag TouchInit when a new
+      touch sequence initializes.
+    ⊳ C receives an XITouchDownEvent when a new touch sequence initializes.
+        ⊳ If the event is unsuitable for this client, C calls XIAllowEvents
+          with ReplayOneTouch and the touch point's tracking id.
+        ⊳ If the event is suitable for this client, C calls XIGrabTouches
+          with touch point's tracking id.
+    ⊳ Repeat the above step until the need for exclusive access is gone.
+    ⊳ C ungrabs the device with an XIUngrabDevice request and the
+      XITouchDownEvent mask set.
+
+    Comments:
+    - the decision of suitable or unsuitable is context-specific to C.
+    - events replayed with ReplayOneTouch will be received by the next
+      client as if non-intercepted but with a delivery delay. The event time
+      is unaffected by the interception.
+
+∙  Client C needs gesture support from direct touch devices such as
+   touchscreens.
+    ⊳ C registers for XITouchSequenceEvents from XIAllMasterDevices on the root window R.
+    ⊳ C registers for XITouch{Down|Move|Up}Event from XIAllMasterDevices on
+      window W.
+    ⊳ C receives an XITouchSequenceEvent with flag TouchInit when a new
+      touch sequence initializes.
+    ⊳ C receives XITouchDownEvent whenever a touch sequence starts within
+      W's borders.
+    ⊳ C receives XITouchMoveEvents whenever the touch events are within the
+      borders of W.
+    ⊳ C receives XITouchUpEvent whenever a touch sequence ceases within
+      W's borders.
+    ⊳ C receives XITouchSequenceEvent with TouchDestroyed is sent when the
+      touch sequence stops.
+    ⊳ C processes events according to C's gesture interpretation rules.
+    ⊳ C communicates out-of-band with A to notify A of the performed
+      gesture.
+
+    Comments:
+    - Gesture interpretation may be performed in C or a dependent process.
+      If C requires the interpretation of events outside of C's accessible
+      windows, C must grab the device with an XIGrabDevice grab and the
+      XITouch{Down|Move|Up}Event mask set.
+
+∙  Application A needs gesture support from indirect touch device D (e.g. a
+   touchpad).
+    ⊳ Client C registers for XITouchSequenceEvents from D on the root window R.
+    ⊳ C grabs device D with an XIGrabDevice request and the
+      XITouch{Down|Move|Up}Event mask set.
+    ⊳ C receives touch events and processes them according to C's gesture
+      interpretation rules.
+    ⊳ C communicates out-of-band with A to notify A of the performed
+      gesture.
+
+    Comments:
+    - C may be the same process as A. In real-world deployments, it its
+      likely that C is a global gesture recognizer daemon with a defined
+      protocol for gesture interpretation and the resulting actions.
+
+∙  Window manager WM needs to intercept all touch events for window
+   management purposes:
+    ⊳ WM registers for XITouchSequenceEvents from XIAllMasterDevices on the
+      root window R.
+    ⊳ WM requests a passive grab of GrabtypeTouch for XIAllMasterDevices on
+      the root window R and grab mode Synchronous.
+    ⊳ WM receives a XITouchDownEvent when a touch sequence initializes.
+    ⊳ WM performs window manager operations as required
+    ⊳ WM requests XIAllowEvents with mode ReplayDevice on D.
+
+∙  Driver DRV provides touch support from tracked device D:
+    ⊳ DRV initializes a TouchClass for the device and a TouchAxisClass for
+      each axis available on 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg-devel/attachments/20100806/9f7f12ec/attachment-0001.pgp>


More information about the xorg-devel mailing list