summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-11-10 16:02:55 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-11-10 16:02:55 +1000
commit55d88994f09b76cab8883055c60fd72d24efb04f (patch)
tree3acb078533f8fa021fcc38580d5678ce579e2f77
parentc47a4ddf50304a43474211aa40532c16e6f39669 (diff)
Add --with-ownership flag and the matching event handling
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--multitouch.c54
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;