summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-11-07 10:47:51 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-11-07 10:48:01 +1000
commit60021af70471857ca7418a116b838120019ef65d (patch)
treecceea654a93b6d5a02db056e4be111f35ca7e35c
parent9b69359671a33c4f8184f9c3206a0da9a8dff417 (diff)
Draw a line from the grab start point to the current one.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--multitouch.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/multitouch.c b/multitouch.c
index 232fbe6..1e44c86 100644
--- a/multitouch.c
+++ b/multitouch.c
@@ -32,6 +32,13 @@ struct touchpoint {
double x, y; /* last recorded x/y position */
};
+struct grabpoint {
+ enum TouchState state;
+ uint32_t touchid;
+ double startx, starty; /* x/y of TouchBegin */
+ double x, y; /* last recorded x/y position */
+};
+
struct multitouch {
Display *dpy;
int screen_no;
@@ -50,11 +57,16 @@ struct multitouch {
cairo_t *cr;
cairo_t *cr_win;
+ cairo_t *cr_grabs;
cairo_surface_t *surface;
cairo_surface_t *surface_win;
+ cairo_surface_t *surface_grabs;
struct touchpoint touches[MAX_TOUCHES];
int ntouches;
+
+ struct grabpoint grabs[MAX_TOUCHES];
+ size_t ngrabs;
};
static void expose(struct multitouch *mt, int x1, int y1, int x2, int y2);
@@ -281,10 +293,65 @@ static void paint_touch_end(struct multitouch *mt, XIDeviceEvent *event)
}
+static void handle_grabbed_event(struct multitouch *mt, XIDeviceEvent *event)
+{
+ struct grabpoint *grab = NULL;
+ const int radius = 50;
+
+ int i;
+ for (i = 0; i < mt->ngrabs; i++)
+ {
+ grab = &mt->grabs[i];
+ if (event->evtype == XI_TouchBegin && grab->state == TSTATE_END)
+ {
+ grab->state = TSTATE_BEGIN;
+ grab->touchid = event->detail;
+ grab->startx = event->event_x;
+ grab->starty = event->event_y;
+ break;
+ } else if (event->evtype != XI_TouchBegin) {
+ if (grab->state != TSTATE_END && grab->touchid == event->detail)
+ break;
+ }
+ }
+ if (!grab) {
+ error("oops, touchpoint for %d (touchid %d) not found\n",
+ event->evtype, event->detail);
+ return;
+ }
+
+ /* clear the whole area */
+ cairo_save(mt->cr_grabs);
+ cairo_save(mt->cr_grabs);
+ cairo_set_operator(mt->cr_grabs, CAIRO_OPERATOR_CLEAR);
+ cairo_paint(mt->cr_grabs);
+ cairo_restore(mt->cr_grabs);
+
+ /* draw starting circle */
+ cairo_set_source_rgba(mt->cr_grabs, 0, 0, 1, 1);
+ cairo_arc(mt->cr_grabs, grab->startx, grab->starty, radius, 0, 2 * M_PI);
+ cairo_stroke(mt->cr_grabs);
+
+ grab->x = event->event_x;
+ grab->y = event->event_y;
+
+ /* draw line to current point */
+ cairo_set_source_rgba(mt->cr_grabs, 0, 0, 1, 1);
+ cairo_move_to(mt->cr_grabs, grab->startx, grab->starty);
+ cairo_line_to(mt->cr_grabs, grab->x, grab->y);
+ cairo_stroke(mt->cr_grabs);
+ cairo_restore(mt->cr_grabs);
+
+ expose(mt, grab->startx, grab->starty, grab->x, grab->y);
+}
+
static void paint_event(struct multitouch *mt, XIDeviceEvent *event)
{
if (event->event == mt->toolbar)
+ {
+ handle_grabbed_event(mt, event);
return;
+ }
switch(event->evtype)
{
@@ -313,6 +380,21 @@ static int init_cairo(struct multitouch *mt)
mt->cr_win = cr;
+ /* grab drawing backbuffer */
+ surface = cairo_surface_create_similar(surface,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ mt->width, mt->height);
+ if (!surface)
+ return error("Failed to create cairo surface\n");
+
+ mt->surface_grabs = surface;
+
+ cr = cairo_create(surface);
+ if (!cr)
+ return error("Failed to create cairo context\n");
+
+ mt->cr_grabs = cr;
+
/* backbuffer */
surface = cairo_surface_create_similar(surface,
CAIRO_CONTENT_COLOR_ALPHA,
@@ -345,6 +427,12 @@ static void expose(struct multitouch *mt, int x1, int y1, int x2, int y2)
{
cairo_set_source_surface(mt->cr_win, mt->surface, 0, 0);
cairo_paint(mt->cr_win);
+
+ cairo_save(mt->cr_win);
+ cairo_set_source_surface(mt->cr_win, mt->surface_grabs, 0, 0);
+ cairo_mask_surface(mt->cr_win, mt->surface_grabs, 0, 0);
+ cairo_restore(mt->cr_win);
+
}
static int main_loop(struct multitouch *mt)
@@ -390,6 +478,7 @@ static void init(struct multitouch *mt)
memset(mt, 0, sizeof(*mt));
mt->ntouches = MAX_TOUCHES;
+ mt->ngrabs = MAX_TOUCHES;
}
int main(int argc, char **argv)