summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-12-05 16:15:23 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-12-05 16:15:23 +1000
commitf4f3e878291fdc5fab8d53cec4d0d352879f6261 (patch)
tree838a2f67e1de853d2b5a34fc4dc391207804874a
parentc5416f08fa3353b876a64c60bbf03bc41c581466 (diff)
Register for pointer events if requested
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--multitouch.c119
1 files changed, 104 insertions, 15 deletions
diff --git a/multitouch.c b/multitouch.c
index e528904..638b0b6 100644
--- a/multitouch.c
+++ b/multitouch.c
@@ -25,14 +25,20 @@
static void usage(void)
{
- printf("Usage: %s [--with-ownership]\n", program_invocation_short_name);
- printf(" Grey window: normal touch surface, with or without ownership\n");
+ printf("Usage: %s [--with-ownership|--pointer-events]\n", program_invocation_short_name);
+ printf(" Grey window: normal touch surface, with or without ownership (or pointer events)\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");
printf(" Lower White bar left: grabs the touchpoint, with ownership, rejects\n");
}
+enum Mode {
+ MODE_DEFAULT, /* touch events, no ownership */
+ MODE_OWNERSHIP, /* touch events, with ownership */
+ MODE_POINTER, /* pointer events */
+};
+
enum TouchState {
TSTATE_END = 0,
TSTATE_BEGIN,
@@ -93,6 +99,8 @@ struct multitouch {
size_t ngrabs;
Bool needs_ownership;
+
+ int last_x, last_y; /* pointer coords */
};
static void expose(struct multitouch *mt, int x1, int y1, int x2, int y2);
@@ -126,7 +134,7 @@ static void sighandler(int signal)
error("signal received, shutting down\n");
}
-static void init_windows(struct multitouch *mt, Bool ownership)
+static void init_windows(struct multitouch *mt, enum Mode mode)
{
Window win, subwin;
XEvent event;
@@ -164,15 +172,26 @@ static void init_windows(struct multitouch *mt, Bool ownership)
memset(mask, 0, sizeof(mask));
evmask.deviceid = XIAllMasterDevices;
- /* select for touch events on main window */
+ /* select for touch or pointer events on main window */
+ if (mode == MODE_POINTER)
+ {
+ XISetMask(mask, XI_ButtonPress);
+ XISetMask(mask, XI_Motion);
+ XISetMask(mask, XI_ButtonRelease);
+ } else {
+ XISetMask(mask, XI_TouchBegin);
+ XISetMask(mask, XI_TouchUpdate);
+ XISetMask(mask, XI_TouchEnd);
+ if (mode == MODE_OWNERSHIP)
+ XISetMask(mask, XI_TouchOwnership);
+ }
+
+ XISelectEvents(mt->dpy, win, &evmask, 1);
+
+ memset(mask, 0, sizeof(mask));
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;
@@ -216,7 +235,7 @@ static GC init_gc(struct multitouch *mt)
return gc;
}
-static int init_x11(struct multitouch *mt, int width, int height, Bool ownership)
+static int init_x11(struct multitouch *mt, int width, int height, enum Mode mode)
{
Display *dpy;
int major = 2, minor = 2;
@@ -242,7 +261,7 @@ static int init_x11(struct multitouch *mt, int width, int height, Bool ownership
mt->width = width;
mt->height = height;
- init_windows(mt, ownership);
+ init_windows(mt, mode);
mt->pixmap = init_pixmap(mt);
mt->gc = init_gc(mt);
@@ -291,10 +310,13 @@ static void print_event(struct multitouch *mt, XIDeviceEvent* event)
case XI_TouchUpdate: type = "TouchUpdate"; break;
case XI_TouchEnd: type = "TouchEnd"; break;
case XI_TouchOwnership: type = "TouchOwnership"; break;
+ case XI_Motion: type = "Motion"; break;
+ case XI_ButtonPress: type = "ButtonPress"; break;
+ case XI_ButtonRelease: type = "ButtonRelease"; break;
}
msg("Event: %s (%d)\n", type, event->deviceid);
msg("\t%.2f/%.2f (%.2f/%.2f)\n", event->event_x, event->event_y, event->root_x, event->root_y);
- msg("\ttouchid: %d\n", event->detail);
+ msg("\tdetail: %d\n", event->detail);
msg("\ton %s\n", window_to_name(mt, event->event));
if (event->flags & XITouchPendingEnd)
msg("\tflags: pending end\n");
@@ -528,6 +550,56 @@ static void handle_ownership(struct multitouch *mt, XITouchOwnershipEvent *event
expose(mt, t->x - radius/2, t->y - radius/2, t->x + radius/2, t->y + radius/2);
}
+static void paint_pointer_event(struct multitouch *mt, XIDeviceEvent *event)
+{
+ const int xsize = 20;
+ int i;
+ if (event->evtype == XI_Motion)
+ {
+ int bt_down = False;
+ for (i = 0; i < event->buttons.mask_len && !bt_down; i++)
+ bt_down = event->buttons.mask[i];
+ if (!bt_down)
+ goto out; /* don't care about motion events when not down */
+ }
+
+ cairo_save(mt->cr);
+ cairo_set_source_rgba(mt->cr, 1, 1, 0, 1);
+ if (mt->last_x != -1 && mt->last_y != -1)
+ {
+ cairo_move_to(mt->cr, mt->last_x, mt->last_y);
+ cairo_line_to(mt->cr, event->event_x, event->event_y);
+ cairo_stroke(mt->cr);
+ expose(mt, mt->last_x, mt->last_y, event->event_x, event->event_y);
+ }
+
+ if (event->evtype != XI_Motion)
+ {
+ if (event->evtype == XI_ButtonPress)
+ {
+ cairo_move_to(mt->cr, event->event_x - xsize/2, event->event_y - xsize/2);
+ cairo_line_to(mt->cr, event->event_x + xsize/2, event->event_y + xsize/2);
+ cairo_move_to(mt->cr, event->event_x + xsize/2, event->event_y - xsize/2);
+ cairo_line_to(mt->cr, event->event_x - xsize/2, event->event_y + xsize/2);
+ } else {
+ cairo_move_to(mt->cr, event->event_x, event->event_y - xsize/2);
+ cairo_line_to(mt->cr, event->event_x, event->event_y + xsize/2);
+ cairo_move_to(mt->cr, event->event_x + xsize/2, event->event_y);
+ cairo_line_to(mt->cr, event->event_x - xsize/2, event->event_y);
+ }
+ cairo_stroke(mt->cr);
+ expose(mt, event->event_x - xsize/2, event->event_x - xsize/2,
+ event->event_x + xsize/2, event->event_x + xsize/2);
+ }
+
+ cairo_restore(mt->cr);
+
+out:
+ mt->last_x = event->event_x;
+ mt->last_y = event->event_y;
+
+}
+
static void paint_event(struct multitouch *mt, XIDeviceEvent *event)
{
if (event->event == mt->blackbar || event->event == mt->whitebar ||
@@ -543,6 +615,11 @@ static void paint_event(struct multitouch *mt, XIDeviceEvent *event)
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;
+ case XI_Motion:
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ paint_pointer_event(mt, event);
+ break;
}
}
@@ -663,6 +740,7 @@ static void init(struct multitouch *mt, Bool ownership)
mt->ntouches = MAX_TOUCHES;
mt->ngrabs = MAX_TOUCHES;
mt->needs_ownership = ownership;
+ mt->last_x = mt->last_y = -1;
}
int main(int argc, char **argv)
@@ -670,15 +748,26 @@ int main(int argc, char **argv)
int rc;
struct multitouch mt;
Bool ownership = False;
+ enum Mode mode = MODE_DEFAULT;
usage();
- if (argc > 1 && strcmp(argv[1], "--with-ownership") == 0)
- ownership = True;
+ if (argc > 1)
+ {
+ if(strcmp(argv[1], "--with-ownership") == 0)
+ {
+ mode = MODE_OWNERSHIP;
+ msg("ownership events selected\n");
+ } else if (strcmp(argv[1], "--pointer-events") == 0)
+ {
+ mode = MODE_POINTER;
+ msg("pointer events selected\n");
+ }
+ }
init(&mt, ownership);
- rc = init_x11(&mt, 800, 600, ownership);
+ rc = init_x11(&mt, 800, 600, mode);
if (rc != EXIT_SUCCESS)
return rc;