diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-11-10 16:02:55 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-11-10 16:02:55 +1000 |
commit | 55d88994f09b76cab8883055c60fd72d24efb04f (patch) | |
tree | 3acb078533f8fa021fcc38580d5678ce579e2f77 | |
parent | c47a4ddf50304a43474211aa40532c16e6f39669 (diff) |
Add --with-ownership flag and the matching event handling
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r-- | multitouch.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/multitouch.c b/multitouch.c index 7adf6f0..35b4a39 100644 --- a/multitouch.c +++ b/multitouch.c @@ -2,6 +2,7 @@ #include <config.h> #endif +#define _GNU_SOURCE #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -11,6 +12,8 @@ #include <stdint.h> #include <math.h> +#include <errno.h> + #include <cairo.h> #include <cairo-xlib.h> @@ -22,8 +25,8 @@ static void usage(void) { - printf("Usage:\n"); - printf(" Grey window: normal touch surface\n"); + printf("Usage: %s [--with-ownership]\n", program_invocation_short_name); + printf(" Grey window: normal touch surface, with or without ownership\n"); printf(" Upper black bar left: grabs the touchpoint, no ownership, accepts\n"); printf(" Upper White bar left: grabs the touchpoint, no ownership, rejects\n"); printf(" Lower black bar left: grabs the touchpoint, with ownership, accepts\n"); @@ -40,6 +43,7 @@ struct touchpoint { enum TouchState state; uint32_t touchid; /* 0 == unused */ double x, y; /* last recorded x/y position */ + Bool owned; }; struct grabpoint { @@ -81,6 +85,8 @@ struct multitouch { struct grabpoint grabs[MAX_TOUCHES]; size_t ngrabs; + + Bool needs_ownership; }; static void expose(struct multitouch *mt, int x1, int y1, int x2, int y2); @@ -114,7 +120,7 @@ static void sighandler(int signal) error("signal received, shutting down\n"); } -static void init_windows(struct multitouch *mt) +static void init_windows(struct multitouch *mt, Bool ownership) { Window win, subwin; XEvent event; @@ -156,8 +162,11 @@ static void init_windows(struct multitouch *mt) XISetMask(mask, XI_TouchBegin); XISetMask(mask, XI_TouchUpdate); XISetMask(mask, XI_TouchEnd); + if (ownership) + XISetMask(mask, XI_TouchOwnership); XISelectEvents(mt->dpy, win, &evmask, 1); + XIClearMask(mask, XI_TouchOwnership); /* grab touch events on blackbar */ modifiers.modifiers = XIAnyModifier; @@ -201,7 +210,7 @@ static GC init_gc(struct multitouch *mt) return gc; } -static int init_x11(struct multitouch *mt, int width, int height) +static int init_x11(struct multitouch *mt, int width, int height, Bool ownership) { Display *dpy; int major = 2, minor = 2; @@ -227,7 +236,7 @@ static int init_x11(struct multitouch *mt, int width, int height) mt->width = width; mt->height = height; - init_windows(mt); + init_windows(mt, ownership); mt->pixmap = init_pixmap(mt); mt->gc = init_gc(mt); @@ -305,9 +314,10 @@ static void paint_touch_begin(struct multitouch *mt, XIDeviceEvent *event) t->x = event->event_x; t->y = event->event_y; t->state = TSTATE_BEGIN; + t->owned = !mt->needs_ownership; cairo_save(mt->cr); - cairo_set_source_rgb(mt->cr, 0, 0, 0); + cairo_set_source_rgba(mt->cr, 0, 0, 0, t->owned ? 1 : .5); cairo_arc(mt->cr, t->x, t->y, radius, 0, 2 * M_PI); cairo_stroke(mt->cr); cairo_restore(mt->cr); @@ -331,7 +341,7 @@ static void paint_touch_update(struct multitouch *mt, XIDeviceEvent *event) struct touchpoint *t = find_touch(mt, event->detail); cairo_save(mt->cr); - cairo_set_source_rgb(mt->cr, 0, 0, 0); + cairo_set_source_rgba(mt->cr, 0, 0, 0, t->owned ? 1 : .5); cairo_move_to(mt->cr, t->x, t->y); cairo_line_to(mt->cr, event->event_x, event->event_y); cairo_stroke(mt->cr); @@ -353,7 +363,7 @@ static void paint_touch_end(struct multitouch *mt, XIDeviceEvent *event) t->state = TSTATE_END; cairo_save(mt->cr); - cairo_set_source_rgb(mt->cr, 0, 0, 0); + cairo_set_source_rgba(mt->cr, 0, 0, 0, t->owned ? 1 : .5); cairo_rectangle(mt->cr, t->x - rsize/2, t->y - rsize/2, rsize, rsize); cairo_stroke(mt->cr); cairo_restore(mt->cr); @@ -398,7 +408,7 @@ static void paint_grabs(struct multitouch *mt) } else { r = 0; g = 1; b = 1; - offset = 3 * mt->height/2; + offset = 3 * mt->height/4; } cairo_save(mt->cr_grabs); @@ -475,6 +485,20 @@ static void handle_grabbed_event(struct multitouch *mt, XIDeviceEvent *event) } } +static void handle_ownership(struct multitouch *mt, XITouchOwnershipEvent *event) +{ + const int radius = 10; + struct touchpoint *t = find_touch(mt, event->touchid); + t->owned = True; + + cairo_save(mt->cr); + cairo_set_source_rgba(mt->cr, 1, 0, 0, t->owned ? 1 : .5); + cairo_arc(mt->cr, t->x, t->y, radius, 0, 2 * M_PI); + cairo_stroke(mt->cr); + cairo_restore(mt->cr); + expose(mt, t->x - radius/2, t->y - radius/2, t->x + radius/2, t->y + radius/2); +} + static void paint_event(struct multitouch *mt, XIDeviceEvent *event) { if (event->event == mt->blackbar || event->event == mt->whitebar || @@ -489,6 +513,7 @@ static void paint_event(struct multitouch *mt, XIDeviceEvent *event) 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; + case XI_TouchOwnership: handle_ownership(mt, (XITouchOwnershipEvent*)event); break; } } @@ -602,24 +627,29 @@ static int main_loop(struct multitouch *mt) return EXIT_SUCCESS; } -static void init(struct multitouch *mt) +static void init(struct multitouch *mt, Bool ownership) { memset(mt, 0, sizeof(*mt)); mt->ntouches = MAX_TOUCHES; mt->ngrabs = MAX_TOUCHES; + mt->needs_ownership = ownership; } int main(int argc, char **argv) { int rc; struct multitouch mt; + Bool ownership = False; usage(); - init(&mt); + if (argc > 1 && strcmp(argv[1], "--with-ownership") == 0) + ownership = True; + + init(&mt, ownership); - rc = init_x11(&mt, 800, 600); + rc = init_x11(&mt, 800, 600, ownership); if (rc != EXIT_SUCCESS) return rc; |