From 2f23f280d5bff3d5aa3f6115ecc05fa73b1cc2bb Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 13 May 2010 23:21:37 +0200 Subject: Add rotation gesture Moving two fingers around a center point will trigger the gesture. This patch computes the rotation gesture and maps it to mouse buttons 14 and 15. Signed-off-by: Henrik Rydberg --- src/gestures.c | 15 +++++++++++++-- src/gestures.h | 3 ++- src/hwdata.h | 4 +++- src/multitouch.c | 12 ++++++++++-- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/gestures.c b/src/gestures.c index 03ec96d..2dafe79 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -74,7 +74,8 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt) float xm[DIM_FINGER], ym[DIM_FINGER]; float xpos = 0, ypos = 0; float move, xmove = 0, ymove = 0; - float rad, rad2 = 0, scale = 0; + float rad, rad2 = 0, scale = 0, rot = 0; + if (!nmove || nmove != npoint) return; @@ -116,13 +117,23 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt) rad2 += yp[i] * yp[i]; scale += xp[i] * xm[i]; scale += yp[i] * ym[i]; + rot += xp[i] * ym[i]; + rot -= yp[i] * xm[i]; } rad2 /= nmove; scale /= nmove; + rot /= nmove; rad = sqrt(rad2); scale /= rad; + rot /= rad; - if (abs(scale) > move) { + if (abs(rot) > move && abs(rot) > abs(scale)) { + gs->rot = rot; + if (gs->rot) { + if (nmove == 2) + SETBIT(gs->type, GS_ROTATE); + } + } else if (abs(scale) > move) { gs->scale = scale; if (gs->scale) { if (nmove == 2) diff --git a/src/gestures.h b/src/gestures.h index 5739d45..2866ba4 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -31,10 +31,11 @@ #define GS_VSWIPE 4 #define GS_HSWIPE 5 #define GS_SCALE 6 +#define GS_ROTATE 7 struct Gestures { unsigned type, btmask, btdata; - int same_fingers, dx, dy, scale; + int same_fingers, dx, dy, scale, rot; }; void extract_gestures(struct Gestures *gs, struct MTouch* mt); diff --git a/src/hwdata.h b/src/hwdata.h index 867a295..42d0a19 100644 --- a/src/hwdata.h +++ b/src/hwdata.h @@ -24,7 +24,7 @@ #include "common.h" -#define DIM_BUTTON 13 +#define DIM_BUTTON 15 #define MT_BUTTON_LEFT 0 #define MT_BUTTON_MIDDLE 1 @@ -39,6 +39,8 @@ #define MT_BUTTON_SWIPE_RIGHT 10 #define MT_BUTTON_SCALE_DOWN 11 #define MT_BUTTON_SCALE_UP 12 +#define MT_BUTTON_ROTATE_LEFT 13 +#define MT_BUTTON_ROTATE_RIGHT 14 #define BIT_MT_TOUCH_MAJOR 0 #define BIT_MT_TOUCH_MINOR 1 diff --git a/src/multitouch.c b/src/multitouch.c index 6281a5b..3dde667 100644 --- a/src/multitouch.c +++ b/src/multitouch.c @@ -32,6 +32,7 @@ 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; +static const float rot_fraction = 0.05; /* flip these to enable event debugging */ #if 1 @@ -85,6 +86,8 @@ static void initButtonLabels(Atom map[DIM_BUTTON]) /* 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); + PROPMAP(map, MT_BUTTON_ROTATE_LEFT, BTN_LABEL_PROP_BTN_6); + PROPMAP(map, MT_BUTTON_ROTATE_RIGHT, BTN_LABEL_PROP_BTN_7); } #endif @@ -92,7 +95,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, 12, 13 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 Atom axes_labels[2], btn_labels[DIM_BUTTON]; @@ -213,12 +216,13 @@ static void handle_gestures(LocalDevicePtr local, const struct Gestures *gs, const struct Capabilities *caps) { - static int vscroll, hscroll, vswipe, hswipe, scale; + static int vscroll, hscroll, vswipe, hswipe, scale, rot; 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 rotstep = 1 + rot_fraction * get_cap_xsize(caps); int i; if (!gs->same_fingers) { vscroll = 0; @@ -258,6 +262,10 @@ static void handle_gestures(LocalDevicePtr local, button_scroll(local, 12, 13, &scale, scalestep, gs->scale); TRACE1("scale: %d\n", gs->scale); } + if (GETBIT(gs->type, GS_ROTATE)) { + button_scroll(local, 14, 15, &rot, rotstep, gs->rot); + TRACE1("rotate: %d\n", gs->rot); + } } /* called for each full received packet from the touchpad */ -- cgit v1.2.3