summaryrefslogtreecommitdiff
path: root/src/gestures.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gestures.c')
-rw-r--r--src/gestures.c174
1 files changed, 43 insertions, 131 deletions
diff --git a/src/gestures.c b/src/gestures.c
index 9426226..f5244aa 100644
--- a/src/gestures.c
+++ b/src/gestures.c
@@ -25,123 +25,14 @@
25 25
26#include "gestures.h" 26#include "gestures.h"
27 27
28#define DELTA_CUT(x) (0.2 * (x)) 28/**
29 29 * extract_buttons
30/* timer for cursor stability on finger touch/release */ 30 *
31static const int FINGER_ATTACK_MS = 70; 31 * Set the button gesture.
32static const int FINGER_DECAY_MS = 120; 32 *
33 33 * Reset memory after use.
34inline int dxval(const struct MTFinger *a, const struct MTFinger *b) 34 *
35{ 35 */
36 return a->hw.position_x - b->hw.position_x;
37}
38inline int dyval(const struct MTFinger *a, const struct MTFinger *b)
39{
40 return a->hw.position_y - b->hw.position_y;
41}
42
43static void extract_finger_configuration(struct Gestures *gs, struct MTouch* mt)
44{
45 const struct MTFinger *f = mt->state.finger;
46 int i, same = mt->state.nfinger == mt->prev_state.nfinger;
47 for (i = 0; i < mt->state.nfinger; i++)
48 same = same && find_finger(&mt->prev_state, f[i].id);
49 gs->same_fingers = same;
50}
51
52static void extract_pointers(struct Gestures *gs, struct MTouch* mt)
53{
54 const struct MTFinger *f = mt->state.finger;
55 int i;
56
57 if (mt->state.nfinger < 2) {
58 mt->mem.pointing = mt->state.nfinger;
59 mt->mem.ybar = mt->caps.abs_position_y.maximum;
60 return;
61 }
62
63 if (gs->same_fingers) {
64 for (i = 0; i < mt->state.nfinger; i++) {
65 if (GETBIT(mt->mem.pointing, i))
66 continue;
67 if (f[i].hw.position_y <= mt->mem.ybar) {
68 mt->mem.pointing = BITONES(mt->state.nfinger);
69 return;
70 }
71 }
72 return;
73 }
74
75 mt->mem.pointing = 0;
76 mt->mem.ybar = mt->caps.yclick;
77 for (i = 0; i < mt->state.nfinger; i++) {
78 if (f[i].hw.position_y > mt->caps.yclick)
79 continue;
80 if (!mt->mem.pointing || f[i].hw.position_y > mt->mem.ybar)
81 mt->mem.ybar = f[i].hw.position_y;
82 SETBIT(mt->mem.pointing, i);
83 }
84
85}
86
87static void extract_movement(struct Gestures *gs, struct MTouch* mt)
88{
89 const struct MTFinger *prev, *f = mt->state.finger;
90 int i, x = 0, y = 0;
91 int dx, dy, xcut, ycut, xmax = 0, ymax = 0;
92
93 mt->mem.moving = 0;
94
95 if (mt->state.nfinger == 0)
96 return;
97
98 if (!gs->same_fingers) {
99 mt->mem.move_time = mt->state.evtime;
100 if (mt->state.nfinger > mt->prev_state.nfinger)
101 mt->mem.move_time += FINGER_ATTACK_MS;
102 else
103 mt->mem.move_time += FINGER_DECAY_MS;
104 memset(mt->mem.dx, 0, sizeof(mt->mem.dx));
105 memset(mt->mem.dy, 0, sizeof(mt->mem.dy));
106 } else {
107 for (i = 0; i < mt->state.nfinger; i++) {
108 if (!GETBIT(mt->mem.pointing, i))
109 continue;
110 prev = find_finger(&mt->prev_state, f[i].id);
111 dx = dxval(&f[i], prev);
112 dy = dyval(&f[i], prev);
113 mt->mem.dx[i] += dx;
114 mt->mem.dy[i] += dy;
115 xmax = maxval(xmax, abs(mt->mem.dx[i]));
116 ymax = maxval(ymax, abs(mt->mem.dy[i]));
117 }
118 xcut = DELTA_CUT(xmax);
119 ycut = DELTA_CUT(ymax);
120 for (i = 0; i < mt->state.nfinger; i++) {
121 if (!GETBIT(mt->mem.pointing, i))
122 continue;
123 if (abs(mt->mem.dx[i]) > xcut ||
124 abs(mt->mem.dy[i]) > ycut)
125 SETBIT(mt->mem.moving, i);
126 }
127
128 /* accumulate all movement during delay */
129 if (mt->mem.moving && mt->state.evtime >= mt->mem.move_time) {
130 int nmove = bitcount(mt->mem.moving);
131 for (i = 0; i < mt->state.nfinger; i++) {
132 if (GETBIT(mt->mem.moving, i)) {
133 gs->dx += mt->mem.dx[i];
134 gs->dy += mt->mem.dy[i];
135 }
136 }
137 gs->dx /= nmove;
138 gs->dy /= nmove;
139 memset(mt->mem.dx, 0, sizeof(mt->mem.dx));
140 memset(mt->mem.dy, 0, sizeof(mt->mem.dy));
141 }
142 }
143}
144
145static void extract_buttons(struct Gestures *gs, struct MTouch* mt) 36static void extract_buttons(struct Gestures *gs, struct MTouch* mt)
146{ 37{
147 unsigned btdata = mt->state.button & BITONES(DIM_BUTTON); 38 unsigned btdata = mt->state.button & BITONES(DIM_BUTTON);
@@ -157,15 +48,35 @@ static void extract_buttons(struct Gestures *gs, struct MTouch* mt)
157 gs->btdata = btdata; 48 gs->btdata = btdata;
158 mt->mem.btdata = btdata; 49 mt->mem.btdata = btdata;
159 } 50 }
51 if (gs->btmask)
52 SETBIT(gs->type, GS_BUTTON);
160} 53}
161 54
162/******************************************************/ 55/**
163 56 * extract_movement
164static void extract_type(struct Gestures *gs, struct MTouch* mt) 57 *
58 * Set the movement gesture.
59 *
60 * Reset memory after use.
61 *
62 */
63static void extract_movement(struct Gestures *gs, struct MTouch* mt)
165{ 64{
166 int npoint = bitcount(mt->mem.pointing); 65 int npoint = bitcount(mt->mem.pointing);
167 if (gs->btmask) 66 int nmove = bitcount(mt->mem.moving);
168 SETBIT(gs->type, GS_BUTTON); 67 int i;
68 if (nmove && mt->state.evtime >= mt->mem.move_time) {
69 for (i = 0; i < mt->state.nfinger; i++) {
70 if (GETBIT(mt->mem.moving, i)) {
71 gs->dx += mt->mem.dx[i];
72 gs->dy += mt->mem.dy[i];
73 }
74 }
75 gs->dx /= nmove;
76 gs->dy /= nmove;
77 memset(mt->mem.dx, 0, sizeof(mt->mem.dx));
78 memset(mt->mem.dy, 0, sizeof(mt->mem.dy));
79 }
169 if (gs->dx || gs->dy) { 80 if (gs->dx || gs->dy) {
170 if (npoint == 1) 81 if (npoint == 1)
171 SETBIT(gs->type, GS_MOVE); 82 SETBIT(gs->type, GS_MOVE);
@@ -184,19 +95,20 @@ static void extract_type(struct Gestures *gs, struct MTouch* mt)
184 } 95 }
185} 96}
186 97
187/******************************************************/ 98/**
188 99 * extract_gestures
100 *
101 * Extract the gestures.
102 *
103 * Reset memory after use.
104 *
105 */
189void extract_gestures(struct Gestures *gs, struct MTouch* mt) 106void extract_gestures(struct Gestures *gs, struct MTouch* mt)
190{ 107{
191 memset(gs, 0, sizeof(struct Gestures)); 108 memset(gs, 0, sizeof(struct Gestures));
192 extract_finger_configuration(gs, mt); 109 gs->same_fingers = mt->mem.same;
193 extract_pointers(gs, mt);
194 extract_movement(gs, mt);
195 extract_buttons(gs, mt); 110 extract_buttons(gs, mt);
196 extract_type(gs, mt); 111 extract_movement(gs, mt);
197 mt->prev_state = mt->state; 112 mt->prev_state = mt->state;
198#if 0
199 output_memory(&mt->mem);
200#endif
201} 113}
202 114