aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-05-14 01:29:05 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-05-14 01:41:39 +0200
commitbfd266660d69e13263e3895fb059040b65255a72 (patch)
tree0ee0737f58307e345f9db2ebdd3de87e01febea6
parent8ced3667a30e00bd2368d4b5417f1f07cc86d290 (diff)
downloadxorg-input-kobomultitouch-bfd266660d69e13263e3895fb059040b65255a72.tar.gz
xorg-input-kobomultitouch-bfd266660d69e13263e3895fb059040b65255a72.tar.bz2
xorg-input-kobomultitouch-bfd266660d69e13263e3895fb059040b65255a72.zip
janitor: Split gesture code into memory refresh and parse
Split the gesture code into a lexical part, which updates the filtered motion state, and a parsing part, which translates the motion state to gestures. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
-rw-r--r--src/gestures.c174
-rw-r--r--src/memory.c159
-rw-r--r--src/memory.h24
-rw-r--r--src/mtouch.c4
4 files changed, 226 insertions, 135 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 @@
#include "gestures.h"
-#define DELTA_CUT(x) (0.2 * (x))
-
-/* timer for cursor stability on finger touch/release */
-static const int FINGER_ATTACK_MS = 70;
-static const int FINGER_DECAY_MS = 120;
-
-inline int dxval(const struct MTFinger *a, const struct MTFinger *b)
-{
- return a->hw.position_x - b->hw.position_x;
-}
-inline int dyval(const struct MTFinger *a, const struct MTFinger *b)
-{
- return a->hw.position_y - b->hw.position_y;
-}
-
-static void extract_finger_configuration(struct Gestures *gs, struct MTouch* mt)
-{
- const struct MTFinger *f = mt->state.finger;
- int i, same = mt->state.nfinger == mt->prev_state.nfinger;
- for (i = 0; i < mt->state.nfinger; i++)
- same = same && find_finger(&mt->prev_state, f[i].id);
- gs->same_fingers = same;
-}
-
-static void extract_pointers(struct Gestures *gs, struct MTouch* mt)
-{
- const struct MTFinger *f = mt->state.finger;
- int i;
-
- if (mt->state.nfinger < 2) {
- mt->mem.pointing = mt->state.nfinger;
- mt->mem.ybar = mt->caps.abs_position_y.maximum;
- return;
- }
-
- if (gs->same_fingers) {
- for (i = 0; i < mt->state.nfinger; i++) {
- if (GETBIT(mt->mem.pointing, i))
- continue;
- if (f[i].hw.position_y <= mt->mem.ybar) {
- mt->mem.pointing = BITONES(mt->state.nfinger);
- return;
- }
- }
- return;
- }
-
- mt->mem.pointing = 0;
- mt->mem.ybar = mt->caps.yclick;
- for (i = 0; i < mt->state.nfinger; i++) {
- if (f[i].hw.position_y > mt->caps.yclick)
- continue;
- if (!mt->mem.pointing || f[i].hw.position_y > mt->mem.ybar)
- mt->mem.ybar = f[i].hw.position_y;
- SETBIT(mt->mem.pointing, i);
- }
-
-}
-
-static void extract_movement(struct Gestures *gs, struct MTouch* mt)
-{
- const struct MTFinger *prev, *f = mt->state.finger;
- int i, x = 0, y = 0;
- int dx, dy, xcut, ycut, xmax = 0, ymax = 0;
-
- mt->mem.moving = 0;
-
- if (mt->state.nfinger == 0)
- return;
-
- if (!gs->same_fingers) {
- mt->mem.move_time = mt->state.evtime;
- if (mt->state.nfinger > mt->prev_state.nfinger)
- mt->mem.move_time += FINGER_ATTACK_MS;
- else
- mt->mem.move_time += FINGER_DECAY_MS;
- memset(mt->mem.dx, 0, sizeof(mt->mem.dx));
- memset(mt->mem.dy, 0, sizeof(mt->mem.dy));
- } else {
- for (i = 0; i < mt->state.nfinger; i++) {
- if (!GETBIT(mt->mem.pointing, i))
- continue;
- prev = find_finger(&mt->prev_state, f[i].id);
- dx = dxval(&f[i], prev);
- dy = dyval(&f[i], prev);
- mt->mem.dx[i] += dx;
- mt->mem.dy[i] += dy;
- xmax = maxval(xmax, abs(mt->mem.dx[i]));
- ymax = maxval(ymax, abs(mt->mem.dy[i]));
- }
- xcut = DELTA_CUT(xmax);
- ycut = DELTA_CUT(ymax);
- for (i = 0; i < mt->state.nfinger; i++) {
- if (!GETBIT(mt->mem.pointing, i))
- continue;
- if (abs(mt->mem.dx[i]) > xcut ||
- abs(mt->mem.dy[i]) > ycut)
- SETBIT(mt->mem.moving, i);
- }
-
- /* accumulate all movement during delay */
- if (mt->mem.moving && mt->state.evtime >= mt->mem.move_time) {
- int nmove = bitcount(mt->mem.moving);
- for (i = 0; i < mt->state.nfinger; i++) {
- if (GETBIT(mt->mem.moving, i)) {
- gs->dx += mt->mem.dx[i];
- gs->dy += mt->mem.dy[i];
- }
- }
- gs->dx /= nmove;
- gs->dy /= nmove;
- memset(mt->mem.dx, 0, sizeof(mt->mem.dx));
- memset(mt->mem.dy, 0, sizeof(mt->mem.dy));
- }
- }
-}
-
+/**
+ * extract_buttons
+ *
+ * Set the button gesture.
+ *
+ * Reset memory after use.
+ *
+ */
static void extract_buttons(struct Gestures *gs, struct MTouch* mt)
{
unsigned btdata = mt->state.button & BITONES(DIM_BUTTON);
@@ -157,15 +48,35 @@ static void extract_buttons(struct Gestures *gs, struct MTouch* mt)
gs->btdata = btdata;
mt->mem.btdata = btdata;
}
+ if (gs->btmask)
+ SETBIT(gs->type, GS_BUTTON);
}
-/******************************************************/
-
-static void extract_type(struct Gestures *gs, struct MTouch* mt)
+/**
+ * extract_movement
+ *
+ * Set the movement gesture.
+ *
+ * Reset memory after use.
+ *
+ */
+static void extract_movement(struct Gestures *gs, struct MTouch* mt)
{
int npoint = bitcount(mt->mem.pointing);
- if (gs->btmask)
- SETBIT(gs->type, GS_BUTTON);
+ int nmove = bitcount(mt->mem.moving);
+ int i;
+ if (nmove && mt->state.evtime >= mt->mem.move_time) {
+ for (i = 0; i < mt->state.nfinger; i++) {
+ if (GETBIT(mt->mem.moving, i)) {
+ gs->dx += mt->mem.dx[i];
+ gs->dy += mt->mem.dy[i];
+ }
+ }
+ gs->dx /= nmove;
+ gs->dy /= nmove;
+ memset(mt->mem.dx, 0, sizeof(mt->mem.dx));
+ memset(mt->mem.dy, 0, sizeof(mt->mem.dy));
+ }
if (gs->dx || gs->dy) {
if (npoint == 1)
SETBIT(gs->type, GS_MOVE);
@@ -184,19 +95,20 @@ static void extract_type(struct Gestures *gs, struct MTouch* mt)
}
}
-/******************************************************/
-
+/**
+ * extract_gestures
+ *
+ * Extract the gestures.
+ *
+ * Reset memory after use.
+ *
+ */
void extract_gestures(struct Gestures *gs, struct MTouch* mt)
{
memset(gs, 0, sizeof(struct Gestures));
- extract_finger_configuration(gs, mt);
- extract_pointers(gs, mt);
- extract_movement(gs, mt);
+ gs->same_fingers = mt->mem.same;
extract_buttons(gs, mt);
- extract_type(gs, mt);
+ extract_movement(gs, mt);
mt->prev_state = mt->state;
-#if 0
- output_memory(&mt->mem);
-#endif
}
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 @@
#include "memory.h"
+/* fraction of max movement threshold */
+#define DELTA_CUT(x) (0.2 * (x))
+
+/* timer for cursor stability on finger touch/release */
+static const int FINGER_ATTACK_MS = 70;
+static const int FINGER_DECAY_MS = 120;
+
+static inline int dxval(const struct MTFinger *a, const struct MTFinger *b)
+{
+ return a->hw.position_x - b->hw.position_x;
+}
+static inline int dyval(const struct MTFinger *a, const struct MTFinger *b)
+{
+ return a->hw.position_y - b->hw.position_y;
+}
+
void init_memory(struct Memory *mem)
{
memset(mem, 0, sizeof(struct Memory));
}
+/**
+ * update_configuration
+ *
+ * Update the same, fingers, added memory variables.
+ *
+ * Precondition: none
+ *
+ * Postcondition: same, fingers, added are set
+ *
+ */
+static void update_configuration(struct Memory *m,
+ const struct MTState *prev_state,
+ const struct MTState *state)
+{
+ const struct MTFinger *f = state->finger;
+ int i;
+ m->same = state->nfinger == prev_state->nfinger;
+ for (i = 0; i < state->nfinger; i++)
+ m->same = m->same && find_finger(prev_state, f[i].id);
+}
+
+/**
+ * update_pointers
+ *
+ * Update the pointing and ybar memory variables.
+ *
+ * Precondition: fingers, added are set
+ *
+ * Postcondition: pointing, ybar are set
+ *
+ */
+static void update_pointers(struct Memory *m,
+ const struct MTState *state,
+ const struct Capabilities *caps)
+{
+ const struct MTFinger *f = state->finger;
+ int i;
+
+ if (state->nfinger < 2) {
+ m->pointing = state->nfinger;
+ m->ybar = caps->abs_position_y.maximum;
+ return;
+ }
+
+ if (m->same) {
+ for (i = 0; i < state->nfinger; i++) {
+ if (GETBIT(m->pointing, i))
+ continue;
+ if (f[i].hw.position_y <= m->ybar) {
+ m->pointing = BITONES(state->nfinger);
+ return;
+ }
+ }
+ return;
+ }
+
+ m->pointing = 0;
+ m->ybar = caps->yclick;
+ for (i = 0; i < state->nfinger; i++) {
+ if (f[i].hw.position_y > caps->yclick)
+ continue;
+ if (!m->pointing || f[i].hw.position_y > m->ybar)
+ m->ybar = f[i].hw.position_y;
+ SETBIT(m->pointing, i);
+ }
+
+}
+
+/**
+ * update_movement
+ *
+ * Update the pending, moving, mvhold, mvforget, dx and dy memory variables.
+ *
+ * When moving is nonzero, gestures can be extracted from the dx and dy
+ * variables. These variables should be cleared after use.
+ *
+ * Precondition: fingers, added, pointing are set
+ *
+ * Postcondition: pending, moving, mvhold, mvforget, dx, dy are set
+ *
+ */
+static void update_movement(struct Memory *m,
+ const struct MTState *prev_state,
+ const struct MTState *state,
+ const struct Capabilities *caps)
+{
+ const struct MTFinger *prev, *f = state->finger;
+ int i, x = 0, y = 0;
+ int dx, dy, xcut, ycut, xmax = 0, ymax = 0;
+
+ m->pending = 0;
+ m->moving = 0;
+
+ if (state->nfinger == 0)
+ return;
+
+ if (!m->same) {
+ m->move_time = state->evtime;
+ if (state->nfinger > prev_state->nfinger)
+ m->move_time += FINGER_ATTACK_MS;
+ else
+ m->move_time += FINGER_DECAY_MS;
+ memset(m->dx, 0, sizeof(m->dx));
+ memset(m->dy, 0, sizeof(m->dy));
+ } else {
+ for (i = 0; i < state->nfinger; i++) {
+ if (!GETBIT(m->pointing, i))
+ continue;
+ prev = find_finger(prev_state, f[i].id);
+ dx = dxval(&f[i], prev);
+ dy = dyval(&f[i], prev);
+ m->dx[i] += dx;
+ m->dy[i] += dy;
+ xmax = maxval(xmax, abs(m->dx[i]));
+ ymax = maxval(ymax, abs(m->dy[i]));
+ }
+ xcut = DELTA_CUT(xmax);
+ ycut = DELTA_CUT(ymax);
+ for (i = 0; i < state->nfinger; i++) {
+ if (!GETBIT(m->pointing, i))
+ continue;
+ if (abs(m->dx[i]) > xcut ||
+ abs(m->dy[i]) > ycut)
+ SETBIT(m->pending, i);
+ }
+
+ /* accumulate all movement during delay */
+ if (m->pending && state->evtime >= m->move_time)
+ m->moving = m->pending;
+ }
+}
+
+void refresh_memory(struct Memory *m,
+ const struct MTState *prev_state,
+ const struct MTState *state,
+ const struct Capabilities *caps)
+{
+ update_configuration(m, prev_state, state);
+ update_pointers(m, state, caps);
+ update_movement(m, prev_state, state, caps);
+}
+
void output_memory(const struct Memory *m)
{
int i;
xf86Msg(X_INFO, "btdata: %04x\n", m->btdata);
xf86Msg(X_INFO, "pointing: %04x\n", m->pointing);
+ xf86Msg(X_INFO, "pending: %04x\n", m->pending);
xf86Msg(X_INFO, "moving: %04x\n", m->moving);
xf86Msg(X_INFO, "ybar: %d\n", m->ybar);
xf86Msg(X_INFO, "move_time: %lld\n", m->move_time);
diff --git a/src/memory.h b/src/memory.h
index 23d2ce6..9810b81 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -24,17 +24,33 @@
#include "mtstate.h"
+/**
+ * struct Memory - parsing state
+ *
+ * @btdata: logical finger state
+ * @same: true if the finger configuration is unchanged
+ * @pointing: bitmask of pointing fingers
+ * @pending: bitmask of tentatively moving fingers
+ * @moving: bitmask of moving fingers
+ * @ybar: vertical position on pad marking the clicking area
+ * @move_time: movement before this point in time is accumulated
+ * @dx: array of accumulated horiontal movement per finger
+ * @dy: array of accumulated vertical movement per finger
+ *
+ */
struct Memory {
- unsigned btdata, pointing, moving;
+ unsigned btdata, same;
+ unsigned pointing, pending, moving;
int ybar;
mstime_t move_time;
int dx[DIM_FINGER], dy[DIM_FINGER];
-
-
-
};
void init_memory(struct Memory *mem);
+void refresh_memory(struct Memory *m,
+ const struct MTState *prev_state,
+ const struct MTState *state,
+ const struct Capabilities *caps);
void output_memory(const struct Memory *m);
#endif
diff --git a/src/mtouch.c b/src/mtouch.c
index 44b4376..ad077b7 100644
--- a/src/mtouch.c
+++ b/src/mtouch.c
@@ -66,4 +66,8 @@ void parse_event(struct MTouch *mt)
#if 0
output_mtstate(&mt->state);
#endif
+ refresh_memory(&mt->mem, &mt->prev_state, &mt->state, &mt->caps);
+#if 0
+ output_memory(&mt->mem);
+#endif
}