summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-11-02 17:24:31 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-11-02 17:24:31 +1000
commit35bc0b4de7974e72f44f79f62bfa7d2e8882cfc6 (patch)
tree663fc03215520c41c8c59b87d16d8ab93e8e94ba
parentb7f2a59dd947e9d659aa1492cbcb962fa9eea785 (diff)
Draw the touches as they come in
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--multitouch.c112
1 files changed, 111 insertions, 1 deletions
diff --git a/multitouch.c b/multitouch.c
index 654719c..f0a7c77 100644
--- a/multitouch.c
+++ b/multitouch.c
@@ -8,6 +8,8 @@
#include <stdarg.h>
#include <signal.h>
#include <poll.h>
+#include <stdint.h>
+#include <math.h>
#include <cairo.h>
#include <cairo-xlib.h>
@@ -16,6 +18,20 @@
#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>
+#define MAX_TOUCHES 10
+
+enum TouchState {
+ TSTATE_END = 0,
+ TSTATE_BEGIN,
+ TSTATE_UPDATE,
+};
+
+struct touchpoint {
+ enum TouchState state;
+ uint32_t touchid; /* 0 == unused */
+ double x, y; /* last recorded x/y position */
+};
+
struct multitouch {
Display *dpy;
int screen_no;
@@ -35,6 +51,9 @@ struct multitouch {
cairo_t *cr_win;
cairo_surface_t *surface;
cairo_surface_t *surface_win;
+
+ struct touchpoint touches[MAX_TOUCHES];
+ int ntouches;
};
static void expose(struct multitouch *mt, int x1, int y1, int x2, int y2);
@@ -171,6 +190,87 @@ static void print_event(struct multitouch *mt, XIDeviceEvent* event)
msg("\ttouchid: %d\n", event->detail);
}
+static void paint_touch_begin(struct multitouch *mt, XIDeviceEvent *event)
+{
+ int i;
+ int radius = 30;
+ struct touchpoint *t = NULL;
+
+ for (i = 0; i < mt->ntouches; i++)
+ {
+ if (mt->touches[i].state == TSTATE_END)
+ {
+ t = &mt->touches[i];
+ break;
+ }
+ }
+ if (!t)
+ {
+ error("Too many touchpoints, skipping\n");
+ return;
+ }
+
+ t->touchid = event->detail;
+ t->x = event->event_x;
+ t->y = event->event_y;
+ t->state = TSTATE_BEGIN;
+
+ cairo_set_source_rgb(mt->cr, 0, 0, 0);
+ cairo_arc(mt->cr, t->x, t->y, radius, 0, 2 * M_PI);
+ cairo_stroke(mt->cr);
+ expose(mt, t->x - radius, t->y - radius, t->x + radius, t->y + radius);
+}
+
+static struct touchpoint* find_touch(struct multitouch *mt, uint32_t touchid)
+{
+ int i;
+
+ for (i = 0; i < mt->ntouches; i++)
+ if (mt->touches[i].state != TSTATE_END)
+ return &mt->touches[i];
+
+ return NULL;
+}
+
+static void paint_touch_update(struct multitouch *mt, XIDeviceEvent *event)
+{
+ struct touchpoint *t = find_touch(mt, event->detail);
+
+ cairo_move_to(mt->cr, t->x, t->y);
+ cairo_line_to(mt->cr, event->event_x, event->event_y);
+ cairo_stroke(mt->cr);
+ expose(mt, t->x, t->y, event->event_x, event->event_y);
+
+ t->x = event->event_x;
+ t->y = event->event_y;
+ t->state = TSTATE_UPDATE;
+}
+
+static void paint_touch_end(struct multitouch *mt, XIDeviceEvent *event)
+{
+ int rsize = 30;
+ struct touchpoint *t = find_touch(mt, event->detail);
+
+ t->x = event->event_x;
+ t->y = event->event_y;
+ t->state = TSTATE_END;
+
+ cairo_rectangle(mt->cr, t->x - rsize/2, t->y - rsize/2, rsize, rsize);
+ cairo_stroke(mt->cr);
+ expose(mt, t->x - rsize/2, t->y - rsize/2, t->x + rsize/2, t->y + rsize/2);
+
+}
+
+static void paint_event(struct multitouch *mt, XIDeviceEvent *event)
+{
+ switch(event->evtype)
+ {
+ case XI_TouchBegin: paint_touch_begin(mt, event); break;
+ case XI_TouchUpdate: paint_touch_update(mt, event); break;
+ case XI_TouchEnd: paint_touch_end(mt, event); break;
+ }
+}
+
static int init_cairo(struct multitouch *mt)
{
cairo_surface_t *surface;
@@ -251,6 +351,7 @@ static int main_loop(struct multitouch *mt)
cookie->type == GenericEvent &&
cookie->extension == mt->xi_opcode)
{
+ paint_event(mt, cookie->data);
print_event(mt, cookie->data);
}
@@ -261,10 +362,19 @@ static int main_loop(struct multitouch *mt)
return EXIT_SUCCESS;
}
+static void init(struct multitouch *mt)
+{
+ memset(mt, 0, sizeof(*mt));
+
+ mt->ntouches = MAX_TOUCHES;
+}
+
int main(int argc, char **argv)
{
int rc;
- struct multitouch mt = { 0 };
+ struct multitouch mt;
+
+ init(&mt);
rc = init_x11(&mt, 800, 600);
if (rc != EXIT_SUCCESS)