From e944cd6a6cc64734642b531dac2b93fff0029fb9 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Wed, 11 Aug 2010 17:54:25 +0100 Subject: add a translation utility to grail By calling the grail_set_bbox(), grail will do translation of api coordinates and matching properties to an external coordinate system, such as screen coordinates. Signed-off-by: Henrik Rydberg --- src/grail-inserter.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) (limited to 'src') diff --git a/src/grail-inserter.c b/src/grail-inserter.c index d982808..8b0296e 100644 --- a/src/grail-inserter.c +++ b/src/grail-inserter.c @@ -24,6 +24,7 @@ #include #include #include +#include static const int MAX_GESTURE_ID = 0xfff; @@ -34,8 +35,99 @@ struct gesture_inserter { grail_mask_t used[DIM_INSTANCE_BYTES]; grail_time_t time; int gestureid; + int transformed; + float scale_x, scale_y, scale_r; + float trans_x, trans_y; }; +static const int grail_main_type[DIM_GRAIL_TYPE] = { + GRAIL_MAIN_DRAG, + GRAIL_MAIN_PINCH, + GRAIL_MAIN_ROTATE, + GRAIL_MAIN_DRAG, + GRAIL_MAIN_PINCH, + GRAIL_MAIN_ROTATE, + GRAIL_MAIN_DRAG, + GRAIL_MAIN_PINCH, + GRAIL_MAIN_ROTATE, + GRAIL_MAIN_DRAG, + GRAIL_MAIN_PINCH, + GRAIL_MAIN_ROTATE, + GRAIL_MAIN_DRAG, + GRAIL_MAIN_PINCH, + GRAIL_MAIN_ROTATE, + GRAIL_MAIN_TAP, + GRAIL_MAIN_TAP, + GRAIL_MAIN_TAP, + GRAIL_MAIN_TAP, + GRAIL_MAIN_TAP, + GRAIL_MAIN_DRAG, + GRAIL_MAIN_PINCH, + GRAIL_MAIN_ROTATE, + GRAIL_MAIN_DRAG, + GRAIL_MAIN_PINCH, + GRAIL_MAIN_ROTATE, +}; + +static void transform_pos(const struct gesture_inserter *gin, + struct grail_coord *pos) +{ + if (gin->transformed) { + pos->x *= gin->scale_x; + pos->x += gin->trans_x; + pos->y *= gin->scale_y; + pos->y += gin->trans_y; + } +} + +static void transform_prop(const struct gesture_inserter *gin, int type, + grail_prop_t *prop, int nprop) +{ + if (!gin->transformed) + return; + switch (grail_main_type[type]) { + case GRAIL_MAIN_DRAG: + prop[GRAIL_PROP_DRAG_DX] *= gin->scale_x; + prop[GRAIL_PROP_DRAG_DY] *= gin->scale_y; + prop[GRAIL_PROP_DRAG_VX] *= gin->scale_x; + prop[GRAIL_PROP_DRAG_VY] *= gin->scale_y; + prop[GRAIL_PROP_DRAG_X] *= gin->scale_x; + prop[GRAIL_PROP_DRAG_X] += gin->trans_x; + prop[GRAIL_PROP_DRAG_Y] *= gin->scale_y; + prop[GRAIL_PROP_DRAG_Y] += gin->trans_y; + break; + case GRAIL_MAIN_PINCH: + prop[GRAIL_PROP_PINCH_DR] *= gin->scale_r; + prop[GRAIL_PROP_PINCH_VR] *= gin->scale_r; + prop[GRAIL_PROP_PINCH_R] *= gin->scale_r; + prop[GRAIL_PROP_PINCH_X1] *= gin->scale_x; + prop[GRAIL_PROP_PINCH_X1] += gin->trans_x; + prop[GRAIL_PROP_PINCH_Y1] *= gin->scale_y; + prop[GRAIL_PROP_PINCH_Y1] += gin->trans_y; + prop[GRAIL_PROP_PINCH_X2] *= gin->scale_x; + prop[GRAIL_PROP_PINCH_X2] += gin->trans_x; + prop[GRAIL_PROP_PINCH_Y2] *= gin->scale_y; + prop[GRAIL_PROP_PINCH_Y2] += gin->trans_y; + break; + case GRAIL_MAIN_ROTATE: + prop[GRAIL_PROP_ROTATE_X1] *= gin->scale_x; + prop[GRAIL_PROP_ROTATE_X1] += gin->trans_x; + prop[GRAIL_PROP_ROTATE_Y1] *= gin->scale_y; + prop[GRAIL_PROP_ROTATE_Y1] += gin->trans_y; + prop[GRAIL_PROP_ROTATE_X2] *= gin->scale_x; + prop[GRAIL_PROP_ROTATE_X2] += gin->trans_x; + prop[GRAIL_PROP_ROTATE_Y2] *= gin->scale_y; + prop[GRAIL_PROP_ROTATE_Y2] += gin->trans_y; + break; + case GRAIL_MAIN_TAP: + prop[GRAIL_PROP_TAP_X] *= gin->scale_x; + prop[GRAIL_PROP_TAP_X] += gin->trans_x; + prop[GRAIL_PROP_TAP_Y] *= gin->scale_y; + prop[GRAIL_PROP_TAP_Y] += gin->trans_y; + break; + }; +} + static int find_gslot(const struct gesture_inserter *gin, int gid) { int i; @@ -59,7 +151,9 @@ static void send_event(struct grail *ge, struct slot_state *s, gev.nprop = ev->nprop; gev.time = ev->time; gev.pos = ev->pos; + transform_pos(ge->gin, &gev.pos); memcpy(gev.prop, ev->prop, ev->nprop * sizeof(grail_prop_t)); + transform_prop(ge->gin, gev.type, gev.prop, gev.nprop); for (i = 0; i < s->nclient; i++) { gev.client_id = s->client_id[i]; ge->gesture(ge, &gev); @@ -95,6 +189,7 @@ static void setup_new_gestures(struct grail *ge, const struct touch *t = &frame->touch[i]; coord[ncoord].x = t->prop[TP_POS_X]; coord[ncoord].y = t->prop[TP_POS_Y]; + transform_pos(gin, &coord[ncoord]); ncoord++; } nclient = ge->get_clients(ge, info, DIM_CLIENT, @@ -284,3 +379,21 @@ void gin_gid_end(struct grail *ge, int gid, } s->status = GRAIL_STATUS_END; } + +void grail_set_bbox(struct grail *ge, + const struct grail_coord *tmin, + const struct grail_coord *tmax) +{ + struct gesture_inserter *gin = ge->gin; + struct grail_coord dmin, dmax; + double sx, sy; + grail_get_units(ge, &dmin, &dmax); + sx = (tmax->x - tmin->x) / (dmax.x - dmin.x); + sy = (tmax->y - tmin->y) / (dmax.y - dmin.y); + gin->scale_x = sx; + gin->scale_y = sy; + gin->scale_r = sqrt((sx * sx + sy * sy) / 2); + gin->trans_x = tmin->x - dmin.x * sx; + gin->trans_y = tmin->y - dmin.y * sy; + gin->transformed = 1; +} -- cgit v1.2.3