From 2091bbf8356c468389948bcea81633b6fe63e351 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Fri, 7 Jan 2011 15:45:41 +0100 Subject: initial test of xi21 --- .gitignore | 1 + configure.ac | 5 +- include/utouch/frame-xi2.h | 38 +++++++ src/Makefile.am | 6 +- src/frame-xi2.c | 246 ++++++++++++++++++++++++++++++++++++++++++ tools/Makefile.am | 10 +- tools/utouch-frame-test-xi2.c | 177 ++++++++++++++++++++++++++++++ 7 files changed, 479 insertions(+), 4 deletions(-) create mode 100644 include/utouch/frame-xi2.h create mode 100644 src/frame-xi2.c create mode 100644 tools/utouch-frame-test-xi2.c diff --git a/.gitignore b/.gitignore index cf601fa..75c2197 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,4 @@ core .bzr patches tools/utouch-frame-test-mtdev +tools/utouch-frame-test-xi2 diff --git a/configure.ac b/configure.ac index 0ff758f..1b2c4c3 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,10 @@ AC_PROG_INSTALL PKG_CHECK_MODULES([MTDEV], [mtdev >= 1.1]) PKG_CHECK_MODULES([EVEMU], [utouch-evemu >= 1.0]) - +PKG_CHECK_MODULES([X11], [x11]) +PKG_CHECK_MODULES(XINPUT, x11 xext [xi >= 1.2] [inputproto >= 1.5]) +PKG_CHECK_MODULES(XI2_1, [xi >= 1.4.99.1] [inputproto >= 2.0.99.1]) + AC_CONFIG_FILES([Makefile src/Makefile test/Makefile diff --git a/include/utouch/frame-xi2.h b/include/utouch/frame-xi2.h new file mode 100644 index 0000000..602bd9b --- /dev/null +++ b/include/utouch/frame-xi2.h @@ -0,0 +1,38 @@ +/***************************************************************************** + * + * 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 . + * + ****************************************************************************/ + +#ifndef _UTOUCH_FRAME_MTDEV_H +#define _UTOUCH_FRAME_MTDEV_H + +#define MTDEV_NO_LEGACY_API + +#include +#include + +int utouch_frame_is_supported_xi2(const XIDeviceInfo *dev); + +int utouch_frame_init_xi2(utouch_frame_handle fh, + const XIDeviceInfo *dev); + +const struct utouch_frame * +utouch_frame_pump_xi2(utouch_frame_handle fh, const XIDeviceEvent *ev); + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index aa11733..34f0462 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,8 @@ libutouch_frame_la_LDFLAGS = \ libutouch_frame_la_SOURCES = \ frame-impl.h \ frame.c \ - frame-mtdev.c + frame-mtdev.c \ + frame-xi2.c AM_CFLAGS = $(CWARNFLAGS) @@ -18,4 +19,5 @@ INCLUDES = -I$(top_srcdir)/include/ libutouch_frameincludedir = $(includedir)/utouch libutouch_frameinclude_HEADERS = \ $(top_srcdir)/include/utouch/frame.h \ - $(top_srcdir)/include/utouch/frame-mtdev.h + $(top_srcdir)/include/utouch/frame-mtdev.h \ + $(top_srcdir)/include/utouch/frame-xi2.h diff --git a/src/frame-xi2.c b/src/frame-xi2.c new file mode 100644 index 0000000..635a346 --- /dev/null +++ b/src/frame-xi2.c @@ -0,0 +1,246 @@ +/***************************************************************************** + * + * utouch-frame - Touch Frame 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 . + * + ****************************************************************************/ + +#include +#include "frame-impl.h" +#include +#include +#include + +int utouch_frame_is_supported_xi2(const XIDeviceInfo *dev) +{ + + int i; + + for (i = 0; i < dev->num_classes; i++) + if (dev->classes[i]->type == XITouchClass) + return 1; + + return 0; +} + +int utouch_frame_init_xi2(utouch_frame_handle fh, + const XIDeviceInfo *dev) +{ + struct utouch_surface *s = fh->surface; + XITouchValuatorClassInfo *v; + float tmp; + int i; + + if (!utouch_frame_is_supported_xi2(dev)) + return -ENODEV; + + s->phys_width = 100; + s->phys_height = 65; + s->phys_pressure = 10; + s->max_x = 1024; + s->max_y = 768; + + for (i = 0; i < dev->num_classes; i++) { + if (dev->classes[i]->type != XITouchValuatorClass) + continue; + v = (void *)dev->classes[i]; + switch (v->label) { + case ABS_MT_POSITION_X: + s->min_x = v->min; + s->max_x = v->max; + if (v->resolution <= 0) + break; + s->phys_width = (v->max - v->min) / v->resolution; + break; + case ABS_MT_POSITION_Y: + s->min_y = v->min; + s->max_y = v->max; + if (v->resolution <= 0) + break; + s->phys_height = (v->max - v->min) / v->resolution; + break; + case ABS_MT_TOUCH_MAJOR: + s->use_touch_major = 1; + break; + case ABS_MT_TOUCH_MINOR: + s->use_touch_minor = 1; + break; + case ABS_MT_WIDTH_MAJOR: + s->use_width_major = 1; + break; + case ABS_MT_WIDTH_MINOR: + s->use_width_minor = 1; + break; + case ABS_MT_ORIENTATION: + s->use_orientation = 1; + fh->max_orient = v->max > 0 ? v->max : 1; + break; + case ABS_MT_PRESSURE: + s->use_pressure = 1; + s->max_pressure = v->max > 0 ? v->max : 256; + if (v->resolution <= 0) + break; + s->phys_pressure = v->max / v->resolution; + break; +#ifdef ABS_MT_DISTANCE + case ABS_MT_DISTANCE: + s->use_distance = 1; + break; +#endif + } + } + + return 0; +} + +static float touch_angle(utouch_frame_handle fh, int orient) +{ + return orient / fh->max_orient * M_PI_2; +} + +#if 0 +static int handle_abs_event(utouch_frame_handle fh, + const struct input_event *ev) +{ + struct utouch_contact *t = utouch_frame_get_current_slot(fh); + + switch (ev->code) { + case ABS_MT_SLOT: + utouch_frame_set_current_slot(fh, ev->value); + return 1; + case ABS_MT_POSITION_X: + t->x = ev->value; + return 1; + case ABS_MT_POSITION_Y: + t->y = ev->value; + return 1; + case ABS_MT_TOUCH_MAJOR: + t->touch_major = ev->value; + return 1; + case ABS_MT_TOUCH_MINOR: + t->touch_minor = ev->value; + return 1; + case ABS_MT_WIDTH_MAJOR: + t->width_major = ev->value; + return 1; + case ABS_MT_WIDTH_MINOR: + t->width_minor = ev->value; + return 1; + case ABS_MT_ORIENTATION: + t->orientation = touch_angle(fh, ev->value); + return 1; + case ABS_MT_PRESSURE: + t->pressure = ev->value; + return 1; +#ifdef ABS_MT_DISTANCE + case ABS_MT_DISTANCE: + t->distance = ev->value; + return 1; +#endif + case ABS_MT_TOOL_TYPE: + t->tool_type = ev->value; + return 1; + case ABS_MT_TRACKING_ID: + t->id = ev->value; + return 1; + default: + return 0; + } +} + +static utouch_frame_time_t get_evtime_ms(const struct input_event *syn) +{ + static const utouch_frame_time_t ms = 1000; + return syn->time.tv_usec / ms + syn->time.tv_sec * ms; +} + +static void print_deviceevent(XIDeviceEvent* event) +{ + double *val; + int i; + static int touch_events_received = 0; + static int thong = 0; + + printf(" device: %d (%d)\n", event->deviceid, event->sourceid); + printf(" detail: %d\n", event->detail); + + switch (event->evtype) + { + case XI_KeyPress: + case XI_KeyRelease: + printf(" flags: %s\n", (event->flags & XIKeyRepeat) ? "repeat" : ""); + break; + case XI_TouchBegin: + case XI_TouchMotion: + case XI_TouchEnd: + printf("flags: %s%s%s\n", + (event->flags & XITouchOwner) ? "owner " : "", + (event->flags & XITouchOwnerAccepted) ? "owner accepted " : "", + (event->flags & XITouchPendingFinish) ? "pending finish " : ""); + break; + } + + printf(" root: %.2f/%.2f\n", event->root_x, event->root_y); + printf(" event: %.2f/%.2f\n", event->event_x, event->event_y); + + printf(" buttons:"); + for (i = 0; i < event->buttons.mask_len * 8; i++) + if (XIMaskIsSet(event->buttons.mask, i)) + printf(" %d", i); + printf("\n"); + + printf(" modifiers: locked %#x latched %#x base %#x effective: %#x\n", + event->mods.locked, event->mods.latched, + event->mods.base, event->mods.effective); + printf(" group: locked %#x latched %#x base %#x effective: %#x\n", + event->group.locked, event->group.latched, + event->group.base, event->group.effective); + printf(" valuators:\n"); + + val = event->valuators.values; + for (i = 0; i < event->valuators.mask_len * 8; i++) + if (XIMaskIsSet(event->valuators.mask, i)) + printf(" %i: %.2f\n", i, *val++); + + printf(" windows: root 0x%lx event 0x%lx child 0x%lx\n", + event->root, event->event, event->child); + + if (event->evtype == XI_TouchBegin) + touch_events_received = 0; + else if (event->evtype == XI_TouchMotion && event->event != event->child && + (event->flags & XITouchOwner) && ++touch_events_received == 5) + XIAllowTouchEvents(event->display, event->sourceid, event->detail, + (thong ^= 1) ? XITouchOwnerAccept : + XITouchOwnerReject); +} + +#endif + +const struct utouch_frame * +utouch_frame_pump_xi2(utouch_frame_handle fh, const XIDeviceEvent *ev) +{ + const struct utouch_frame *f = 0; + +#if 0 + if (ev->type == EV_SYN && ev->code == SYN_REPORT) + f = utouch_frame_sync(fh, get_evtime_ms(ev)); + else if (ev->type == EV_ABS) + handle_abs_event(fh, ev); +#endif + + return f; +} diff --git a/tools/Makefile.am b/tools/Makefile.am index 6b50897..8c91029 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,7 +1,15 @@ -bin_PROGRAMS = utouch-frame-test-mtdev +bin_PROGRAMS = utouch-frame-test-mtdev \ + utouch-frame-test-xi2 INCLUDES=-I$(top_srcdir)/include/ +AM_CFLAGS = $(XINPUT_CFLAGS) + utouch_frame_test_mtdev_SOURCES = utouch-frame-test-mtdev.c utouch_frame_test_mtdev_LDFLAGS = -L$(top_builddir)/src/.libs/ \ -lutouch-frame -lutouch-evemu -lmtdev -lm + +utouch_frame_test_xi2_SOURCES = utouch-frame-test-xi2.c +utouch_frame_test_xi2_LDFLAGS = $(XINPUT_LIBS) $(X11_LIBS) \ + -L$(top_builddir)/src/.libs/ \ + -lutouch-frame -lutouch-evemu -lmtdev -lm diff --git a/tools/utouch-frame-test-xi2.c b/tools/utouch-frame-test-xi2.c new file mode 100644 index 0000000..3351a5a --- /dev/null +++ b/tools/utouch-frame-test-xi2.c @@ -0,0 +1,177 @@ +/***************************************************************************** + * + * 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 + +struct frame_test { + Display *display; + XIDeviceInfo *info, *dev; + utouch_frame_handle fh; +}; + +static int init_xi2(struct frame_test *test, int id) +{ + int ndevices, i; + + test->display = XOpenDisplay(NULL); + if (!test->display) + return -1; + + test->info = XIQueryDevice(test->display, 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; + 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->dev); +} + +static void destroy_all(struct frame_test *test) +{ + utouch_frame_delete_engine(test->fh); + XIFreeDeviceInfo(test->info); + XCloseDisplay(test->display); + memset(test, 0, sizeof(*test)); +} + +static void report_frame(const struct utouch_frame *frame) +{ + 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\n", + frame->num_active, + frame->time, + frame->sequence_id, + frame->revision, + frame->slot_revision); +} + +static void loop_device(struct frame_test *test) +{ + const struct utouch_frame *frame; +#if 0 + 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(frame); + } + } +#endif +} + +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"); +} + +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.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; +} -- cgit v1.2.3