summaryrefslogtreecommitdiff
path: root/src/grail-inserter.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/grail-inserter.c')
-rw-r--r--src/grail-inserter.c248
1 files changed, 151 insertions, 97 deletions
diff --git a/src/grail-inserter.c b/src/grail-inserter.c
index b357e29..3927875 100644
--- a/src/grail-inserter.c
+++ b/src/grail-inserter.c
@@ -29,28 +29,6 @@
29 29
30static const int MAX_GESTURE_ID = 0xfff; 30static const int MAX_GESTURE_ID = 0xfff;
31 31
32int gin_init(struct grail *ge)
33{
34 struct gesture_inserter *x;
35 x = calloc(1, sizeof(*x));
36 if (!x)
37 return -ENOMEM;
38 ge->gin = x;
39 return 0;
40}
41
42void gin_destroy(struct grail *ge)
43{
44 free(ge->gin);
45 ge->gin = NULL;
46}
47
48void gin_frame_begin(struct grail *ge, grail_time_t time)
49{
50 struct gesture_inserter *gin = ge->gin;
51 gin->time = time;
52}
53
54static void send_event(struct grail *ge, struct slot_state *s, 32static void send_event(struct grail *ge, struct slot_state *s,
55 const struct gesture_event *ev) 33 const struct gesture_event *ev)
56{ 34{
@@ -61,124 +39,200 @@ static void send_event(struct grail *ge, struct slot_state *s,
61 gev.type = s->type; 39 gev.type = s->type;
62 gev.id = s->id; 40 gev.id = s->id;
63 gev.status = s->status; 41 gev.status = s->status;
64 gev.pos.x = s->x; 42 gev.ntouch = ev->ntouch;
65 gev.pos.y = s->x; 43 gev.nprop = ev->nprop;
66 gev.time = ev->time; 44 gev.time = ev->time;
67 memcpy(gev.prop, ev->prop, DIM_GRAIL_PROP * sizeof(gev.prop[0])); 45 gev.pos = ev->pos;
46 memcpy(gev.prop, ev->prop, ev->nprop * sizeof(grail_prop_t));
68 for (i = 0; i < s->nclient; i++) { 47 for (i = 0; i < s->nclient; i++) {
69 gev.client_id = s->client_id[i]; 48 gev.client_id = s->client_id[i];
70 ge->gesture(ge, &gev); 49 ge->gesture(ge, &gev);
71 } 50 }
72} 51}
73 52
74void gin_frame_end(struct grail *ge, grail_mask_t *filtered) 53// todo: spanning tree for multi-user case
54static void setup_new_gestures(struct grail *ge,
55 const struct touch_frame *frame)
75{ 56{
76 struct gesture_inserter *gin = ge->gin; 57 struct gesture_inserter *gin = ge->gin;
77 struct gesture_event ev; 58 grail_mask_t types[DIM_GRAIL_TYPE_BYTES];
78 grail_mask_t span[DIM_SLOT_BYTES]; 59 grail_mask_t span[DIM_TOUCH_BYTES];
79 int i, slot, spanned = 0; 60 struct grail_client_info info[DIM_CLIENT];
80 memset(filtered, 0, DIM_EV_TYPE_BYTES); 61 int i, j, nclient = 0;
62 int nfresh = grail_mask_count(gin->fresh, sizeof(gin->fresh));
63 if (!nfresh)
64 return;
65
66 memset(types, 0, sizeof(types));
81 memset(span, 0, sizeof(span)); 67 memset(span, 0, sizeof(span));
82 for (slot = 0; slot < DIM_SLOT; slot++) { 68
83 struct slot_state *s = &gin->state[slot]; 69 grail_mask_foreach(i, gin->fresh, sizeof(gin->fresh)) {
84 if (!grail_get_mask(gin->used, slot)) 70 struct slot_state *s = &gin->state[i];
85 continue; 71 grail_mask_set(types, s->type);
72 grail_mask_set_mask(span, s->span, sizeof(span));
73 }
74
75 if (ge->get_clients) {
76 struct grail_coord coord[DIM_CLIENT];
77 int ncoord = 0;
78 grail_mask_foreach(i, span, sizeof(span)) {
79 const struct touch *t = &frame->touch[i];
80 coord[ncoord].x = t->prop[TP_POS_X];
81 coord[ncoord].y = t->prop[TP_POS_Y];
82 ncoord++;
83 }
84 nclient = ge->get_clients(ge, info, DIM_CLIENT,
85 coord, ncoord, types, sizeof(types));
86 }
87
88 grail_mask_foreach(i, gin->fresh, sizeof(gin->fresh)) {
89 struct slot_state *s = &gin->state[i];
90 s->nclient = 0;
91 for (j = 0; j < nclient; j++) {
92 if (!grail_mask_get(info[j].mask, s->type))
93 continue;
94 s->client_id[s->nclient++] = info[j].id;
95 }
96 }
97
98 memset(gin->fresh, 0, sizeof(gin->fresh));
99}
100
101int gin_init(struct grail *ge)
102{
103 struct gesture_inserter *gin;
104 int i;
105 gin = calloc(1, sizeof(*gin));
106 if (!gin)
107 return -ENOMEM;
108 for (i = 0; i < DIM_INSTANCE; i++)
109 grail_mask_set(gin->unused, i);
110 ge->gin = gin;
111 return 0;
112}
113
114void gin_destroy(struct grail *ge)
115{
116 free(ge->gin);
117 ge->gin = NULL;
118}
119
120void gin_frame_begin(struct grail *ge, const struct touch_frame *frame)
121{
122 struct gesture_inserter *gin = ge->gin;
123 gin->time = frame->time;
124}
125
126void gin_frame_end(struct grail *ge,
127 grail_mask_t *filtered, int max_filtered,
128 const struct touch_frame *frame)
129{
130 struct gesture_inserter *gin = ge->gin;
131 grail_mask_t span[DIM_INSTANCE_BYTES];
132 int i, hold = 0, discard = 0;
133
134 memset(filtered, 0, max_filtered);
135 memset(span, 0, sizeof(span));
136
137 setup_new_gestures(ge, frame);
138
139 grail_mask_foreach(i, gin->used, sizeof(gin->used)) {
140 struct slot_state *s = &gin->state[i];
86 if (!s->nclient) 141 if (!s->nclient)
87 gin_gesture_discard(gin, slot); 142 continue;
143 if (s->priority > hold)
144 hold = s->priority;
145 if (s->status == GRAIL_STATUS_BEGIN)
146 continue;
147 if (s->priority > discard)
148 discard = s->priority;
88 } 149 }
89 for (slot = 0; slot < DIM_SLOT; slot++) { 150
90 struct slot_state *s = &gin->state[slot]; 151 grail_mask_foreach(i, gin->used, sizeof(gin->used)) {
91 if (!grail_get_mask(gin->used, slot)) 152 struct slot_state *s = &gin->state[i];
153 if (!s->nclient || s->priority < discard)
154 gin_gesture_discard(gin, i);
155 }
156
157 grail_mask_foreach(i, gin->used, sizeof(gin->used)) {
158 struct slot_state *s = &gin->state[i];
159 struct gesture_event ev;
160 grail_mask_set_mask(span, s->span, sizeof(span));
161 if (s->priority < hold)
92 continue; 162 continue;
93 for (i = 0; i < DIM_SLOT_BYTES; i++) {
94 span[i] |= s->span[i];
95 spanned += !!span[i];
96 }
97 while (!gebuf_empty(&s->buf)) { 163 while (!gebuf_empty(&s->buf)) {
98 gebuf_get(&s->buf, &ev); 164 gebuf_get(&s->buf, &ev);
99 send_event(ge, s, &ev); 165 send_event(ge, s, &ev);
100 } 166 }
101 if (s->status == GRAIL_STATUS_BEGIN)
102 s->status = GRAIL_STATUS_UPDATE;
103 } 167 }
104 if (spanned) 168
105 grail_set_mask(filtered, EV_ABS); 169 grail_mask_foreach(i, gin->used, sizeof(gin->used)) {
170 struct slot_state *s = &gin->state[i];
171 if (s->status == GRAIL_STATUS_END)
172 gin_gesture_discard(gin, i);
173 }
174
175 if (grail_mask_count(span, sizeof(span)))
176 grail_mask_set(filtered, EV_ABS);
106} 177}
107 178
108int gin_gesture_begin(struct grail *ge, const struct touch_frame *frame, 179int gin_gesture_begin(struct grail *ge, int type, int priority,
109 int type, int x, int y, const grail_mask_t *span) 180 const grail_mask_t *span, int nspan)
110{ 181{
111 struct grail_client_info info[DIM_CLIENT];
112 struct grail_coord coord[DIM_CLIENT];
113 struct gesture_inserter *gin = ge->gin; 182 struct gesture_inserter *gin = ge->gin;
114 struct slot_state *s; 183 struct slot_state *s;
115 int i, slot, nc, ncoord = 0; 184 int geslot = grail_mask_get_first(gin->unused, sizeof(gin->unused));
116 for (slot = 0; slot < DIM_SLOT; slot++) 185 if (geslot < 0)
117 if (!grail_get_mask(gin->used, slot))
118 break;
119 if (slot >= DIM_SLOT)
120 return -1; 186 return -1;
121 s = &gin->state[slot]; 187 s = &gin->state[geslot];
122 s->type = type; 188 s->type = type;
189 s->priority = priority;
123 s->id = gin->gestureid++ & MAX_GESTURE_ID; 190 s->id = gin->gestureid++ & MAX_GESTURE_ID;
124 s->status = GRAIL_STATUS_BEGIN; 191 s->status = GRAIL_STATUS_BEGIN;
125 s->x = x;
126 s->y = y;
127 s->nclient = 0; 192 s->nclient = 0;
128 if (ge->get_clients) { 193 memcpy(s->span, span, nspan);
129 grail_mask_t tps[DIM_GRAIL_TYPE_BYTES];
130 memset(tps, 0, sizeof(tps));
131 grail_set_mask(tps, type);
132 for (i = 0; i < DIM_SLOT; i++) {
133 const struct touch *t = &frame->touch[i];
134 if (!grail_get_mask(span, i))
135 continue;
136 coord[ncoord].x = t->prop[TP_POS_X];
137 coord[ncoord].y = t->prop[TP_POS_Y];
138 ncoord++;
139 }
140 nc = ge->get_clients(ge, info, DIM_CLIENT, coord, ncoord, tps);
141 for (i = 0; i < nc; i++) {
142 if (!grail_get_mask(info[i].mask, type))
143 continue;
144 s->client_id[s->nclient] = info[i].id;
145 s->nclient++;
146 }
147 }
148 memcpy(s->span, span, sizeof(s->span));
149 gebuf_clear(&s->buf); 194 gebuf_clear(&s->buf);
150 grail_set_mask(gin->used, slot); 195 grail_mask_clear(gin->unused, geslot);
151 return slot; 196 grail_mask_set(gin->fresh, geslot);
197 grail_mask_set(gin->used, geslot);
198 return geslot;
152} 199}
153 200
154void gin_gesture_end(struct gesture_inserter *gin, int slot) 201void gin_gesture_end(struct gesture_inserter *gin, int geslot)
155{ 202{
156 struct slot_state *s = &gin->state[slot]; 203 gin->state[geslot].status = GRAIL_STATUS_END;
157 s->status = GRAIL_STATUS_END;
158 grail_clear_mask(gin->used, slot);
159} 204}
160 205
161void gin_gesture_discard(struct gesture_inserter *gin, int slot) 206void gin_gesture_discard(struct gesture_inserter *gin, int geslot)
162{ 207{
163 struct slot_state *s = &gin->state[slot]; 208 gebuf_clear(&gin->state[geslot].buf);
164 gebuf_clear(&s->buf); 209 gin_gesture_end(gin, geslot);
165 gin_gesture_end(gin, slot); 210 grail_mask_clear(gin->used, geslot);
211 grail_mask_set(gin->unused, geslot);
166} 212}
167 213
168void gin_gesture_end_all(struct gesture_inserter *gin) 214void gin_gesture_discard_type(struct gesture_inserter *gin, int type)
169{ 215{
170 int slot; 216 int i;
171 for (slot = 0; slot < DIM_SLOT; slot++) 217 grail_mask_foreach(i, gin->used, sizeof(gin->used))
172 gin_gesture_end(gin, slot); 218 if (gin->state[i].type == type)
219 gin_gesture_discard(gin, i);
173} 220}
174 221
175void gin_gesture_event(struct gesture_inserter *gin, int slot, 222void gin_gesture_event(struct gesture_inserter *gin, int geslot,
176 const grail_prop_t *prop) 223 float x, float y, int ntouch,
224 const grail_prop_t *prop, int nprop)
177{ 225{
178 struct slot_state *s = &gin->state[slot]; 226 struct slot_state *s = &gin->state[geslot];
179 struct gesture_event ev; 227 struct gesture_event ev;
228 ev.ntouch = ntouch;
229 ev.nprop = nprop;
180 ev.time = gin->time; 230 ev.time = gin->time;
181 memcpy(ev.prop, prop, sizeof(ev.prop)); 231 ev.pos.x = x;
232 ev.pos.y = y;
233 memcpy(ev.prop, prop, nprop * sizeof(grail_prop_t));
234 if (s->status == GRAIL_STATUS_BEGIN)
235 s->status = GRAIL_STATUS_UPDATE;
182 gebuf_put(&s->buf, &ev); 236 gebuf_put(&s->buf, &ev);
183} 237}
184 238