summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-01-07 15:45:41 +0100
committerHenrik Rydberg <rydberg@euromail.se>2011-01-07 15:45:41 +0100
commit2091bbf8356c468389948bcea81633b6fe63e351 (patch)
tree5060600027cd592caeab8aabbd61db33ba7be0b1
parentf0aba58c91933a4702a7cc74f7daf4192868f570 (diff)
initial test of xi21
-rw-r--r--.gitignore1
-rw-r--r--configure.ac5
-rw-r--r--include/utouch/frame-xi2.h38
-rw-r--r--src/Makefile.am6
-rw-r--r--src/frame-xi2.c246
-rw-r--r--tools/Makefile.am10
-rw-r--r--tools/utouch-frame-test-xi2.c177
7 files changed, 479 insertions, 4 deletions
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 <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+#ifndef _UTOUCH_FRAME_MTDEV_H
+#define _UTOUCH_FRAME_MTDEV_H
+
+#define MTDEV_NO_LEGACY_API
+
+#include <utouch/frame.h>
+#include <X11/extensions/XInput2.h>
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+#include <utouch/frame-xi2.h>
+#include "frame-impl.h"
+#include <linux/input.h>
+#include <errno.h>
+#include <math.h>
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Henrik Rydberg <rydberg@bitmath.org>
+ *
+ ****************************************************************************/
+
+#define MTDEV_NO_LEGACY_API
+
+#include <X11/Xlib.h>
+#include <utouch/frame-xi2.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+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 <xinput_device_number>\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;
+}