diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-11-02 17:24:31 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-11-02 17:24:31 +1000 |
commit | 35bc0b4de7974e72f44f79f62bfa7d2e8882cfc6 (patch) | |
tree | 663fc03215520c41c8c59b87d16d8ab93e8e94ba | |
parent | b7f2a59dd947e9d659aa1492cbcb962fa9eea785 (diff) |
Draw the touches as they come in
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r-- | multitouch.c | 112 |
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) |