Commit 40475261 authored by Peter Hutterer's avatar Peter Hutterer

dix: add touch event history helper functions

If touch client has not registered for ownership events and a grab above
that client is rejected, the client needs to receive the complete event

The history currently doesn't really do fancy overflow handling. We assume
that the first TOUCH_HISTORY_SIZE events are the important ones and anything
after that is dropped. If that is a problem, fix the client that takes > 100
event to decide whether to accept or reject.

Events marked with TOUCH_CLIENT_ID or TOUCH_REPLAYING must not be stored in
the history, they are events created by the DIX to comply with the protocol.
Any such event should already be in the history anyway.

A fixme in this patch: we don't have a function to actually deliver the
event yet.
Signed-off-by: default avatarPeter Hutterer <>
Reviewed-by: default avatarChase Douglas <>
parent b274c472
......@@ -35,6 +35,9 @@
#include "eventstr.h"
#include "exevents.h"
/* If a touch queue resize is needed, the device id's bit is set. */
static unsigned char resize_waiting[(MAXDEVICES + 7)/8];
......@@ -394,6 +397,112 @@ TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti)
ti->num_grabs = 0;
ti->client_id = 0;
* Allocate the event history for this touch pointer. Calling this on a
* touchpoint that already has an event history does nothing but counts as
* as success.
* @return TRUE on success, FALSE on allocation errors
TouchEventHistoryAllocate(TouchPointInfoPtr ti)
if (ti->history)
return TRUE;
ti->history = calloc(TOUCH_HISTORY_SIZE, sizeof(*ti->history));
ti->history_elements = 0;
if (ti->history)
ti->history_size = TOUCH_HISTORY_SIZE;
return ti->history != NULL;
TouchEventHistoryFree(TouchPointInfoPtr ti)
ti->history = NULL;
ti->history_size = 0;
ti->history_elements = 0;
* Store the given event on the event history (if one exists)
* A touch event history consists of one TouchBegin and several TouchUpdate
* events (if applicable) but no TouchEnd event.
* If more than one TouchBegin is pushed onto the stack, the push is
* ignored, calling this function multiple times for the TouchBegin is
* valid.
TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev)
if (!ti->history)
case ET_TouchBegin:
/* don't store the same touchbegin twice */
if (ti->history_elements > 0)
case ET_TouchUpdate:
case ET_TouchEnd:
return; /* no TouchEnd events in the history */
/* We only store real events in the history */
ti->history[ti->history_elements++] = *ev;
/* FIXME: proper overflow fixes */
if (ti->history_elements > ti->history_size - 1)
ti->history_elements = ti->history_size - 1;
DebugF("source device %d: history size %d overflowing for touch %u\n",
ti->sourceid, ti->history_size, ti->client_id);
TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource)
InternalEvent *tel = InitEventList(GetMaximumEventsNum());
ValuatorMask *mask = valuator_mask_new(0);
int i, nev;
int flags;
if (!ti->history)
valuator_mask_set_double(mask, 0, ti->history[0][0]);
valuator_mask_set_double(mask, 1, ti->history[0][1]);
if (ti->emulate_pointer)
/* send fake begin event to next owner */
nev = GetTouchEvents(tel, dev, ti->client_id, XI_TouchBegin, flags, mask);
/* FIXME: deliver the event */
FreeEventList(tel, GetMaximumEventsNum());
/* First event was TouchBegin, already replayed that one */
for (i = 1; i < ti->history_elements; i++)
DeviceEvent *ev = &ti->history[i];
ev->flags |= TOUCH_REPLAYING;
/* FIXME: deliver the event */
......@@ -607,6 +607,10 @@ extern TouchPointInfoPtr TouchBeginTouch(DeviceIntPtr dev, int sourceid,
extern TouchPointInfoPtr TouchFindByClientID(DeviceIntPtr dev,
uint32_t client_id);
extern void TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti);
extern Bool TouchEventHistoryAllocate(TouchPointInfoPtr ti);
extern void TouchEventHistoryFree(TouchPointInfoPtr ti);
extern void TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev);
extern void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource);
/* misc event helpers */
extern Mask GetEventMask(DeviceIntPtr dev, xEvent* ev, InputClientsPtr clients);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment