/***************************************************************************** * * grail - Gesture Recognition And Instantiation Library * * Copyright (C) 2010 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Authors: * Henrik Rydberg * ****************************************************************************/ #include #include static void tp_event(struct touch_dev *dev, const struct input_event *ev) { struct touch_engine *engine = dev->priv; if (engine && engine->event) engine->event(engine, ev); } static void update_frame(struct touch_frame *frame, int slot, int active, const grail_mask_t *mask, const touch_prop_t *prop) { struct touch *t = &frame->touch[slot]; int i; t->active = active; grail_mask_modify(frame->touches, slot, active); if (mask && prop) grail_mask_foreach(i, mask, DIM_TOUCH_PROP_BYTES) t->prop[i] = prop[i]; } static void finalize_frame(struct touch_frame *frame, touch_time_t time) { int i, nslot = 0; grail_mask_foreach(i, frame->touches, DIM_TOUCH_BYTES) frame->active[nslot++] = &frame->touch[i]; frame->nactive = nslot; frame->time = time; } static void tp_create(struct touch_dev *dev, int slot, const grail_mask_t *mask, const touch_prop_t *prop) { struct touch_engine *engine = dev->priv; if (engine) { engine->frame.ncreate++; update_frame(&engine->frame, slot, 1, mask, prop); } } static void tp_modify(struct touch_dev *dev, int slot, const grail_mask_t *mask, const touch_prop_t *prop) { struct touch_engine *engine = dev->priv; if (engine) { engine->frame.nmodify++; update_frame(&engine->frame, slot, 1, mask, prop); } } static void tp_destroy(struct touch_dev *dev, int slot) { struct touch_engine *engine = dev->priv; if (engine) { engine->frame.ndestroy++; update_frame(&engine->frame, slot, 0, 0, 0); } } static void tp_sync(struct touch_dev *dev, const struct input_event *syn) { static const touch_time_t ms = 1000; struct touch_engine *engine = dev->priv; touch_time_t time = syn->time.tv_usec / ms + syn->time.tv_sec * ms; if (engine) { finalize_frame(&engine->frame, time); if (engine->sync) engine->sync(engine, syn); engine->frame.ncreate = 0; engine->frame.nmodify = 0; engine->frame.ndestroy = 0; } } void touch_engine_init(struct touch_engine *engine, void (*event)(struct touch_engine *engine, const struct input_event *ev), void (*sync)(struct touch_engine *engine, const struct input_event *ev), void *priv) { int i; memset(engine, 0, sizeof(*engine)); for (i = 0; i < DIM_TOUCH; i++) engine->frame.touch[i].slot = i; engine->event = event; engine->sync = sync; engine->priv = priv; } void touch_engine_attach(struct touch_engine *engine, struct touch_dev *dev) { dev->priv = engine; dev->event = tp_event; dev->create = tp_create; dev->modify = tp_modify; dev->destroy = tp_destroy; dev->sync = tp_sync; } void touch_engine_detach(struct touch_engine *engine, struct touch_dev *dev) { dev->sync = 0; dev->destroy = 0; dev->modify = 0; dev->create = 0; dev->event = 0; dev->priv = 0; }