From a2ef8bcda6cd3864b4c367579defb52ecad19657 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 13 May 2010 23:21:37 +0200 Subject: Add scale gesture Moving two fingers apart or closer together will trigger the gesture. This patch computes the scaling gesture and maps it to mouse buttons 12 and 13. Signed-off-by: Henrik Rydberg --- src/gestures.c | 34 +++++++++++++++++++++++++++++++++- src/gestures.h | 3 ++- src/hwdata.h | 4 +++- src/multitouch.c | 13 +++++++++++-- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/gestures.c b/src/gestures.c index 977655c..03ec96d 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -70,22 +70,32 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt) int npoint = bitcount(mt->mem.pointing); int nmove = bitcount(mt->mem.moving); int i; + float xp[DIM_FINGER], yp[DIM_FINGER]; float xm[DIM_FINGER], ym[DIM_FINGER]; - float xmove = 0, ymove = 0; + float xpos = 0, ypos = 0; + float move, xmove = 0, ymove = 0; + float rad, rad2 = 0, scale = 0; if (!nmove || nmove != npoint) return; foreach_bit(i, mt->mem.moving) { + xp[i] = mt->state.finger[i].hw.position_x - xpos; + yp[i] = mt->state.finger[i].hw.position_y - ypos; xm[i] = mt->mem.dx[i]; ym[i] = mt->mem.dy[i]; mt->mem.dx[i] = 0; mt->mem.dy[i] = 0; + xpos += xp[i]; + ypos += yp[i]; xmove += xm[i]; ymove += ym[i]; } + xpos /= nmove; + ypos /= nmove; xmove /= nmove; ymove /= nmove; + move = sqrt(xmove * xmove + ymove * ymove); if (nmove == 1) { if (mt->mem.moving & mt->mem.thumb) { @@ -96,6 +106,28 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt) gs->dy = ymove; if (gs->dx || gs->dy) SETBIT(gs->type, GS_MOVE); + return; + } + + foreach_bit(i, mt->mem.moving) { + xp[i] -= xpos; + yp[i] -= ypos; + rad2 += xp[i] * xp[i]; + rad2 += yp[i] * yp[i]; + scale += xp[i] * xm[i]; + scale += yp[i] * ym[i]; + } + rad2 /= nmove; + scale /= nmove; + rad = sqrt(rad2); + scale /= rad; + + if (abs(scale) > move) { + gs->scale = scale; + if (gs->scale) { + if (nmove == 2) + SETBIT(gs->type, GS_SCALE); + } } else { if (mt->mem.moving & mt->mem.thumb) { mt_skip_movement(mt, FINGER_THUMB_MS); diff --git a/src/gestures.h b/src/gestures.h index 5630d4c..5739d45 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -30,10 +30,11 @@ #define GS_HSCROLL 3 #define GS_VSWIPE 4 #define GS_HSWIPE 5 +#define GS_SCALE 6 struct Gestures { unsigned type, btmask, btdata; - int same_fingers, dx, dy; + int same_fingers, dx, dy, scale; }; void extract_gestures(struct Gestures *gs, struct MTouch* mt); diff --git a/src/hwdata.h b/src/hwdata.h index 5dd99cf..867a295 100644 --- a/src/hwdata.h +++ b/src/hwdata.h @@ -24,7 +24,7 @@ #include "common.h" -#define DIM_BUTTON 11 +#define DIM_BUTTON 13 #define MT_BUTTON_LEFT 0 #define MT_BUTTON_MIDDLE 1 @@ -37,6 +37,8 @@ #define MT_BUTTON_SWIPE_DOWN 8 #define MT_BUTTON_SWIPE_LEFT 9 #define MT_BUTTON_SWIPE_RIGHT 10 +#define MT_BUTTON_SCALE_DOWN 11 +#define MT_BUTTON_SCALE_UP 12 #define BIT_MT_TOUCH_MAJOR 0 #define BIT_MT_TOUCH_MINOR 1 diff --git a/src/multitouch.c b/src/multitouch.c index a11b8da..6281a5b 100644 --- a/src/multitouch.c +++ b/src/multitouch.c @@ -31,6 +31,7 @@ static const float vscroll_fraction = 0.05; static const float hscroll_fraction = 0.05; static const float vswipe_fraction = 0.25; static const float hswipe_fraction = 0.25; +static const float scale_fraction = 0.05; /* flip these to enable event debugging */ #if 1 @@ -81,6 +82,9 @@ static void initButtonLabels(Atom map[DIM_BUTTON]) PROPMAP(map, MT_BUTTON_SWIPE_DOWN, BTN_LABEL_PROP_BTN_1); PROPMAP(map, MT_BUTTON_SWIPE_LEFT, BTN_LABEL_PROP_BTN_2); PROPMAP(map, MT_BUTTON_SWIPE_RIGHT, BTN_LABEL_PROP_BTN_3); + /* how to map scale and rotate? */ + PROPMAP(map, MT_BUTTON_SCALE_DOWN, BTN_LABEL_PROP_BTN_4); + PROPMAP(map, MT_BUTTON_SCALE_UP, BTN_LABEL_PROP_BTN_5); } #endif @@ -88,7 +92,7 @@ static int device_init(DeviceIntPtr dev, LocalDevicePtr local) { struct MTouch *mt = local->private; unsigned char btmap[DIM_BUTTON + 1] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 Atom axes_labels[2], btn_labels[DIM_BUTTON]; @@ -209,11 +213,12 @@ static void handle_gestures(LocalDevicePtr local, const struct Gestures *gs, const struct Capabilities *caps) { - static int vscroll, hscroll, vswipe, hswipe; + static int vscroll, hscroll, vswipe, hswipe, scale; int vscrollstep = 1 + vscroll_fraction * get_cap_ysize(caps); int hscrollstep = 1 + hscroll_fraction * get_cap_xsize(caps); int vswipestep = 1 + vswipe_fraction * get_cap_ysize(caps); int hswipestep = 1 + hswipe_fraction * get_cap_xsize(caps); + int scalestep = 1 + scale_fraction * get_cap_xsize(caps); int i; if (!gs->same_fingers) { vscroll = 0; @@ -249,6 +254,10 @@ static void handle_gestures(LocalDevicePtr local, button_scroll(local, 10, 11, &hswipe, hswipestep, gs->dx); TRACE1("hswipe: %d\n", gs->dx); } + if (GETBIT(gs->type, GS_SCALE)) { + button_scroll(local, 12, 13, &scale, scalestep, gs->scale); + TRACE1("scale: %d\n", gs->scale); + } } /* called for each full received packet from the touchpad */ -- cgit v1.2.3