summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-05-13 23:21:37 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-05-14 01:41:39 +0200
commita2ef8bcda6cd3864b4c367579defb52ecad19657 (patch)
tree902391874bd1982f99854c33728abdee77913004 /src
parent32dea71a85ac1b46c35bf85f456f3c4772b30e76 (diff)
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 <rydberg@euromail.se>
Diffstat (limited to 'src')
-rw-r--r--src/gestures.c34
-rw-r--r--src/gestures.h3
-rw-r--r--src/hwdata.h4
-rw-r--r--src/multitouch.c13
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 */