From 477f338c8de5e20d82e7c861bba742bc4c203a42 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Wed, 11 Aug 2010 15:30:42 +0100 Subject: Add environment and meta gestures With meta gestures, the gesture starts given a certain number of fingers, but can then continue even if the number of fingers change. By configuration, such gestures live on a different priority plane from normal gestures. To match window manager specs, this patch adds the environment and meta planes, and add drag, pinch and rotate gestures initiated with three and four fingers, respectively. Signed-off-by: Henrik Rydberg --- src/gestures-drag.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/gestures-pinch.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/gestures-rotate.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/grail-gestures.h | 20 +++++++++++++++++--- src/grail-recognizer.c | 3 +++ src/grail-recognizer.h | 3 +++ 6 files changed, 146 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gestures-drag.c b/src/gestures-drag.c index b894bda..253bc9d 100644 --- a/src/gestures-drag.c +++ b/src/gestures-drag.c @@ -82,3 +82,44 @@ int gru_drag(struct grail *ge, return 1; } +int gru_windrag(struct grail *ge, + const struct touch_frame *frame) +{ + struct gesture_recognizer *gru = ge->gru; + struct combo_model *state = &gru->windrag; + struct move_model *move = &gru->move; + int mask = state->active ? (move->active & fm_mask) : fm_mask; + if (!move->multi && !move->single) { + if (state->active && out_of_bounds(state, move)) { + gru_end(ge, state->gid, move, + state->prop, state->nprop); + state->active = 0; + } + return 0; + } + if (!(move->tickle & mask)) + return 0; + if (!state->active) { + if (move->ntouch == 4) { + state->gid = gin_gid_begin(ge, GRAIL_TYPE_MDRAG, + PRIO_META, frame); + state->mintouch = 1; + state->maxtouch = 4; + state->active = 1; + } else if (move->ntouch == 3) { + state->gid = gin_gid_begin(ge, GRAIL_TYPE_EDRAG, + PRIO_ENV, frame); + state->mintouch = 1; + state->maxtouch = 3; + state->active = 1; + } else { + return 0; + } + } + if (!move->single && !(move->active & fm_mask)) + return 0; + set_props(state, move); + gru_event(ge, state->gid, move, state->prop, state->nprop); + return 1; +} + diff --git a/src/gestures-pinch.c b/src/gestures-pinch.c index 0ddffa4..91e6504 100644 --- a/src/gestures-pinch.c +++ b/src/gestures-pinch.c @@ -100,3 +100,44 @@ int gru_pinch(struct grail *ge, gru_event(ge, state->gid, move, state->prop, state->nprop); return 1; } + +int gru_winpinch(struct grail *ge, + const struct touch_frame *frame) +{ + struct gesture_recognizer *gru = ge->gru; + struct combo_model *state = &gru->winpinch; + struct move_model *move = &gru->move; + int mask = state->active ? (move->active & fm_mask) : fm_mask; + if (!move->multi) { + if (state->active && out_of_bounds(state, move)) { + gru_end(ge, state->gid, move, + state->prop, state->nprop); + state->active = 0; + } + return 0; + } + if (!(move->tickle & mask)) + return 0; + if (!state->active) { + if (move->ntouch == 4) { + state->gid = gin_gid_begin(ge, GRAIL_TYPE_MPINCH, + PRIO_META, frame); + state->mintouch = 2; + state->maxtouch = 4; + state->active = 1; + } else if (move->ntouch == 3) { + state->gid = gin_gid_begin(ge, GRAIL_TYPE_EPINCH, + PRIO_ENV, frame); + state->mintouch = 2; + state->maxtouch = 3; + state->active = 1; + } else { + return 0; + } + } + if (!(move->active & fm_mask)) + return 0; + set_props(state, move, frame); + gru_event(ge, state->gid, move, state->prop, state->nprop); + return 1; +} diff --git a/src/gestures-rotate.c b/src/gestures-rotate.c index 52b5004..5763294 100644 --- a/src/gestures-rotate.c +++ b/src/gestures-rotate.c @@ -73,3 +73,44 @@ int gru_rotate(struct grail *ge, gru_event(ge, state->gid, move, state->prop, state->nprop); return 1; } + +int gru_winrotate(struct grail *ge, + const struct touch_frame *frame) +{ + struct gesture_recognizer *gru = ge->gru; + struct combo_model *state = &gru->winrotate; + struct move_model *move = &gru->move; + int mask = state->active ? (move->active & fm_mask) : fm_mask; + if (!move->multi) { + if (state->active && out_of_bounds(state, move)) { + gru_end(ge, state->gid, move, + state->prop, state->nprop); + state->active = 0; + } + return 0; + } + if (!(move->tickle & mask)) + return 0; + if (!state->active) { + if (move->ntouch == 4) { + state->gid = gin_gid_begin(ge, GRAIL_TYPE_MROTATE, + PRIO_META, frame); + state->mintouch = 2; + state->maxtouch = 4; + state->active = 1; + } else if (move->ntouch == 3) { + state->gid = gin_gid_begin(ge, GRAIL_TYPE_EROTATE, + PRIO_ENV, frame); + state->mintouch = 2; + state->maxtouch = 3; + state->active = 1; + } else { + return 0; + } + } + if (!(move->active & fm_mask)) + return 0; + set_props(state, move); + gru_event(ge, state->gid, move, state->prop, state->nprop); + return 1; +} diff --git a/src/grail-gestures.h b/src/grail-gestures.h index 888a50b..e716757 100644 --- a/src/grail-gestures.h +++ b/src/grail-gestures.h @@ -27,7 +27,9 @@ #define PRIO_POINTER 1 #define PRIO_GESTURE 2 -#define PRIO_TAP 3 +#define PRIO_ENV 3 +#define PRIO_META 4 +#define PRIO_TAP 5 #define DIM_FM 4 @@ -69,6 +71,7 @@ void gru_end(struct grail *ge, int gid, struct combo_model { int active, gid; + int mintouch, maxtouch; int nprop; grail_prop_t prop[DIM_GRAIL_PROP]; }; @@ -79,8 +82,19 @@ int gru_pinch(struct grail *ge, const struct touch_frame *frame); int gru_rotate(struct grail *ge, const struct touch_frame *frame); -int gru_combo(struct grail *ge, - const struct touch_frame *frame); + +static inline int out_of_bounds(const struct combo_model *s, + const struct move_model *m) +{ + return m->ntouch < s->mintouch || m->ntouch > s->maxtouch; +} + +int gru_windrag(struct grail *ge, + const struct touch_frame *frame); +int gru_winpinch(struct grail *ge, + const struct touch_frame *frame); +int gru_winrotate(struct grail *ge, + const struct touch_frame *frame); struct tapping_model { grail_time_t start; diff --git a/src/grail-recognizer.c b/src/grail-recognizer.c index fffbf6e..932f28a 100644 --- a/src/grail-recognizer.c +++ b/src/grail-recognizer.c @@ -50,6 +50,9 @@ void gru_recognize(struct grail *ge, const struct touch_frame *frame) gru_drag(ge, frame); gru_pinch(ge, frame); gru_rotate(ge, frame); + gru_windrag(ge, frame); + gru_winpinch(ge, frame); + gru_winrotate(ge, frame); gru_tapping(ge, frame); ge->gru->frame = *frame; } diff --git a/src/grail-recognizer.h b/src/grail-recognizer.h index b39eac3..1a9edd1 100644 --- a/src/grail-recognizer.h +++ b/src/grail-recognizer.h @@ -31,6 +31,9 @@ struct gesture_recognizer { struct combo_model drag; struct combo_model pinch; struct combo_model rotate; + struct combo_model windrag; + struct combo_model winpinch; + struct combo_model winrotate; struct tapping_model tapping; }; -- cgit v1.2.3