summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2010-02-13 00:52:50 +0100
committerBenjamin Tissoires <tissoire@cena.fr>2010-03-15 19:05:34 +0100
commite53d32e016d43592fb660a2a885c0f938890107b (patch)
tree95d80b53a5e29cb5735fd397fbd7ac034972455b
parent502a3853992e172745daa3c8409dd78a446fd9a2 (diff)
Wait until EV_SYNC to process/send MT events.
In the case where tracking ID is not offered by the device, and the event order is not guaranteed (N-Trig device behaves like this), we need to collect all MT events in order to assign the most likely subdev to an event. If no closest subdevice is found to an MT event, a new subdev is used to route it. If the tracking ID is provided, the events are directly correlated with the matching subdevice in EV_SYNC. Signed-off-by: Carlos Garnacho <carlosg@gnome.org> Signed-off-by: Benjamin Tissoires <tissoire@cena.fr>
-rw-r--r--src/evdev.c113
-rw-r--r--src/evdev.h15
2 files changed, 87 insertions, 41 deletions
diff --git a/src/evdev.c b/src/evdev.c
index f56a208..cc03976 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -598,9 +598,10 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
pEvdev->abs |= ABS_MT_X_VALUE;
else if (ev->code == ABS_MT_POSITION_Y)
pEvdev->abs |= ABS_MT_Y_VALUE;
- else if (ev->code == ABS_MT_TRACKING_ID)
+ else if (ev->code == ABS_MT_TRACKING_ID) {
pEvdev->current_id = ev->value;
- else
+ pEvdev->has_tracking_id = TRUE;
+ } else
pEvdev->abs |= ABS_VALUE;
}
@@ -705,6 +706,7 @@ EvdevFindUnallocatedSubdev(InputInfoPtr pInfo)
if (pSubdevInfo && !pSubdevInfo->used && pSubdevInfo->id == -1) {
pSubdevInfo->used = TRUE;
+ pSubdevInfo->id = i + 1; /* 0 means no id */
return pSubdevInfo;
}
}
@@ -713,6 +715,14 @@ EvdevFindUnallocatedSubdev(InputInfoPtr pInfo)
}
+static void
+EvdevCopyFromTouchData(InputInfoPtr pInfo, EvdevTouchDataPtr pTouchData, int id) {
+ EvdevPtr pEvdev = pInfo->private;
+
+ memcpy(pEvdev->vals, pTouchData->vals, MAX_VALUATORS * sizeof(int));
+ pEvdev->vals[pEvdev->axis_map[ABS_MT_TRACKING_ID]] = id;
+}
+
/**
* Post the release of mt-events that were not send before.
*/
@@ -721,27 +731,59 @@ EvdevPostMTMotionEvents(InputInfoPtr pInfo, struct input_event *ev)
{
EvdevPtr pEvdev = pInfo->private;
EvdevSubdevInfoPtr pSubdevInfo;
- InputInfoPtr pSubdev;
+ EvdevSubdevInfoPtr subdev_map[MAX_VALUATORS_MT] = { 0 };
+ EvdevTouchDataPtr pTouchData;
int i;
- for (i = 0; i < pEvdev->num_multitouch; ++i) {
- pSubdevInfo = &(pEvdev->subdev_info[i]);
+ for (i = 0; i < pEvdev->num_mt_events; ++i) {
+ pTouchData = &pEvdev->mt_events[i];
+ pSubdevInfo = EvdevFindMatchingIdSubdevInfo(pInfo, pTouchData->id);
+
+ if (!pSubdevInfo) {
+ /* There was no previous subdev for this tracking ID */
+ pSubdevInfo = EvdevFindUnallocatedSubdev(pInfo);
+
+ if (pSubdevInfo)
+ pSubdevInfo->id = pTouchData->id;
+ }
+
+ subdev_map[i] = pSubdevInfo;
+ }
+
+ /* Now, actually process the MT events,
+ * routing through the mapped subdevs
+ */
+ for (i = 0; i < pEvdev->num_mt_events; ++i) {
+ pTouchData = &pEvdev->mt_events[i];
+ pSubdevInfo = subdev_map[i];
+
if (!pSubdevInfo)
continue;
- if (pSubdevInfo->used || pSubdevInfo->id < 0) {
- pSubdevInfo->used = FALSE;
+
+ EvdevCopyFromTouchData(pSubdevInfo->pInfo, pTouchData, pSubdevInfo->id);
+ EvdevSendSyncEvent(pSubdevInfo->pInfo);
+ pSubdevInfo->used = TRUE;
+ }
+
+ /* Now reset things in order to
+ * process the next MT events batch.
+ */
+ for (i = 0; i < pEvdev->num_multitouch; ++i) {
+ pSubdevInfo = &pEvdev->subdev_info[i];
+
+ if (!pSubdevInfo)
continue;
- }
- pSubdev = pSubdevInfo->pInfo;
- if (!pSubdev)
- break;
- /* if we are here, we have found a touch that were not sent during at this time.
- * We can end it.
- */
- EvdevEndOfMultiTouch(pInfo, pSubdevInfo);
+ /* Device was unused this time */
+ if (!pSubdevInfo->used && pSubdevInfo->id > 0)
+ EvdevEndOfMultiTouch(pInfo, pSubdevInfo);
+
+ pSubdevInfo->used = FALSE;
}
+ pEvdev->num_mt_events = 0;
+ pEvdev->has_tracking_id = FALSE;
+
pEvdev->subdevice_timer = TimerSet(pEvdev->subdevice_timer, 0, pEvdev->timeout, EvdevSubdevTimer, pInfo);
}
@@ -809,21 +851,27 @@ static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
}
static void
-EvdevStoreMTData(InputInfoPtr pInfo, EvdevSubdevInfoPtr pSubdevInfo)
+EvdevStoreMTData(InputInfoPtr pInfo, int n_data)
{
EvdevPtr pEvdev = pInfo->private;
- EvdevPtr pSubdev = pSubdevInfo->pInfo->private;
+ EvdevTouchDataPtr pTouchData;
int id, x, y;
+ pTouchData = &pEvdev->mt_events[n_data];
+
x = pEvdev->vals[pEvdev->axis_map[ABS_MT_POSITION_X]];
y = pEvdev->vals[pEvdev->axis_map[ABS_MT_POSITION_Y]];
id = pEvdev->vals[pEvdev->axis_map[ABS_MT_TRACKING_ID]];
- pSubdevInfo->id = id;
- memcpy(pSubdev->vals, pEvdev->vals, MAX_VALUATORS * sizeof(int));
- pSubdev->vals[pEvdev->axis_map[ABS_X]] = x;
- pSubdev->vals[pEvdev->axis_map[ABS_Y]] = y;
- pSubdevInfo->used = TRUE;
+ pTouchData->id = id;
+
+ /* Copy event axis values */
+ memcpy(pTouchData->vals, pEvdev->vals, MAX_VALUATORS * sizeof(int));
+
+ pTouchData->vals[pEvdev->axis_map[ABS_MT_POSITION_X]] = x;
+ pTouchData->vals[pEvdev->axis_map[ABS_MT_POSITION_Y]] = y;
+ pTouchData->vals[pEvdev->axis_map[ABS_X]] = x;
+ pTouchData->vals[pEvdev->axis_map[ABS_Y]] = y;
}
/**
@@ -848,29 +896,16 @@ static void
EvdevProcessMTSyncReport(InputInfoPtr pInfo, struct input_event *ev)
{
EvdevPtr pEvdev = pInfo->private;
- EvdevSubdevInfoPtr pSubdevInfo;
- int id;
if (!pEvdev->num_multitouch)
return;
- id = pEvdev->current_id;
-
- if (id >= 0) { /* the trackID is given by the device */
- /* find the previously associated pSubdev */
- pSubdevInfo = EvdevFindMatchingIdSubdevInfo(pInfo, id);
-
- if (!pSubdevInfo) {
- /* not found : find the first available pSubdev */
- pSubdevInfo = EvdevFindUnallocatedSubdev(pInfo);
- }
- }
+ if (pEvdev->num_mt_events >= pEvdev->num_multitouch)
+ return;
- if (pSubdevInfo) {
- EvdevStoreMTData(pInfo, pSubdevInfo);
- EvdevSendSyncEvent(pSubdevInfo->pInfo);
- }
+ EvdevStoreMTData(pInfo, pEvdev->num_mt_events);
EvdevReinitPEvdev(pInfo);
+ pEvdev->num_mt_events++;
}
/**
diff --git a/src/evdev.h b/src/evdev.h
index bfdcd95..a345e6e 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -139,6 +139,12 @@ typedef struct _EvdevSubdevInfo{
int id;
} EvdevSubdevInfoRec, *EvdevSubdevInfoPtr;
+typedef struct _EvdevTouchDataRec {
+ int id;
+ int vals[MAX_VALUATORS];
+ BOOL new_device_assigned;
+} EvdevTouchDataRec, *EvdevTouchDataPtr;
+
typedef struct {
const char *device;
int grabDevice; /* grab the event device? */
@@ -220,11 +226,16 @@ typedef struct {
EventQueueRec queue[EVDEV_MAXQUEUE];
/* mt-related */
- /* the number of subdevice we have for mt. */
+
+ /* the subdevices we have for mt. */
+ EvdevSubdevInfoRec subdev_info[MAX_VALUATORS_MT];
unsigned int num_multitouch;
/* used to store MT events until the EV_SYNC. */
- EvdevSubdevInfoRec subdev_info[MAX_VALUATORS_MT];
+ EvdevTouchDataRec mt_events[MAX_VALUATORS_MT];
+ unsigned int num_mt_events;
+
+ BOOL has_tracking_id;
/* the maximum time between two events to consider a mt event as released. */
Time timeout;