summaryrefslogtreecommitdiff
path: root/src/frame-xi2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/frame-xi2.c')
-rw-r--r--src/frame-xi2.c246
1 files changed, 246 insertions, 0 deletions
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;
+}