From c0666a895e7fe8e488332263fd106ced0ed7cab7 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sun, 2 Jan 2011 11:00:52 +0100 Subject: Replace touch logic with utouch frame engine The original grail uses an internal touch framework and exports some touch information as extended attributes to gesture events. This was never quite the intention, but rather to expose gestures and touches on a similar footing, such that grail can be input agnostic. This patch starts off by replacing the internal touch framework with the utouch-frame engine. Signed-off-by: Henrik Rydberg --- src/grail-api.c | 280 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 158 insertions(+), 122 deletions(-) (limited to 'src/grail-api.c') diff --git a/src/grail-api.c b/src/grail-api.c index f38ca18..3aca75d 100644 --- a/src/grail-api.c +++ b/src/grail-api.c @@ -30,27 +30,124 @@ #include #include -static void tp_event(struct touch_dev *dev, - const struct input_event *ev) +#define DIM_FRAMES 100 +#define FRAME_RATE 100 + +void grail_filter_abs_events(struct grail *ge, int usage) { - struct grail *ge = dev->priv; struct grail_impl *x = ge->impl; - if (ev->type == EV_ABS) { - return; + x->filter_abs = usage; +} + +static void init_impl(struct grail_impl *x) +{ + int i; + + if (evemu_has_event(x->evemu, EV_ABS, ABS_X)) { + x->emin_x = evemu_get_abs_minimum(x->evemu, ABS_X); + x->emin_y = evemu_get_abs_minimum(x->evemu, ABS_Y); + x->emax_x = evemu_get_abs_maximum(x->evemu, ABS_X); + x->emax_y = evemu_get_abs_maximum(x->evemu, ABS_Y); + } else { + struct utouch_surface *s = utouch_frame_get_surface(x->fh); + x->emin_x = s->min_x; + x->emin_y = s->min_y; + x->emax_x = s->max_x; + x->emax_y = s->max_y; } - if (ev->type == EV_KEY) { - switch (ev->code) { - case BTN_TOUCH: - case BTN_TOOL_FINGER: - case BTN_TOOL_DOUBLETAP: - case BTN_TOOL_TRIPLETAP: - case BTN_TOOL_QUADTAP: - return; - } +} + +int grail_open(struct grail *ge, int fd) +{ + struct grail_impl *x; + int ret; + x = calloc(1, sizeof(*x)); + if (!x) + return -ENOMEM; + + x->evemu = evemu_new(0); + if (!x->evemu) { + ret = -ENOMEM; + goto freemem; } - evbuf_put(&x->evbuf, ev); + ret = evemu_extract(x->evemu, fd); + if (ret) + goto freemem; + if (!utouch_frame_is_supported_mtdev(x->evemu)) { + ret = -ENODEV; + goto freemem; + } + x->mtdev = mtdev_new_open(fd); + if (!x->mtdev) { + ret = -ENOMEM; + goto freemem; + } + + x->fh = utouch_frame_new_engine(DIM_FRAMES, DIM_TOUCH, FRAME_RATE); + if (!x->fh) { + ret = -ENOMEM; + goto freedev; + } + ret = utouch_frame_init_mtdev(x->fh, x->evemu); + if (ret) + goto freeframe; + + init_impl(x); + ge->impl = x; + + ret = gin_init(ge); + if (ret) + goto freeframe; + + ret = gru_init(ge); + if (ret) + goto freegin; + + return 0; + freegin: + gin_destroy(ge); + freeframe: + utouch_frame_delete_engine(x->fh); + freedev: + mtdev_close_delete(x->mtdev); + freemem: + evemu_delete(x->evemu); + free(x); + ge->impl = 0; + return ret; +} + +void grail_close(struct grail *ge, int fd) +{ + struct grail_impl *x = ge->impl; + void *status; + gru_destroy(ge); + gin_destroy(ge); + utouch_frame_delete_engine(x->fh); + mtdev_close_delete(x->mtdev); + evemu_delete(x->evemu); + free(x); + ge->impl = 0; } +int grail_idle(struct grail *ge, int fd, int ms) +{ + struct grail_impl *x = ge->impl; + return mtdev_idle(x->mtdev, fd, ms); +} + +void grail_get_units(const struct grail *ge, + struct grail_coord *min, struct grail_coord *max) +{ + struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh); + min->x = s->min_x; + min->y = s->min_y; + max->x = s->max_x; + max->y = s->max_y; +} + +// legacy glue below + static void evput(struct grail_impl *x, struct timeval time, unsigned type, unsigned code, int value) { @@ -76,47 +173,19 @@ static void report_up(struct grail_impl *impl, const struct input_event *syn) impl->report_status = 0; } -#define SYSCALL(call) while (((call) == -1) && (errno == EINTR)) - -static int getabs(struct input_absinfo *abs, int key, int fd) -{ - int rc; - SYSCALL(rc = ioctl(fd, EVIOCGABS(key), abs)); - return rc >= 0; -} - -static void set_emulation_caps(struct grail_impl *impl, int fd) -{ - struct touch_caps *emu = &impl->emu; - struct input_absinfo info; - - memset(emu, 0, sizeof(*emu)); - - if (getabs(&info, ABS_X, fd)) { - emu->min_x = info.minimum; - emu->max_x = info.maximum; - } - if (getabs(&info, ABS_Y, fd)) { - emu->min_y = info.minimum; - emu->max_y = info.maximum; - } -} - static void set_pointer(struct grail_impl *impl) { - struct touch_dev *dev = &impl->dev; - struct touch_caps *caps = &dev->caps; - struct touch_caps *emu = &impl->emu; - struct touch_frame *frame = &dev->frame; + struct utouch_surface *s = utouch_frame_get_surface(impl->fh); + const struct utouch_frame *frame = impl->frame; int best_x, best_y, best_d = -1; int i; - for (i = 0; i < frame->nactive; i++) { - struct touch *t = frame->active[i]; - float u = (t->x - caps->min_x) / (caps->max_x - caps->min_x); - float v = (t->y - caps->min_y) / (caps->max_y - caps->min_y); - int x = emu->min_x + u * (emu->max_x - emu->min_x); - int y = emu->min_y + v * (emu->max_y - emu->min_y); + for (i = 0; i < frame->num_active; i++) { + const struct utouch_contact *t = frame->active[i]; + float u = (t->x - s->min_x) / (s->max_x - s->min_x); + float v = (t->y - s->min_y) / (s->max_y - s->min_y); + int x = impl->emin_x + u * (impl->emax_x - impl->emin_x); + int y = impl->emin_y + v * (impl->emax_y - impl->emin_y); int d = abs(x - impl->pointer_x) + abs(y - impl->pointer_y); if (best_d < 0 || d < best_d) { best_x = x; @@ -181,15 +250,18 @@ static void handle_abs_events(struct grail *ge, const struct input_event *syn) } } -static void tp_sync(struct touch_dev *dev, - const struct input_event *syn) +static void report_frame(struct grail *ge, + const struct utouch_frame *frame, + const struct input_event *syn) { - struct grail *ge = dev->priv; + struct grail_impl *impl = ge->impl; int head = impl->evbuf.head; struct input_event iev; struct grail_event gev; - struct touch_frame *frame = &dev->frame; + + ge->impl->frame = frame; + gin_frame_begin(ge, frame); gru_recognize(ge, frame); gin_frame_end(ge, frame); @@ -211,78 +283,42 @@ static void tp_sync(struct touch_dev *dev, } } -void grail_filter_abs_events(struct grail *ge, int usage) -{ - struct grail_impl *x = ge->impl; - x->filter_abs = usage; -} - -int grail_open(struct grail *ge, int fd) -{ - struct grail_impl *x; - int ret; - x = calloc(1, sizeof(*x)); - if (!x) - return -ENOMEM; - ge->impl = x; - - ret = touch_dev_open(&x->dev, fd); - if (ret) - goto freemem; - set_emulation_caps(x, fd); - x->dev.event = tp_event; - x->dev.sync = tp_sync; - x->dev.priv = ge; - - ret = gin_init(ge); - if (ret) - goto freedev; - - ret = gru_init(ge); - if (ret) - goto freegin; - - return 0; - freegin: - gin_destroy(ge); - freedev: - touch_dev_close(&x->dev, fd); - freemem: - free(x); - ge->impl = 0; - return ret; -} - -void grail_close(struct grail *ge, int fd) +static void grail_pump_mtdev(struct grail *ge, const struct input_event *ev) { - struct grail_impl *x = ge->impl; - void *status; - gru_destroy(ge); - gin_destroy(ge); - touch_dev_close(&x->dev, fd); - free(ge->impl); - ge->impl = 0; -} + struct grail_impl *impl = ge->impl; + const struct utouch_frame *frame; -int grail_idle(struct grail *ge, int fd, int ms) -{ - struct grail_impl *x = ge->impl; - return touch_dev_idle(&x->dev, fd, ms); + if (ev->type == EV_SYN || ev->type == EV_ABS) { + frame = utouch_frame_pump_mtdev(impl->fh, ev); + if (frame) + report_frame(ge, frame, ev); + } else if (ev->type == EV_KEY) { + switch (ev->code) { + case BTN_TOUCH: + case BTN_TOOL_FINGER: + case BTN_TOOL_DOUBLETAP: + case BTN_TOOL_TRIPLETAP: + case BTN_TOOL_QUADTAP: + break; + default: + evbuf_put(&impl->evbuf, ev); + break; + } + } else { + evbuf_put(&impl->evbuf, ev); + } } int grail_pull(struct grail *ge, int fd) { - struct grail_impl *x = ge->impl; - return touch_dev_pull(&x->dev, fd); -} + struct grail_impl *impl = ge->impl; + struct input_event ev; + int ret, count = 0; -void grail_get_units(const struct grail *ge, - struct grail_coord *min, struct grail_coord *max) -{ - const struct touch_caps *caps = &ge->impl->dev.caps; - min->x = caps->min_x; - min->y = caps->min_y; - max->x = caps->max_x; - max->y = caps->max_y; -} + while ((ret = mtdev_get(impl->mtdev, fd, &ev, 1)) > 0) { + grail_pump_mtdev(ge, &ev); + count++; + } + return count > 0 ? count : ret; +} -- cgit v1.2.3