diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2010-08-26 16:29:01 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2010-08-26 16:29:01 +0200 |
| commit | 241c5ec03f649dedc617686cd3163f131c2b4ce9 (patch) | |
| tree | b751f3909712d85933297204ec655fc986265776 /src | |
| parent | 3cd78ffe61b4a5d6430b6453a8e3aa8247b70f6e (diff) | |
Introduce tapping from any finger configuration
The current code only emits taps from zero fingers to N fingers.
This patch introduces tapping from any prior finger configuration.
A tap is defined as an increased number of fingers followed by a
decrease within the tap timeout. A tap is reported as the maximum
number of fingers present during the tap sequence.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src')
| -rw-r--r-- | src/gestures-tapping.c | 82 | ||||
| -rw-r--r-- | src/grail-gestures.h | 2 |
2 files changed, 34 insertions, 50 deletions
diff --git a/src/gestures-tapping.c b/src/gestures-tapping.c index 371dbde..fe7b7fe 100644 --- a/src/gestures-tapping.c +++ b/src/gestures-tapping.c | |||
| @@ -23,10 +23,6 @@ | |||
| 23 | #include "grail-recognizer.h" | 23 | #include "grail-recognizer.h" |
| 24 | #include <math.h> | 24 | #include <math.h> |
| 25 | 25 | ||
| 26 | static const int TAP_BEGIN = 0; | ||
| 27 | static const int TAP_END = 1; | ||
| 28 | static const int TAP_CANCEL = 2; | ||
| 29 | |||
| 30 | static const int TAP_MIN_GAP_MS = 25; | 26 | static const int TAP_MIN_GAP_MS = 25; |
| 31 | 27 | ||
| 32 | static const int fm_mask = 0x03; | 28 | static const int fm_mask = 0x03; |
| @@ -48,61 +44,49 @@ int gru_tapping(struct grail *ge, | |||
| 48 | struct gesture_recognizer *gru = ge->gru; | 44 | struct gesture_recognizer *gru = ge->gru; |
| 49 | struct tapping_model *state = &gru->tapping; | 45 | struct tapping_model *state = &gru->tapping; |
| 50 | struct move_model *move = &gru->move; | 46 | struct move_model *move = &gru->move; |
| 51 | if (move->ntouch) { | 47 | if (move->ntouch > state->ntouch) { |
| 52 | if (state->status == TAP_CANCEL) | 48 | if (state->active) { |
| 53 | return 0; | 49 | gin_gid_discard(ge, state->gid); |
| 54 | state->status = TAP_BEGIN; | 50 | state->active = 0; |
| 55 | if (!state->ntouch) | ||
| 56 | state->start = move->time; | ||
| 57 | if (move->ntouch >= state->ntouch) { | ||
| 58 | set_props(ge->gin, state, move, frame); | ||
| 59 | } | ||
| 60 | if (move->ntouch > state->ntouch) { | ||
| 61 | state->ntouch = move->ntouch; | ||
| 62 | if (state->active) { | ||
| 63 | gin_gid_discard(ge, state->gid); | ||
| 64 | state->active = 0; | ||
| 65 | } | ||
| 66 | } | 51 | } |
| 67 | if (!state->active) { | 52 | state->start = move->time; |
| 53 | state->ntouch = move->ntouch; | ||
| 54 | set_props(ge->gin, state, move, frame); | ||
| 55 | if (state->ntouch <= 5) { | ||
| 68 | int type = GRAIL_TYPE_TAP1 + state->ntouch - 1; | 56 | int type = GRAIL_TYPE_TAP1 + state->ntouch - 1; |
| 69 | state->gid = gin_gid_begin(ge, type, PRIO_TAP, frame); | 57 | state->gid = gin_gid_begin(ge, type, PRIO_TAP, frame); |
| 70 | state->active = 1; | 58 | state->active = 1; |
| 71 | } | 59 | } |
| 72 | } else if (state->status == TAP_BEGIN && state->ntouch) { | ||
| 73 | state->status = TAP_END; | ||
| 74 | } else { | ||
| 75 | state->status = TAP_BEGIN; | ||
| 76 | state->ntouch = 0; | ||
| 77 | return 0; | 60 | return 0; |
| 78 | } | 61 | } |
| 79 | if (state->ntouch < 1 || state->ntouch > 5) | 62 | if (!state->active) { |
| 80 | state->status = TAP_CANCEL; | 63 | state->ntouch = move->ntouch; |
| 81 | if (move->time - state->start > move->fm[FM_X].bar_ms) | 64 | return 0; |
| 82 | state->status = TAP_CANCEL; | 65 | } |
| 83 | if (state->status == TAP_END && | 66 | if (move->ntouch < state->ntouch) { |
| 84 | move->time - state->start < TAP_MIN_GAP_MS) | 67 | int x = state->prop[GRAIL_PROP_TAP_X]; |
| 85 | state->status = TAP_CANCEL; | 68 | int y = state->prop[GRAIL_PROP_TAP_Y]; |
| 86 | if (move->active & fm_mask) | 69 | int t = move->time - state->start; |
| 87 | state->status = TAP_CANCEL; | 70 | if (t < TAP_MIN_GAP_MS) { |
| 88 | if (state->status == TAP_CANCEL) { | ||
| 89 | if (state->active) { | ||
| 90 | gin_gid_discard(ge, state->gid); | 71 | gin_gid_discard(ge, state->gid); |
| 72 | state->ntouch = move->ntouch; | ||
| 91 | state->active = 0; | 73 | state->active = 0; |
| 74 | return 0; | ||
| 92 | } | 75 | } |
| 93 | state->ntouch = 0; | 76 | state->prop[GRAIL_PROP_TAP_DT] = t; |
| 94 | return 0; | 77 | gin_gid_event(ge, state->gid, x, y, state->ntouch, |
| 78 | state->prop, state->nprop, 1); | ||
| 79 | state->ntouch = move->ntouch; | ||
| 80 | state->active = 0; | ||
| 81 | return 1; | ||
| 95 | } | 82 | } |
| 96 | if (state->status != TAP_END || | 83 | if (!move->ntouch) |
| 97 | move->time - state->start < TAP_MIN_GAP_MS) | ||
| 98 | return 0; | 84 | return 0; |
| 99 | state->prop[GRAIL_PROP_TAP_DT] = move->time - state->start; | 85 | set_props(ge->gin, state, move, frame); |
| 100 | gin_gid_event(ge, state->gid, | 86 | if ((move->active & fm_mask) || |
| 101 | state->prop[GRAIL_PROP_TAP_X], | 87 | move->time - state->start > move->fm[FM_X].bar_ms) { |
| 102 | state->prop[GRAIL_PROP_TAP_Y], state->ntouch, | 88 | gin_gid_discard(ge, state->gid); |
| 103 | state->prop, state->nprop, 1); | 89 | state->active = 0; |
| 104 | state->status = TAP_BEGIN; | 90 | } |
| 105 | state->ntouch = 0; | 91 | return 0; |
| 106 | state->active = 0; | ||
| 107 | return 1; | ||
| 108 | } | 92 | } |
diff --git a/src/grail-gestures.h b/src/grail-gestures.h index e716757..5a242d9 100644 --- a/src/grail-gestures.h +++ b/src/grail-gestures.h | |||
| @@ -98,7 +98,7 @@ int gru_winrotate(struct grail *ge, | |||
| 98 | 98 | ||
| 99 | struct tapping_model { | 99 | struct tapping_model { |
| 100 | grail_time_t start; | 100 | grail_time_t start; |
| 101 | int status, ntouch; | 101 | int ntouch; |
| 102 | int active, gid; | 102 | int active, gid; |
| 103 | int nprop; | 103 | int nprop; |
| 104 | grail_prop_t prop[DIM_GRAIL_PROP]; | 104 | grail_prop_t prop[DIM_GRAIL_PROP]; |
