/***************************************************************************** * * grail - Gesture Recognition And Instantiation Library * * Copyright (C) 2010 Canonical Ltd. * Copyright (C) 2010 Henrik Rydberg * * 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 . * ****************************************************************************/ #include "grail-inserter.h" #include "grail-impl.h" #include #include #include #include static void compute_bbox(struct grail_coord *min, struct grail_coord *max, const struct utouch_frame *frame) { float x, y; int i; if (frame->num_active < 1) return; x = frame->active[0]->x; y = frame->active[0]->y; min->x = max->x = x; min->y = max->y = y; for (i = 1; i < frame->num_active; i++) { x = frame->active[i]->x; y = frame->active[i]->y; if (x < min->x) min->x = x; if (y < min->y) min->y = y; if (x > max->x) max->x = x; if (y > max->y) max->y = y; } } int gin_add_contact_props(const struct gesture_inserter *gin, grail_prop_t *prop, const struct utouch_frame *frame) { struct grail_coord min, max; int i, n = 0, ntouch = frame->num_active; if (!ntouch) return n; if (ntouch > 5) ntouch = 5; compute_bbox(&min, &max, frame); prop[n++] = min.x; prop[n++] = min.y; prop[n++] = max.x; prop[n++] = max.y; for (i = 0; i < ntouch; i++) { const struct utouch_contact *ct = frame->active[i]; prop[n++] = ct->id; prop[n++] = ct->x; prop[n++] = ct->y; } return n; } int gin_get_clients(struct grail *ge, struct grail_client_info *info, int maxinfo, const grail_mask_t* types, int btypes, const grail_mask_t* span, int bspan, const struct utouch_frame *frame) { struct grail_coord pos[DIM_TOUCH]; int i, npos = 0; if (!ge->get_clients) return 0; grail_mask_foreach(i, span, bspan) { pos[npos].x = frame->slots[i]->x; pos[npos].y = frame->slots[i]->y; npos++; } return ge->get_clients(ge, info, maxinfo, pos, npos, types, btypes); } void gin_send_event(struct grail *ge, struct slot_state *s, const struct gesture_event *ev, const struct utouch_frame *frame) { struct grail_impl *impl = ge->impl; const struct gesture_inserter *gin = ge->gin; struct grail_event gev; int i; if (!ge->gesture) return; gev.type = s->type; gev.id = s->id; gev.status = ev->status; gev.ntouch = ev->ntouch; gev.nprop = ev->nprop; gev.time = ev->time; gev.pos.x = ev->pos.x; gev.pos.y = ev->pos.y; memcpy(gev.prop, ev->prop, ev->nprop * sizeof(grail_prop_t)); for (i = 0; i < s->nclient; i++) { gev.client_id = s->client_id[i]; grailbuf_put(&impl->gbuf, &gev); } } int grail_get_contacts(const struct grail *ge, struct grail_contact *touch, int max_touch) { const struct gesture_inserter *gin = ge->gin; const struct utouch_frame *frame = ge->impl->frame; int i; if (frame->num_active < max_touch) max_touch = frame->num_active; for (i = 0; i < max_touch; i++) { struct grail_contact *t = &touch[i]; const struct utouch_contact *ct = frame->active[i]; t->id = ct->id; t->tool_type = ct->tool_type; t->pos.x = ct->x; t->pos.y = ct->y; t->touch_major = ct->touch_major; t->touch_minor = ct->touch_minor; t->width_major = ct->width_major; t->width_minor = ct->width_minor; t->angle = ct->orientation; t->pressure = ct->pressure; } return max_touch; }