/***************************************************************************** * * 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 . * ****************************************************************************/ #define MTDEV_NO_LEGACY_API #include #include #include #include #include #include #include struct frame_test { struct evemu_device *evemu; struct mtdev *mtdev; utouch_frame_handle fh; grail_handle ge; }; static int init_evemu(struct frame_test *test, FILE *fp, int fd) { test->evemu = evemu_new(NULL); if (!test->evemu) return -1; if (fp) return evemu_read(test->evemu, fp) <= 0; else return evemu_extract(test->evemu, fd); } static int init_mtdev(struct frame_test *test, int fd) { test->mtdev = mtdev_new_open(fd); if (!test->mtdev) return -1; return 0; } static int init_frame(struct frame_test *test, int fd) { test->fh = utouch_frame_new_engine(100, 32, 100); if (!test->fh) return -1; return utouch_frame_init_mtdev(test->fh, test->evemu); } static int init_grail(struct frame_test *test) { struct grail_coord min = { 0, 0 }; struct grail_coord max = { 1, 1 }; test->ge = grail_new(test->fh, 10, 0); if (!test->ge) return -1; grail_set_bbox(test->ge, &min, &max); return 0; } static void destroy_all(struct frame_test *test) { grail_delete(test->ge); utouch_frame_delete_engine(test->fh); if (test->mtdev) mtdev_close_delete(test->mtdev); evemu_delete(test->evemu); memset(test, 0, sizeof(*test)); } static void report_frame(grail_handle ge, const struct utouch_frame *touch) { const struct grail_frame *frame = grail_pump_frame(ge, touch); int i; if (!frame) return; fprintf(stderr, "ongoing elements: %d\n", frame->num_ongoing); for (i = 0; i < frame->num_ongoing; i++) { const struct grail_element *slot = frame->ongoing[i]; if (!slot->expect_mask) continue; fprintf(stderr, " element %d\n", i); fprintf(stderr, " slot: %d\n", slot->slot); fprintf(stderr, " id: %d\n", slot->id); fprintf(stderr, " num_touches: %d\n", slot->num_touches); fprintf(stderr, " expect: %d\n", slot->expect_mask); fprintf(stderr, " active: %d\n", slot->active_mask); fprintf(stderr, " start time: %ld\n", slot->start_time); fprintf(stderr, " center.x: %f\n", slot->center.x); fprintf(stderr, " center.y: %f\n", slot->center.y); fprintf(stderr, " velocity.x: %f\n", slot->velocity.x); fprintf(stderr, " velocity.y: %f\n", slot->velocity.y); fprintf(stderr, " radius2: %f\n", slot->radius2); fprintf(stderr, " %+08f %+08f %+08f\n" " %+08f %+08f %+08f\n" " %+08f %+08f %+08f\n", slot->transform[0], slot->transform[1], slot->transform[2], slot->transform[3], slot->transform[4], slot->transform[5], slot->transform[6], slot->transform[7], slot->transform[8]); fprintf(stderr, " rot center.x: %f\n", slot->rotation_center.x); fprintf(stderr, " rot center.y: %f\n", slot->rotation_center.y); fprintf(stderr, " drag.x: %f\n", slot->drag.x); fprintf(stderr, " drag.y: %f\n", slot->drag.y); fprintf(stderr, " scale2: %f\n", slot->scale2); fprintf(stderr, " angle: %f\n", slot->angle); } } static void loop_device(struct frame_test *test, FILE *fp, int fd) { const struct utouch_frame *frame; struct input_event ev; if (fp) { struct timeval evtime; memset(&evtime, 0, sizeof(evtime)); while (evemu_read_event_realtime(fp, &ev, &evtime) > 0) { frame = utouch_frame_pump_mtdev(test->fh, &ev); if (frame) report_frame(test->ge, frame); } } else { while (!mtdev_idle(test->mtdev, fd, 5000)) { while (mtdev_get(test->mtdev, fd, &ev, 1) > 0) { frame = utouch_frame_pump_mtdev(test->fh, &ev); if (frame) report_frame(test->ge, frame); } } } } static void report_device_caps(struct frame_test *test) { const struct utouch_surface *s = utouch_frame_get_surface(test->fh); fprintf(stderr, "device props:\n"); if (s->needs_pointer) fprintf(stderr, "\tpointer\n"); if (s->is_direct) fprintf(stderr, "\tdirect\n"); if (s->is_buttonpad) fprintf(stderr, "\tbuttonpad\n"); if (s->is_semi_mt) fprintf(stderr, "\tsemi_mt\n"); fprintf(stderr, "device mt events:\n"); if (s->use_touch_major) fprintf(stderr, "\ttouch_major\n"); if (s->use_touch_minor) fprintf(stderr, "\ttouch_minor\n"); if (s->use_width_major) fprintf(stderr, "\twidth_major\n"); if (s->use_width_minor) fprintf(stderr, "\twidth_minor\n"); if (s->use_orientation) fprintf(stderr, "\torientation\n"); if (s->use_pressure) fprintf(stderr, "\tpressure\n"); if (s->use_distance) fprintf(stderr, "\tdistance\n"); fprintf(stderr, "touch frames: %d\n", utouch_frame_get_num_frames(test->fh)); fprintf(stderr, "touch slots: %d\n", utouch_frame_get_num_slots(test->fh)); } int main(int argc, char *argv[]) { struct frame_test test; struct stat fs; FILE *fp = 0; int fd; if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return -1; } memset(&test, 0, sizeof(test)); fd = open(argv[1], O_RDONLY | O_NONBLOCK); if (fd < 0) { fprintf(stderr, "error: could not open device\n"); return -1; } if (fstat(fd, &fs)) { fprintf(stderr, "error: could not stat the device\n"); return -1; } if (!fs.st_rdev) fp = fdopen(fd, "r"); if (!fp && ioctl(fd, EVIOCGRAB, 1)) { fprintf(stderr, "error: could not grab the device\n"); return -1; } if (init_evemu(&test, fp, fd)) { fprintf(stderr, "error: could not describe device\n"); return -1; } if (!utouch_frame_is_supported_mtdev(test.evemu)) { fprintf(stderr, "error: unsupported device\n"); return -1; } fprintf(stderr, "device: %s\n", evemu_get_name(test.evemu)); if (!fp && init_mtdev(&test, fd)) { fprintf(stderr, "error: could not init mtdev\n"); return -1; } if (init_frame(&test, fd)) { fprintf(stderr, "error: could not init frame\n"); return -1; } if (init_grail(&test)) { fprintf(stderr, "error: could not init grail\n"); return -1; } report_device_caps(&test); loop_device(&test, fp, fd); destroy_all(&test); if (fs.st_rdev) ioctl(fd, EVIOCGRAB, 0); return 0; }