From 9bdd12a8046f33a6d190bb33371eb30d3ee59062 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 9 Sep 2010 10:17:09 +0200 Subject: Support legacy devices Simulate MT touch events for legacy devices that support the DOUBLETAP, TRIPLETAP and QUADTAP events. This allows multi-finger tap and drag gestures to be emitted, providing a basic level of MT functionality for legacy devices. Signed-off-by: Henrik Rydberg --- src/touch-dev.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 2 deletions(-) (limited to 'src/touch-dev.c') diff --git a/src/touch-dev.c b/src/touch-dev.c index 17082ed..d8e192e 100644 --- a/src/touch-dev.c +++ b/src/touch-dev.c @@ -53,13 +53,45 @@ static void finish_touch(struct touch_dev *dev, struct touch_frame *frame) dev->state = 0; } +static void finish_legacy(struct touch_dev *dev, struct touch_frame *frame) +{ + static int trkid; + int i; + for (i = 0; i < frame->nactive; i++) { + struct touch *t = &frame->touch[i]; + t->active = 1; + if (t->id < 0) { + t->id = trkid++ & 0xffff; + frame->ncreate++; + } + if (i > 0) { + SET_PROP(x, frame->touch[0].x); + SET_PROP(y, frame->touch[0].y); + SET_PROP(pressure, frame->touch[0].pressure); + } + grail_mask_set(frame->touches, i); + } + for (i = frame->nactive; i < DIM_TOUCH; i++) { + struct touch *t = &frame->touch[i]; + t->active = 0; + if (t->id >= 0) { + t->id = -1; + frame->ndestroy++; + } + grail_mask_clear(frame->touches, i); + } +} + static void finish_packet(struct touch_dev *dev, const struct input_event *syn) { static const touch_time_t ms = 1000; struct touch_frame *frame = &dev->frame; int i, nslot = 0; - finish_touch(dev, frame); + if (dev->mtdev.caps.has_mtdata) + finish_touch(dev, frame); + else + finish_legacy(dev, frame); grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES) frame->active[nslot++] = &frame->touch[i]; frame->nactive = nslot; @@ -77,6 +109,21 @@ static int handle_abs_event(struct touch_dev *dev, struct touch_frame *frame = &dev->frame; struct touch *t = &frame->touch[dev->slot]; switch (ev->code) { + case ABS_X: + if (dev->mtdev.caps.has_mtdata) + return 0; + SET_PROP(x, ev->value); + return 0; + case ABS_Y: + if (dev->mtdev.caps.has_mtdata) + return 0; + SET_PROP(y, ev->value); + return 0; + case ABS_PRESSURE: + if (dev->mtdev.caps.has_mtdata) + return 0; + SET_PROP(pressure, ev->value); + return 0; case ABS_MT_SLOT: if (ev->value >= 0 && ev->value < DIM_TOUCH) { if (dev->slot != ev->value) @@ -128,6 +175,40 @@ static int handle_abs_event(struct touch_dev *dev, } } +static int handle_key_event(struct touch_dev *dev, + const struct input_event *ev) +{ + struct touch_frame *frame = &dev->frame; + if (dev->mtdev.caps.has_mtdata) + return 0; + switch (ev->code) { + case BTN_TOUCH: + if (ev->value && !frame->nactive) + frame->nactive = 1; + else if (!ev->value && frame->nactive) + frame->nactive = 0; + return 0; + case BTN_TOOL_FINGER: + if (ev->value) + frame->nactive = 1; + return 0; + case BTN_TOOL_DOUBLETAP: + if (ev->value) + frame->nactive = 2; + return 0; + case BTN_TOOL_TRIPLETAP: + if (ev->value) + frame->nactive = 3; + return 0; + case BTN_TOOL_QUADTAP: + if (ev->value) + frame->nactive = 4; + return 0; + default: + return 0; + } +} + int touch_dev_open(struct touch_dev *dev, int fd) { struct touch_frame *frame = &dev->frame; @@ -139,7 +220,7 @@ int touch_dev_open(struct touch_dev *dev, int fd) t->id = MT_ID_NULL; } ret = mtdev_open(&dev->mtdev, fd); - if (!ret && !dev->mtdev.caps.has_mtdata) + if (!ret && !touch_caps_is_supported(dev, fd)) ret = -ENODEV; if (ret) goto error; @@ -166,6 +247,8 @@ int touch_dev_pull(struct touch_dev *dev, int fd) consumed++; } else if (ev.type == EV_ABS) { consumed += handle_abs_event(dev, &ev); + } else if (ev.type == EV_KEY) { + consumed += handle_key_event(dev, &ev); } if (!consumed && dev->event) dev->event(dev, &ev); -- cgit v1.2.3