Linux Type-B Multitouch: Track Contact Identity Separately from the Slot Number

In a Linux Type-B touchscreen stream, a slot is a reusable state container. A tracking ID identifies the contact currently occupying it. Treating the slot number as a permanent finger identity can join two unrelated touches into one drag after the first contact lifts.

This guide uses the Linux v6.12 multitouch protocol for an embedded HMI’s event decoder. It assumes an uninterrupted Type-B event stream and a known initial state. It does not claim that a stock LVGL pointer driver implements a multitouch gesture system. Event-loss recovery and coordinate calibration need separate handling.

Keep a state record for each slot

The upstream protocol describes Type B as a stateful protocol: events update selected slot attributes, and values omitted from a report remain unchanged. ABS_MT_SLOT selects the slot for subsequent multitouch data. ABS_MT_TRACKING_ID gives the contact identity; a value of -1 marks the slot as unused.

A decoder therefore needs both the currently selected slot and an array of slot records. Each record contains its current tracking ID and supported attributes, such as position. The active-contact set is derived from valid tracking IDs, not from the number of slot-selection events seen in the latest report.

Initialize or obtain state through the product’s supported input-startup path before interpreting deltas. Starting halfway through an unknown stream and filling every omitted field with zero does not reconstruct a trustworthy contact history.

Follow one contact through a partial update

Consider this hypothetical first report, with two supported slots and illustrative coordinate units:

ABS_MT_SLOT          0
ABS_MT_TRACKING_ID   101
ABS_MT_POSITION_X    100
ABS_MT_POSITION_Y    200
ABS_MT_SLOT          1
ABS_MT_TRACKING_ID   202
ABS_MT_POSITION_X    400
ABS_MT_POSITION_Y    500
SYN_REPORT

After the report, contact 101 occupies slot zero at (100, 200) and contact 202 occupies slot one at (400, 500). The current selected slot is one. A second report can select slot zero, update only its X coordinate to 110, and end with SYN_REPORT.

The resulting first contact is at (110, 200). Its Y value remains 200. The second contact remains active at (400, 500) even though the report contains no update for it. Resetting unmentioned slots or axes would manufacture releases and jumps that the device never reported.

Four Type-B reports retain unchanged slot state, release contact 101, then reuse slot zero for a new contact with tracking ID 303.
Original synthetic Type-B state table. Slot storage is reused while contact identity changes.

Original state-transition example. Values are synthetic; unchanged fields are retained rather than regenerated from each report.

End identity before reusing storage

At the end of that second report, slot zero remains selected. A later ABS_MT_TRACKING_ID event with value -1, followed by SYN_REPORT, can release that slot without repeating ABS_MT_SLOT. The selector persists across reports. A parser that resets its selector at every synchronization event may apply this release to the wrong contact.

Now reuse slot zero with tracking ID 303 and a newly reported position (70, 90). The slot storage is familiar; the contact is new. End contact 101’s gesture history before admitting 303. Do not compute the new contact’s first movement from the old contact’s final coordinates.

Preserve the slot’s already valid axis state across this identity change when the initial state is known and no events have been lost. Reset per-contact gesture history, not the underlying slot-axis cache. Linux v6.12’s input event handler filters unchanged axis values against that cache, while slot-state reporting changes tracking identity without clearing X and Y.

As an alternate reuse fixture, start from the released slot’s valid (110, 200) state. Report new ID 303 and X value 70, but omit Y because it remains 200. At SYN_REPORT, the new contact is at (70, 200). It needs new gesture history, not another Y event. Requiring all coordinates to be resent for every new ID could suppress a valid contact indefinitely.

Publish a coherent report

Collect the state changes until SYN_REPORT, then deliver the resulting coherent contact snapshot or equivalent ordered change set to the HMI’s gesture owner. Updating the UI after every individual axis event could expose an intermediate pair containing new X and old Y before the report is complete.

Type A’s contact-separating SYN_MT_REPORT is a different protocol mechanism. Do not insert that assumption into a Type-B parser. Also keep event decoding separate from decisions such as which finger controls a single-pointer widget: the decoder should preserve the available contacts before a product-specific adapter selects one.

Review with a small replay table

A proposed software-only replay should cover four outcomes: the initial two-contact state, the X-only update with retained Y, the release without a repeated selector, and reuse of the same slot with a new ID. Compare complete state after each SYN_REPORT, not only the last received event.

Add a negative assertion that no movement segment connects contact 101 to contact 303. Count active contacts from slot state and verify that contact 202 survives reports which mention only slot zero. Finally, qualify event-loss and reconnect handling separately before relying on the decoder in a product. An uninterrupted synthetic trace establishes the intended state machine; it does not prove recovery from a dropped kernel event stream.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *