summaryrefslogtreecommitdiff
path: root/src/gestures.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-04-14 15:39:44 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-04-15 06:10:08 +0200
commitd9bbb8d87508677dda2be8df7e26213774f3166c (patch)
tree989a541415c1052f648a7aaa27ac9837afcd5170 /src/gestures.c
parent428a29ac5dc8ebf6a1092c2d989fa020d79791af (diff)
Extract moving fingers
The current code determines the moving, scrolling and swiping gestures based on the number of fingers on the trackpad, including the resting fingers at the bottom of the pad. With information about all fingers at hand, it is possible to determine which fingers on the trackpad are participating in a moving gesture. This patch computes the movement based on the pointing fingers only, and uses that number to determine the type of moving gesture. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/gestures.c')
-rw-r--r--src/gestures.c69
1 files changed, 52 insertions, 17 deletions
diff --git a/src/gestures.c b/src/gestures.c
index 915a521..3502255 100644
--- a/src/gestures.c
+++ b/src/gestures.c
@@ -25,10 +25,23 @@
25 25
26#include "gestures.h" 26#include "gestures.h"
27 27
28#define DELTA_CUT(x) (0.2 * (x))
29
28/* timer for cursor stability on finger touch/release */ 30/* timer for cursor stability on finger touch/release */
29static const int FINGER_ATTACK_MS = 70; 31static const int FINGER_ATTACK_MS = 70;
30static const int FINGER_DECAY_MS = 120; 32static const int FINGER_DECAY_MS = 120;
31 33
34static inline int maxval(int x, int y) { return x > y ? x : y; }
35
36inline int dxval(const struct FingerState *a, const struct FingerState *b)
37{
38 return a->hw.position_x - b->hw.position_x;
39}
40inline int dyval(const struct FingerState *a, const struct FingerState *b)
41{
42 return a->hw.position_y - b->hw.position_y;
43}
44
32static void extract_pointers(struct Gestures *gs, struct MTouch* mt) 45static void extract_pointers(struct Gestures *gs, struct MTouch* mt)
33{ 46{
34 const struct FingerState *f = mt->state.finger; 47 const struct FingerState *f = mt->state.finger;
@@ -73,6 +86,10 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt)
73 const struct FingerState *prev[DIM_FINGER]; 86 const struct FingerState *prev[DIM_FINGER];
74 const struct FingerState *f = mt->state.finger; 87 const struct FingerState *f = mt->state.finger;
75 int same_fingers, i, x = 0, y = 0; 88 int same_fingers, i, x = 0, y = 0;
89 int dx, dy, xcut, ycut, xmax = 0, ymax = 0;
90
91 mt->mem.moving = 0;
92 mt->mem.nmove = 0;
76 93
77 if (mt->state.nfinger == 0) 94 if (mt->state.nfinger == 0)
78 return; 95 return;
@@ -83,29 +100,47 @@ static void extract_movement(struct Gestures *gs, struct MTouch* mt)
83 same_fingers = same_fingers && prev[i]; 100 same_fingers = same_fingers && prev[i];
84 } 101 }
85 102
86 for (i = 0; i < mt->state.nfinger; i++) {
87 x += f[i].hw.position_x;
88 y += f[i].hw.position_y;
89 }
90 x /= mt->state.nfinger;
91 y /= mt->state.nfinger;
92
93 if (!same_fingers) { 103 if (!same_fingers) {
94 mt->mem.move_time = mt->state.evtime; 104 mt->mem.move_time = mt->state.evtime;
95 if (mt->state.nfinger > mt->prev_state.nfinger) 105 if (mt->state.nfinger > mt->prev_state.nfinger)
96 mt->mem.move_time += FINGER_ATTACK_MS; 106 mt->mem.move_time += FINGER_ATTACK_MS;
97 else 107 else
98 mt->mem.move_time += FINGER_DECAY_MS; 108 mt->mem.move_time += FINGER_DECAY_MS;
99 } else if (mt->state.evtime >= mt->mem.move_time) {
100 gs->dx = x - mt->mem.move_x;
101 gs->dy = y - mt->mem.move_y;
102 } else { 109 } else {
110 for (i = 0; i < mt->state.nfinger; i++) {
111 if (!GETBIT(mt->mem.pointing, i))
112 continue;
113 dx = dxval(&f[i], prev[i]);
114 dy = dyval(&f[i], prev[i]);
115 mt->mem.dx[i] += dx;
116 mt->mem.dy[i] += dy;
117 xmax = maxval(xmax, abs(mt->mem.dx[i]));
118 ymax = maxval(ymax, abs(mt->mem.dy[i]));
119 }
120 xcut = DELTA_CUT(xmax);
121 ycut = DELTA_CUT(ymax);
122 for (i = 0; i < mt->state.nfinger; i++) {
123 if (abs(mt->mem.dx[i]) > xcut ||
124 abs(mt->mem.dy[i]) > ycut) {
125 SETBIT(mt->mem.moving, i);
126 mt->mem.nmove++;
127 }
128 }
129
103 /* accumulate all movement during delay */ 130 /* accumulate all movement during delay */
104 return; 131 if (mt->mem.nmove && mt->state.evtime >= mt->mem.move_time) {
132 for (i = 0; i < mt->state.nfinger; i++) {
133 if (GETBIT(mt->mem.moving, i)) {
134 gs->dx += mt->mem.dx[i];
135 gs->dy += mt->mem.dy[i];
136 }
137 }
138 gs->dx /= mt->mem.nmove;
139 gs->dy /= mt->mem.nmove;
140 memset(mt->mem.dx, 0, sizeof(mt->mem.dx));
141 memset(mt->mem.dy, 0, sizeof(mt->mem.dy));
142 }
105 } 143 }
106
107 mt->mem.move_x = x;
108 mt->mem.move_y = y;
109} 144}
110 145
111static void extract_buttons(struct Gestures *gs, struct MTouch* mt) 146static void extract_buttons(struct Gestures *gs, struct MTouch* mt)
@@ -127,15 +162,15 @@ static void extract_buttons(struct Gestures *gs, struct MTouch* mt)
127static void extract_type(struct Gestures *gs, struct MTouch* mt) 162static void extract_type(struct Gestures *gs, struct MTouch* mt)
128{ 163{
129 if (gs->dx || gs->dy) { 164 if (gs->dx || gs->dy) {
130 if (mt->state.nfinger == 1) 165 if (mt->mem.npoint == 1)
131 SETBIT(gs->type, GS_MOVE); 166 SETBIT(gs->type, GS_MOVE);
132 if (mt->state.nfinger == 2) { 167 if (mt->mem.npoint == 2) {
133 if (gs->dx) 168 if (gs->dx)
134 SETBIT(gs->type, GS_HSCROLL); 169 SETBIT(gs->type, GS_HSCROLL);
135 if (gs->dy) 170 if (gs->dy)
136 SETBIT(gs->type, GS_VSCROLL); 171 SETBIT(gs->type, GS_VSCROLL);
137 } 172 }
138 if (mt->state.nfinger == 3) { 173 if (mt->mem.npoint == 3) {
139 if (gs->dx) 174 if (gs->dx)
140 SETBIT(gs->type, GS_HSWIPE); 175 SETBIT(gs->type, GS_HSWIPE);
141 if (gs->dy) 176 if (gs->dy)