/***************************************************************************** * * utouch-frame - Touch Frame 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 . * * Authors: * Henrik Rydberg * ****************************************************************************/ #define MTDEV_NO_LEGACY_API #include #include #include #include #include #include static int opcode; struct frame_test { Display *display; Window root, win; XIDeviceInfo *info, *dev; utouch_frame_handle fh; }; static int init_xi2(struct frame_test *test, int id) { Display *dpy; int ndevices, i; int event, error; dpy = XOpenDisplay(NULL); if (!dpy) return -1; if (!XQueryExtension(dpy, "XInputExtension", &opcode, &event, &error)) return -1; test->display = dpy; test->info = XIQueryDevice(dpy, XIAllDevices, &ndevices); test->dev = 0; for (i = 0; i < ndevices; i++) if (test->info[i].deviceid == id) test->dev = &test->info[i]; if (!test->dev) return -1; test->root = DefaultRootWindow(dpy); test->win = XCreateSimpleWindow(dpy, test->root, 0, 0, 400, 400, 0, BlackPixel(dpy, 0), WhitePixel(dpy, 0)); XMapWindow(test->display, test->win); XFlush(test->display); return 0; } static int init_frame(struct frame_test *test) { test->fh = utouch_frame_new_engine(100, 32, 100); if (!test->fh) return -1; return utouch_frame_init_xi2(test->fh, test->display, test->dev); } static void destroy_all(struct frame_test *test) { utouch_frame_delete_engine(test->fh); XIFreeDeviceInfo(test->info); XDestroyWindow(test->display, test->win); XCloseDisplay(test->display); memset(test, 0, sizeof(*test)); } static void report_device_caps(struct frame_test *test) { 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"); } static void report_frame(const struct utouch_frame *frame, const XIDeviceEvent *ev) { int i; for (i = 0; i < frame->num_active; i++) { const struct utouch_contact *t = frame->active[i]; fprintf(stderr, "touch %d\n", i); fprintf(stderr, " slot: %d\n", t->slot); fprintf(stderr, " id: %d\n", t->id); fprintf(stderr, " tool_type: %d\n", t->tool_type); fprintf(stderr, " x: %f\n", t->x); fprintf(stderr, " y: %f\n", t->y); fprintf(stderr, " touch_major: %f\n", t->touch_major); fprintf(stderr, " touch_minor: %f\n", t->touch_minor); fprintf(stderr, " width_major: %f\n", t->width_major); fprintf(stderr, " width_minor: %f\n", t->width_minor); fprintf(stderr, " angle: %f\n", t->orientation); fprintf(stderr, " pressure: %f\n", t->pressure); fprintf(stderr, " distance: %f\n", t->distance); } fprintf(stderr, "sync %d %ld %d %d %d %f %f\n", frame->num_active, frame->time, frame->sequence_id, frame->revision, frame->slot_revision, ev->root_x, ev->root_y); } static void handle_event(struct frame_test *test, XEvent *ev) { XGenericEventCookie *gev = &ev->xcookie; const struct utouch_frame *frame; XConfigureEvent *cev; XIDeviceEvent *dev; switch(ev->type) { case ConfigureNotify: cev = (XConfigureEvent *)ev; if (cev->window == XDefaultRootWindow(cev->display)) utouch_frame_configure_xi2(test->fh, cev); break; case GenericEvent: if (!XGetEventData(test->display, gev)) break; dev = gev->data; /* null for some requests, quite odd */ dev->display = ev->xany.display; if (gev->type == GenericEvent && gev->extension == opcode) { frame = utouch_frame_pump_xi2(test->fh, dev); if (frame) report_frame(frame, dev); } XFreeEventData(test->display, gev); break; } } static void loop_device(struct frame_test *test) { XIEventMask mask; mask.deviceid = XIAllDevices; mask.mask_len = XIMaskLen(XI_TouchMotion); mask.mask = calloc(mask.mask_len, sizeof(char)); XISetMask(mask.mask, XI_TouchBegin); XISetMask(mask.mask, XI_TouchMotion); XISetMask(mask.mask, XI_TouchEnd); XISetMask(mask.mask, XI_PropertyEvent); XISelectEvents(test->display, test->win, &mask, 1); XSelectInput(test->display, test->root, StructureNotifyMask); while (1) { XEvent ev; XNextEvent(test->display, &ev); handle_event(test, &ev); } } int main(int argc, char *argv[]) { struct frame_test test; int id; if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return -1; } id = atoi(argv[1]); if (init_xi2(&test, id)) { fprintf(stderr, "error: could not describe device\n"); return -1; } if (!utouch_frame_is_supported_xi2(test.display, test.dev)) { fprintf(stderr, "error: unsupported device\n"); return -1; } if (init_frame(&test)) { fprintf(stderr, "error: could not init frame\n"); return -1; } report_device_caps(&test); loop_device(&test); destroy_all(&test); return 0; }