/***************************************************************************** * * 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 #include #include #include #define GESTURE_GAP (1000 * 60 * 60) struct client_impl { enum gesture_state state; touch_time_t begin, end; struct gebuf buf; }; int client_init(struct gesture_client *client, void *priv) { struct client_impl *x; memset(client, 0, sizeof(*client)); x = calloc(DIM_GESTURE_TYPE, sizeof(*x)); if (!x) return -ENOMEM; client->impl = x; client->priv = priv; return 0; } void client_flag(struct gesture_client *client, const struct gesture_flag *flag) { if (client->priority[flag->type]) { struct client_impl *x = &client->impl[flag->type]; switch(flag->state) { case GS_BEGIN: x->begin = flag->time; x->end = flag->time + GESTURE_GAP; break; case GS_CANCEL: x->end = x->begin; break; case GS_END: x->end = flag->time; break; } x->state = flag->state; } } void client_event(struct gesture_client *client, const struct gesture_event *ev) { if (client->priority[ev->type]) { struct client_impl *x = &client->impl[ev->type]; gebuf_put(&x->buf, ev); } } void client_sync(struct gesture_client *client) { struct gesture_event ev; struct client_impl *x = client->impl; int i, prio = 0; for (i = 0; i < DIM_GESTURE_TYPE; i++) { if (x[i].begin != x[i].end) { if (client->priority[i] > prio) prio = client->priority[i]; } } for (i = 0; i < DIM_GESTURE_TYPE; i++) { if (client->priority[i] < prio) { gebuf_clear(&x[i].buf); } else if (prio && client->gesture) { if (x[i].state == GS_END) { while (!gebuf_empty(&x[i].buf)) { gebuf_get(&x[i].buf, &ev); client->gesture(client, &ev); } } } } for (i = 0; i < DIM_GESTURE_TYPE; i++) if (x[i].state == GS_END) x[i].begin = x[i].end; } void client_destroy(struct gesture_client *client) { free(client->impl); memset(client, 0, sizeof(*client)); }