/***************************************************************************** * * grail - Gesture Recognition And Instantiation Library * * Copyright (C) 2010-2011 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 . * ****************************************************************************/ #include "grail-impl.h" #include #include #include static struct grail_control *create_control(int size) { struct grail_control *c = calloc(1, size); if (!c) return 0; c->glue_ms = 60; c->bar_center_x = 0.03; c->bar_center_y = 0.03; c->bar_drag_x = 0.03; c->bar_drag_y = 0.03; c->bar_scale = 0.3; c->bar_angle = 0.1; c->drop_x_ms = 300; c->drop_y_ms = 300; c->drop_scale_ms = 300; c->drop_angle_ms = 300; return c; } static void destroy_slots(struct grail_element **slots, int nslot) { int i; if (slots) { for (i = nslot - 1; i >= 0; i--) free(slots[i]); free(slots); } } static void destroy_frame(struct grail_frame *frame, int nslot) { if (frame) { destroy_slots(frame->slots, nslot); free(frame->ongoing); free(frame); } } static void destroy_frames(struct grail_frame **frames, int nframe, int nslot) { int i; if (frames) { for (i = nframe - 1; i >= 0; i--) destroy_frame(frames[i], nslot); free(frames); } } static struct grail_element **create_slots(int nslot, int ntouch, int size) { struct grail_element **slots; struct grail_element *s; int i; slots = calloc(nslot, sizeof(slots[0])); if (!slots) return 0; for (i = 0; i < nslot; i++) { s = calloc(1, size + ntouch * sizeof(void *)); if (!s) goto out; s->slot = i; s->id = -1; s->touches = (void *)((char *)s + size); slots[i] = s; } return slots; out: destroy_slots(slots, nslot); return 0; } static struct grail_frame *create_frame(int nslot, int ntouch, int frame_size, int slot_size) { struct grail_frame *frame; int i; frame = calloc(1, frame_size); if (!frame) return 0; frame->ongoing = calloc(nslot, sizeof(frame->ongoing[0])); frame->slots = create_slots(nslot, ntouch, slot_size); if (!frame->ongoing || !frame->slots) goto out; return frame; out: destroy_frame(frame, nslot); return 0; } static struct grail_frame **create_frames(int nframe, int nslot, int ntouch, int frame_size, int slot_size) { struct grail_frame **frames; struct grail_frame *f; int i; frames = calloc(nframe, sizeof(frames[0])); if (!frames) return 0; for (i = 0; i < nframe; i++) { f = create_frame(nslot, ntouch, frame_size, slot_size); if (!f) goto out; frames[i] = f; } return frames; out: destroy_frames(frames, nframe, nslot); return 0; } int create_grail2(struct grail_impl *x, utouch_frame_handle fh, unsigned int num_frames, grail_select_callback select, unsigned int version, unsigned int control_size, unsigned int frame_size, unsigned int slot_size) { struct utouch_surface *s = utouch_frame_get_surface(fh); unsigned int ntouch = utouch_frame_get_num_slots(fh); unsigned int nslot = get_slot_count(ntouch); int i, j; x->select = select; x->control_size = MAX(control_size, sizeof(struct grail_control)); x->frame_size = MAX(frame_size, sizeof(struct grail_frame)); x->slot_size = MAX(slot_size, sizeof(struct grail_element)); x->num_frames = num_frames; x->num_slots = nslot; x->num_touches = ntouch; x->ctl = create_control(x->control_size); if (!x->ctl) goto freemem; x->frames = create_frames(num_frames, nslot, ntouch, x->frame_size, x->slot_size); if (!x->frames) goto freemem; for (i = 0; i < num_frames; i++) x->frames[(i + 1) % num_frames]->prev = x->frames[i]; return 0; freemem: destroy_grail2(x); return -ENOMEM; } void destroy_grail2(struct grail_impl *x) { destroy_frames(x->frames, x->num_frames, x->num_slots); free(x->ctl); } grail_handle GRAIL_PUBLIC grail_new_raw(utouch_frame_handle fh, unsigned int num_frames, grail_select_callback select, unsigned int version, unsigned int control_size, unsigned int frame_size, unsigned int slot_size) { struct grail *ge; struct grail_impl *x; ge = calloc(1, sizeof(*ge)); if (!ge) return 0; x = calloc(1, sizeof(*x)); if (!x) goto out; x->fh = fh; if (create_grail2(x, fh, num_frames, select, version, control_size, frame_size, slot_size)) goto out; ge->impl = x; return ge; out: free(x); free(ge); return 0; } void GRAIL_PUBLIC grail_delete(grail_handle ge) { destroy_grail2(ge->impl); free(ge->impl); free(ge); } struct grail_control GRAIL_PUBLIC *grail_get_control(grail_handle ge) { return ge->impl->ctl; }