summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/grail.h4
-rw-r--r--src/grail-inserter.c113
-rw-r--r--test/grail-gesture.c4
3 files changed, 121 insertions, 0 deletions
diff --git a/include/grail.h b/include/grail.h
index 241800e..c77a6e3 100644
--- a/include/grail.h
+++ b/include/grail.h
@@ -86,6 +86,10 @@ int grail_idle(struct grail *ge, int fd, int ms);
86int grail_pull(struct grail *ge, int fd); 86int grail_pull(struct grail *ge, int fd);
87void grail_close(struct grail *ge, int fd); 87void grail_close(struct grail *ge, int fd);
88 88
89void grail_set_bbox(struct grail *ge,
90 const struct grail_coord *min,
91 const struct grail_coord *max);
92
89void grail_get_units(const struct grail *ge, 93void grail_get_units(const struct grail *ge,
90 struct grail_coord *min, struct grail_coord *max); 94 struct grail_coord *min, struct grail_coord *max);
91 95
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 @@
24#include <malloc.h> 24#include <malloc.h>
25#include <string.h> 25#include <string.h>
26#include <errno.h> 26#include <errno.h>
27#include <math.h>
27 28
28static const int MAX_GESTURE_ID = 0xfff; 29static const int MAX_GESTURE_ID = 0xfff;
29 30
@@ -34,8 +35,99 @@ struct gesture_inserter {
34 grail_mask_t used[DIM_INSTANCE_BYTES]; 35 grail_mask_t used[DIM_INSTANCE_BYTES];
35 grail_time_t time; 36 grail_time_t time;
36 int gestureid; 37 int gestureid;
38 int transformed;
39 float scale_x, scale_y, scale_r;
40 float trans_x, trans_y;
37}; 41};
38 42
43static const int grail_main_type[DIM_GRAIL_TYPE] = {
44 GRAIL_MAIN_DRAG,
45 GRAIL_MAIN_PINCH,
46 GRAIL_MAIN_ROTATE,
47 GRAIL_MAIN_DRAG,
48 GRAIL_MAIN_PINCH,
49 GRAIL_MAIN_ROTATE,
50 GRAIL_MAIN_DRAG,
51 GRAIL_MAIN_PINCH,
52 GRAIL_MAIN_ROTATE,
53 GRAIL_MAIN_DRAG,
54 GRAIL_MAIN_PINCH,
55 GRAIL_MAIN_ROTATE,
56 GRAIL_MAIN_DRAG,
57 GRAIL_MAIN_PINCH,
58 GRAIL_MAIN_ROTATE,
59 GRAIL_MAIN_TAP,
60 GRAIL_MAIN_TAP,
61 GRAIL_MAIN_TAP,
62 GRAIL_MAIN_TAP,
63 GRAIL_MAIN_TAP,
64 GRAIL_MAIN_DRAG,
65 GRAIL_MAIN_PINCH,
66 GRAIL_MAIN_ROTATE,
67 GRAIL_MAIN_DRAG,
68 GRAIL_MAIN_PINCH,
69 GRAIL_MAIN_ROTATE,
70};
71
72static void transform_pos(const struct gesture_inserter *gin,
73 struct grail_coord *pos)
74{
75 if (gin->transformed) {
76 pos->x *= gin->scale_x;
77 pos->x += gin->trans_x;
78 pos->y *= gin->scale_y;
79 pos->y += gin->trans_y;
80 }
81}
82
83static void transform_prop(const struct gesture_inserter *gin, int type,
84 grail_prop_t *prop, int nprop)
85{
86 if (!gin->transformed)
87 return;
88 switch (grail_main_type[type]) {
89 case GRAIL_MAIN_DRAG:
90 prop[GRAIL_PROP_DRAG_DX] *= gin->scale_x;
91 prop[GRAIL_PROP_DRAG_DY] *= gin->scale_y;
92 prop[GRAIL_PROP_DRAG_VX] *= gin->scale_x;
93 prop[GRAIL_PROP_DRAG_VY] *= gin->scale_y;
94 prop[GRAIL_PROP_DRAG_X] *= gin->scale_x;
95 prop[GRAIL_PROP_DRAG_X] += gin->trans_x;
96 prop[GRAIL_PROP_DRAG_Y] *= gin->scale_y;
97 prop[GRAIL_PROP_DRAG_Y] += gin->trans_y;
98 break;
99 case GRAIL_MAIN_PINCH:
100 prop[GRAIL_PROP_PINCH_DR] *= gin->scale_r;
101 prop[GRAIL_PROP_PINCH_VR] *= gin->scale_r;
102 prop[GRAIL_PROP_PINCH_R] *= gin->scale_r;
103 prop[GRAIL_PROP_PINCH_X1] *= gin->scale_x;
104 prop[GRAIL_PROP_PINCH_X1] += gin->trans_x;
105 prop[GRAIL_PROP_PINCH_Y1] *= gin->scale_y;
106 prop[GRAIL_PROP_PINCH_Y1] += gin->trans_y;
107 prop[GRAIL_PROP_PINCH_X2] *= gin->scale_x;
108 prop[GRAIL_PROP_PINCH_X2] += gin->trans_x;
109 prop[GRAIL_PROP_PINCH_Y2] *= gin->scale_y;
110 prop[GRAIL_PROP_PINCH_Y2] += gin->trans_y;
111 break;
112 case GRAIL_MAIN_ROTATE:
113 prop[GRAIL_PROP_ROTATE_X1] *= gin->scale_x;
114 prop[GRAIL_PROP_ROTATE_X1] += gin->trans_x;
115 prop[GRAIL_PROP_ROTATE_Y1] *= gin->scale_y;
116 prop[GRAIL_PROP_ROTATE_Y1] += gin->trans_y;
117 prop[GRAIL_PROP_ROTATE_X2] *= gin->scale_x;
118 prop[GRAIL_PROP_ROTATE_X2] += gin->trans_x;
119 prop[GRAIL_PROP_ROTATE_Y2] *= gin->scale_y;
120 prop[GRAIL_PROP_ROTATE_Y2] += gin->trans_y;
121 break;
122 case GRAIL_MAIN_TAP:
123 prop[GRAIL_PROP_TAP_X] *= gin->scale_x;
124 prop[GRAIL_PROP_TAP_X] += gin->trans_x;
125 prop[GRAIL_PROP_TAP_Y] *= gin->scale_y;
126 prop[GRAIL_PROP_TAP_Y] += gin->trans_y;
127 break;
128 };
129}
130
39static int find_gslot(const struct gesture_inserter *gin, int gid) 131static int find_gslot(const struct gesture_inserter *gin, int gid)
40{ 132{
41 int i; 133 int i;
@@ -59,7 +151,9 @@ static void send_event(struct grail *ge, struct slot_state *s,
59 gev.nprop = ev->nprop; 151 gev.nprop = ev->nprop;
60 gev.time = ev->time; 152 gev.time = ev->time;
61 gev.pos = ev->pos; 153 gev.pos = ev->pos;
154 transform_pos(ge->gin, &gev.pos);
62 memcpy(gev.prop, ev->prop, ev->nprop * sizeof(grail_prop_t)); 155 memcpy(gev.prop, ev->prop, ev->nprop * sizeof(grail_prop_t));
156 transform_prop(ge->gin, gev.type, gev.prop, gev.nprop);
63 for (i = 0; i < s->nclient; i++) { 157 for (i = 0; i < s->nclient; i++) {
64 gev.client_id = s->client_id[i]; 158 gev.client_id = s->client_id[i];
65 ge->gesture(ge, &gev); 159 ge->gesture(ge, &gev);
@@ -95,6 +189,7 @@ static void setup_new_gestures(struct grail *ge,
95 const struct touch *t = &frame->touch[i]; 189 const struct touch *t = &frame->touch[i];
96 coord[ncoord].x = t->prop[TP_POS_X]; 190 coord[ncoord].x = t->prop[TP_POS_X];
97 coord[ncoord].y = t->prop[TP_POS_Y]; 191 coord[ncoord].y = t->prop[TP_POS_Y];
192 transform_pos(gin, &coord[ncoord]);
98 ncoord++; 193 ncoord++;
99 } 194 }
100 nclient = ge->get_clients(ge, info, DIM_CLIENT, 195 nclient = ge->get_clients(ge, info, DIM_CLIENT,
@@ -284,3 +379,21 @@ void gin_gid_end(struct grail *ge, int gid,
284 } 379 }
285 s->status = GRAIL_STATUS_END; 380 s->status = GRAIL_STATUS_END;
286} 381}
382
383void grail_set_bbox(struct grail *ge,
384 const struct grail_coord *tmin,
385 const struct grail_coord *tmax)
386{
387 struct gesture_inserter *gin = ge->gin;
388 struct grail_coord dmin, dmax;
389 double sx, sy;
390 grail_get_units(ge, &dmin, &dmax);
391 sx = (tmax->x - tmin->x) / (dmax.x - dmin.x);
392 sy = (tmax->y - tmin->y) / (dmax.y - dmin.y);
393 gin->scale_x = sx;
394 gin->scale_y = sy;
395 gin->scale_r = sqrt((sx * sx + sy * sy) / 2);
396 gin->trans_x = tmin->x - dmin.x * sx;
397 gin->trans_y = tmin->y - dmin.y * sy;
398 gin->transformed = 1;
399}
diff --git a/test/grail-gesture.c b/test/grail-gesture.c
index c559661..762d3df 100644
--- a/test/grail-gesture.c
+++ b/test/grail-gesture.c
@@ -103,6 +103,10 @@ int main(int argc, char *argv[])
103 return -1; 103 return -1;
104 } 104 }
105 grail_filter_abs_events(&ge, 1); 105 grail_filter_abs_events(&ge, 1);
106
107 struct grail_coord min = { -2, -1 }, max = { 2, 1 };
108 grail_set_bbox(&ge, &min, &max);
109
106 loop_device(&ge, fd); 110 loop_device(&ge, fd);
107 grail_close(&ge, fd); 111 grail_close(&ge, fd);
108 112