summaryrefslogtreecommitdiff
path: root/src/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory.c')
-rw-r--r--src/memory.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/memory.c b/src/memory.c
index 0e2edba..a09eadb 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -21,16 +21,175 @@
21 21
22#include "memory.h" 22#include "memory.h"
23 23
24/* fraction of max movement threshold */
25#define DELTA_CUT(x) (0.2 * (x))
26
27/* timer for cursor stability on finger touch/release */
28static const int FINGER_ATTACK_MS = 70;
29static const int FINGER_DECAY_MS = 120;
30
31static inline int dxval(const struct MTFinger *a, const struct MTFinger *b)
32{
33 return a->hw.position_x - b->hw.position_x;
34}
35static inline int dyval(const struct MTFinger *a, const struct MTFinger *b)
36{
37 return a->hw.position_y - b->hw.position_y;
38}
39
24void init_memory(struct Memory *mem) 40void init_memory(struct Memory *mem)
25{ 41{
26 memset(mem, 0, sizeof(struct Memory)); 42 memset(mem, 0, sizeof(struct Memory));
27} 43}
28 44
45/**
46 * update_configuration
47 *
48 * Update the same, fingers, added memory variables.
49 *
50 * Precondition: none
51 *
52 * Postcondition: same, fingers, added are set
53 *
54 */
55static void update_configuration(struct Memory *m,
56 const struct MTState *prev_state,
57 const struct MTState *state)
58{
59 const struct MTFinger *f = state->finger;
60 int i;
61 m->same = state->nfinger == prev_state->nfinger;
62 for (i = 0; i < state->nfinger; i++)
63 m->same = m->same && find_finger(prev_state, f[i].id);
64}
65
66/**
67 * update_pointers
68 *
69 * Update the pointing and ybar memory variables.
70 *
71 * Precondition: fingers, added are set
72 *
73 * Postcondition: pointing, ybar are set
74 *
75 */
76static void update_pointers(struct Memory *m,
77 const struct MTState *state,
78 const struct Capabilities *caps)
79{
80 const struct MTFinger *f = state->finger;
81 int i;
82
83 if (state->nfinger < 2) {
84 m->pointing = state->nfinger;
85 m->ybar = caps->abs_position_y.maximum;
86 return;
87 }
88
89 if (m->same) {
90 for (i = 0; i < state->nfinger; i++) {
91 if (GETBIT(m->pointing, i))
92 continue;
93 if (f[i].hw.position_y <= m->ybar) {
94 m->pointing = BITONES(state->nfinger);
95 return;
96 }
97 }
98 return;
99 }
100
101 m->pointing = 0;
102 m->ybar = caps->yclick;
103 for (i = 0; i < state->nfinger; i++) {
104 if (f[i].hw.position_y > caps->yclick)
105 continue;
106 if (!m->pointing || f[i].hw.position_y > m->ybar)
107 m->ybar = f[i].hw.position_y;
108 SETBIT(m->pointing, i);
109 }
110
111}
112
113/**
114 * update_movement
115 *
116 * Update the pending, moving, mvhold, mvforget, dx and dy memory variables.
117 *
118 * When moving is nonzero, gestures can be extracted from the dx and dy
119 * variables. These variables should be cleared after use.
120 *
121 * Precondition: fingers, added, pointing are set
122 *
123 * Postcondition: pending, moving, mvhold, mvforget, dx, dy are set
124 *
125 */
126static void update_movement(struct Memory *m,
127 const struct MTState *prev_state,
128 const struct MTState *state,
129 const struct Capabilities *caps)
130{
131 const struct MTFinger *prev, *f = state->finger;
132 int i, x = 0, y = 0;
133 int dx, dy, xcut, ycut, xmax = 0, ymax = 0;
134
135 m->pending = 0;
136 m->moving = 0;
137
138 if (state->nfinger == 0)
139 return;
140
141 if (!m->same) {
142 m->move_time = state->evtime;
143 if (state->nfinger > prev_state->nfinger)
144 m->move_time += FINGER_ATTACK_MS;
145 else
146 m->move_time += FINGER_DECAY_MS;
147 memset(m->dx, 0, sizeof(m->dx));
148 memset(m->dy, 0, sizeof(m->dy));
149 } else {
150 for (i = 0; i < state->nfinger; i++) {
151 if (!GETBIT(m->pointing, i))
152 continue;
153 prev = find_finger(prev_state, f[i].id);
154 dx = dxval(&f[i], prev);
155 dy = dyval(&f[i], prev);
156 m->dx[i] += dx;
157 m->dy[i] += dy;
158 xmax = maxval(xmax, abs(m->dx[i]));
159 ymax = maxval(ymax, abs(m->dy[i]));
160 }
161 xcut = DELTA_CUT(xmax);
162 ycut = DELTA_CUT(ymax);
163 for (i = 0; i < state->nfinger; i++) {
164 if (!GETBIT(m->pointing, i))
165 continue;
166 if (abs(m->dx[i]) > xcut ||
167 abs(m->dy[i]) > ycut)
168 SETBIT(m->pending, i);
169 }
170
171 /* accumulate all movement during delay */
172 if (m->pending && state->evtime >= m->move_time)
173 m->moving = m->pending;
174 }
175}
176
177void refresh_memory(struct Memory *m,
178 const struct MTState *prev_state,
179 const struct MTState *state,
180 const struct Capabilities *caps)
181{
182 update_configuration(m, prev_state, state);
183 update_pointers(m, state, caps);
184 update_movement(m, prev_state, state, caps);
185}
186
29void output_memory(const struct Memory *m) 187void output_memory(const struct Memory *m)
30{ 188{
31 int i; 189 int i;
32 xf86Msg(X_INFO, "btdata: %04x\n", m->btdata); 190 xf86Msg(X_INFO, "btdata: %04x\n", m->btdata);
33 xf86Msg(X_INFO, "pointing: %04x\n", m->pointing); 191 xf86Msg(X_INFO, "pointing: %04x\n", m->pointing);
192 xf86Msg(X_INFO, "pending: %04x\n", m->pending);
34 xf86Msg(X_INFO, "moving: %04x\n", m->moving); 193 xf86Msg(X_INFO, "moving: %04x\n", m->moving);
35 xf86Msg(X_INFO, "ybar: %d\n", m->ybar); 194 xf86Msg(X_INFO, "ybar: %d\n", m->ybar);
36 xf86Msg(X_INFO, "move_time: %lld\n", m->move_time); 195 xf86Msg(X_INFO, "move_time: %lld\n", m->move_time);