949c45e3bcd5251c06c9d14cac0e2665b994f3a8
[platform/core/uifw/e-mod-tizen-gesture.git] / src / e_mod_main.c
1 #define E_COMP_WL
2 #include "e_mod_main.h"
3 #include <string.h>
4
5 E_GesturePtr gesture = NULL;
6 E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Gesture Module of Window Manager" };
7
8 static void *_e_gesture_init(E_Module *m);
9 static void _e_gesture_init_handlers(void);
10
11
12 static void _e_gesture_wl_client_cb_destroy(struct wl_listener *l, void *data);
13
14 static void
15 _e_gesture_swipe_set_client_to_list(struct wl_client *client, E_Gesture_Event_Swipe_Finger *fingers, unsigned int direction)
16 {
17    if (direction & TIZEN_GESTURE_DIRECTION_DOWN)
18      fingers->direction[E_GESTURE_DIRECTION_DOWN].client = client;
19    if (direction & TIZEN_GESTURE_DIRECTION_LEFT)
20      fingers->direction[E_GESTURE_DIRECTION_LEFT].client = client;
21    if (direction & TIZEN_GESTURE_DIRECTION_UP)
22      fingers->direction[E_GESTURE_DIRECTION_UP].client = client;
23    if (direction & TIZEN_GESTURE_DIRECTION_RIGHT)
24      fingers->direction[E_GESTURE_DIRECTION_RIGHT].client = client;
25 }
26
27 /* Function for registering wl_client destroy listener */
28 int
29 e_gesture_add_client_destroy_listener(struct wl_client *client, int mode EINA_UNUSED, int num_of_fingers, unsigned int direction)
30 {
31    struct wl_listener *destroy_listener = NULL;
32    Eina_List *l;
33    E_Gesture_Grabbed_Client *grabbed_client, *data;
34
35    EINA_LIST_FOREACH(gesture->grab_client_list, l, data)
36      {
37         if (data->client == client)
38           {
39              _e_gesture_swipe_set_client_to_list(client, &data->swipe_fingers[num_of_fingers], direction);
40
41              return TIZEN_GESTURE_ERROR_NONE;
42           }
43      }
44
45    destroy_listener = E_NEW(struct wl_listener, 1);
46    if (!destroy_listener)
47      {
48         GTERR("Failed to allocate memory for wl_client destroy listener !\n");
49         return TIZEN_GESTURE_ERROR_NO_SYSTEM_RESOURCES;
50      }
51
52    grabbed_client = E_NEW(E_Gesture_Grabbed_Client, 1);
53    if (!grabbed_client)
54      {
55         GTERR("Failed to allocate memory to save client information !\n");
56         return TIZEN_GESTURE_ERROR_NO_SYSTEM_RESOURCES;
57      }
58
59    destroy_listener->notify = _e_gesture_wl_client_cb_destroy;
60    wl_client_add_destroy_listener(client, destroy_listener);
61    grabbed_client->client = client;
62    grabbed_client->destroy_listener = destroy_listener;
63    _e_gesture_swipe_set_client_to_list(client, &grabbed_client->swipe_fingers[num_of_fingers], direction);
64
65    gesture->grab_client_list = eina_list_append(gesture->grab_client_list, grabbed_client);
66
67    return TIZEN_KEYROUTER_ERROR_NONE;
68 }
69
70 static void
71 _e_gesture_remove_client_destroy_listener(struct wl_client *client, unsigned int num_of_fingers, unsigned int direction)
72 {
73    Eina_List *l, *l_next;
74    E_Gesture_Grabbed_Client *data;
75    int i;
76
77    EINA_LIST_FOREACH_SAFE(gesture->grab_client_list, l, l_next, data)
78      {
79         if (data->client == client)
80           {
81              _e_gesture_swipe_set_client_to_list(NULL, &data->swipe_fingers[num_of_fingers], direction);
82
83              for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
84                {
85                   if (data->swipe_fingers[i].direction[E_GESTURE_DIRECTION_DOWN].client ||
86                       data->swipe_fingers[i].direction[E_GESTURE_DIRECTION_LEFT].client ||
87                       data->swipe_fingers[i].direction[E_GESTURE_DIRECTION_UP].client ||
88                       data->swipe_fingers[i].direction[E_GESTURE_DIRECTION_RIGHT].client)
89                     {
90                        return;
91                     }
92                }
93              wl_list_remove(&data->destroy_listener->link);
94              E_FREE(data->destroy_listener);
95              gesture->grab_client_list = eina_list_remove(gesture->grab_client_list, data);
96              E_FREE(data);
97           }
98      }
99 }
100
101 static void
102 _e_gesture_cb_grab_swipe(struct wl_client *client,
103                    struct wl_resource *resource,
104                    uint32_t num_of_fingers, uint32_t direction)
105 {
106    E_Gesture_Event *gev;
107    unsigned int grabbed_direction = 0x0;
108
109    GTINF("client %p is request grab gesture, fingers: %d, direction: 0x%x\n", client, num_of_fingers, direction);
110    if (num_of_fingers > E_GESTURE_FINGER_MAX)
111      {
112         GTWRN("Do not support %d fingers (max: %d)\n", num_of_fingers, E_GESTURE_FINGER_MAX);
113         tizen_gesture_send_grab_swipe_notify(resource, num_of_fingers, direction, TIZEN_GESTURE_ERROR_INVALID_DATA);
114         goto out;
115      }
116
117    gev = &gesture->gesture_events;
118
119    if (direction & TIZEN_GESTURE_DIRECTION_DOWN)
120      {
121         if (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].client)
122            {
123               grabbed_direction |= TIZEN_GESTURE_DIRECTION_DOWN;
124            }
125         else
126            {
127               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].client = client;
128               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].res = resource;
129            }
130      }
131    if (direction & TIZEN_GESTURE_DIRECTION_LEFT)
132      {
133         if (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].client)
134            {
135               grabbed_direction |= TIZEN_GESTURE_DIRECTION_LEFT;
136            }
137         else
138            {
139               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].client = client;
140               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].res = resource;
141            }
142      }
143    if (direction & TIZEN_GESTURE_DIRECTION_UP)
144      {
145         if (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].client)
146            {
147               grabbed_direction |= TIZEN_GESTURE_DIRECTION_UP;
148            }
149         else
150            {
151               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].client = client;
152               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].res = resource;
153            }
154      }
155    if (direction & TIZEN_GESTURE_DIRECTION_RIGHT)
156      {
157         if (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].client)
158            {
159               grabbed_direction |= TIZEN_GESTURE_DIRECTION_RIGHT;
160            }
161         else
162            {
163               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].client = client;
164               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].res = resource;
165            }
166      }
167
168    if (grabbed_direction)
169      tizen_gesture_send_grab_swipe_notify(resource, num_of_fingers, grabbed_direction, TIZEN_GESTURE_ERROR_GRABBED_ALREADY);
170
171    e_gesture_add_client_destroy_listener(client, TIZEN_GESTURE_TYPE_SWIPE, num_of_fingers, direction & ~grabbed_direction);
172    gesture->grabbed_gesture |= TIZEN_GESTURE_TYPE_SWIPE;
173    gev->swipes.fingers[num_of_fingers].enabled = EINA_TRUE;
174
175    if (!grabbed_direction)
176      tizen_gesture_send_grab_swipe_notify(resource, num_of_fingers, direction, TIZEN_GESTURE_ERROR_NONE);
177
178 out:
179    return;
180 }
181
182 static void
183 _e_gesture_cb_ungrab_swipe(struct wl_client *client,
184                            struct wl_resource *resouce,
185                            uint32_t num_of_fingers, uint32_t direction)
186 {
187    int i, j;
188    E_Gesture_Event *gev;
189    unsigned int ungrabbed_direction = 0x0;
190    int ret = TIZEN_GESTURE_ERROR_NONE;
191
192    GTINF("client %p is request ungrab swipe gesture, fingers: %d, direction: 0x%x, client: %p\n", client, num_of_fingers, direction, gesture->gesture_events.swipes.fingers[0].direction[3].client);
193
194    if (num_of_fingers > E_GESTURE_FINGER_MAX)
195      {
196         GTWRN("Do not support %d fingers (max: %d)\n", num_of_fingers, E_GESTURE_FINGER_MAX);
197         ret = TIZEN_GESTURE_ERROR_INVALID_DATA;
198         goto finish;
199      }
200
201    gev = &gesture->gesture_events;
202
203    if (direction & TIZEN_GESTURE_DIRECTION_DOWN)
204      {
205         if ((gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].client) &&
206             (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].client == client))
207            {
208               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].client = NULL;
209               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].res = NULL;
210            }
211         else
212            {
213               ungrabbed_direction |= TIZEN_GESTURE_DIRECTION_DOWN;
214            }
215      }
216    if (direction & TIZEN_GESTURE_DIRECTION_LEFT)
217      {
218         if ((gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].client) &&
219             (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].client == client))
220            {
221               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].client = NULL;
222               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].res = NULL;
223            }
224         else
225            {
226               ungrabbed_direction |= TIZEN_GESTURE_DIRECTION_LEFT;
227            }
228      }
229    if (direction & TIZEN_GESTURE_DIRECTION_UP)
230      {
231         if ((gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].client) &&
232             (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].client == client))
233            {
234               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].client = NULL;
235               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].res = NULL;
236            }
237         else
238            {
239               ungrabbed_direction |= TIZEN_GESTURE_DIRECTION_UP;
240            }
241      }
242    if (direction & TIZEN_GESTURE_DIRECTION_RIGHT)
243      {
244         if ((gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].client) &&
245             (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].client == client))
246            {
247               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].client = NULL;
248               gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].res = NULL;
249            }
250         else
251            {
252               ungrabbed_direction |= TIZEN_GESTURE_DIRECTION_RIGHT;
253            }
254      }
255
256    if (direction & ~ungrabbed_direction)
257      {
258         _e_gesture_remove_client_destroy_listener(client, num_of_fingers, direction & ~ungrabbed_direction);
259         for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
260           {
261              for (j = 0; j < E_GESTURE_DIRECTION_MAX+1; j++)
262                {
263                   if (gev->swipes.fingers[i].direction[j].client)
264                     {
265                        goto finish;
266                     }
267                }
268              gev->swipes.fingers[i].enabled = EINA_FALSE;
269           }
270         gesture->grabbed_gesture &= ~TIZEN_GESTURE_TYPE_SWIPE;
271      }
272
273 finish:
274    tizen_gesture_send_grab_swipe_notify(resouce, num_of_fingers, direction, ret);
275    return;
276 }
277
278 static const struct tizen_gesture_interface _e_gesture_implementation = {
279    _e_gesture_cb_grab_swipe,
280    _e_gesture_cb_ungrab_swipe
281 };
282
283 /* tizen_gesture global object destroy function */
284 static void
285 _e_gesture_cb_destory(struct wl_resource *resource)
286 {
287    /* TODO : destroy resources if exist */
288 }
289
290 /* tizen_keyrouter global object bind function */
291 static void
292 _e_gesture_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
293 {
294    E_GesturePtr gesture_instance = data;
295    struct wl_resource *resource;
296
297    resource = wl_resource_create(client, &tizen_gesture_interface, MIN(version, 1), id);
298
299    GTDBG("wl_resource_create(...,tizen_gesture_interface,...)\n");
300
301    if (!resource)
302      {
303         GTERR("Failed to create resource ! (version :%d, id:%d)\n", version, id);
304         wl_client_post_no_memory(client);
305          return;
306      }
307
308    wl_resource_set_implementation(resource, &_e_gesture_implementation, gesture_instance, _e_gesture_cb_destory);
309 }
310
311
312
313 static Eina_Bool
314 _e_gesture_event_filter(void *data, void *loop_data EINA_UNUSED, int type, void *event)
315 {
316    (void) data;
317
318    return e_gesture_process_events(event, type);
319 }
320
321 static void
322 _e_gesture_init_handlers(void)
323 {
324    gesture->ef_handler = ecore_event_filter_add(NULL, _e_gesture_event_filter, NULL, NULL);
325 }
326
327 static void *
328 _e_gesture_init(E_Module *m)
329 {
330    gesture = E_NEW(E_Gesture, 1);
331
332    if (!gesture)
333      {
334         GTERR("Failed to allocate memory for gesture !\n");
335         return NULL;
336      }
337
338    if (!e_comp)
339      {
340         GTERR("Failed to initialize gesture module ! (e_comp == NULL)\n");
341         goto err;
342      }
343
344    /* Add filtering mechanism */
345    _e_gesture_init_handlers();
346    gesture->global = wl_global_create(e_comp_wl->wl.disp, &tizen_gesture_interface, 1, gesture, _e_gesture_cb_bind);
347    if (!gesture->global)
348      {
349         GTERR("Failed to create global !\n");
350         goto err;
351      }
352
353    gesture->gesture_filter = E_GESTURE_TYPE_MAX;
354
355    return m;
356
357 err:
358    if (gesture && gesture->ef_handler) ecore_event_filter_del(gesture->ef_handler);
359    if (gesture) E_FREE(gesture);
360
361    return NULL;
362 }
363
364 E_API void *
365 e_modapi_init(E_Module *m)
366 {
367    return _e_gesture_init(m);
368 }
369
370 E_API int
371 e_modapi_shutdown(E_Module *m)
372 {
373    return 1;
374 }
375
376 E_API int
377 e_modapi_save(E_Module *m)
378 {
379    /* Save something to be kept */
380    return 1;
381 }
382
383 static void
384 _e_gesture_wl_client_cb_destroy(struct wl_listener *l, void *data)
385 {
386    struct wl_client *client = data;
387    int i, j;
388    Eina_List *l_list, *l_next;
389    E_Gesture_Grabbed_Client *client_data;
390
391    if (gesture->grabbed_gesture & TIZEN_GESTURE_TYPE_SWIPE)
392      {
393         for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
394           {
395              for (j = 0; j < E_GESTURE_DIRECTION_MAX+1; j++)
396                {
397                   if (gesture->gesture_events.swipes.fingers[i].direction[j].client == client)
398                     {
399                        gesture->gesture_events.swipes.fingers[i].direction[j].client = NULL;
400                        gesture->gesture_events.swipes.fingers[i].direction[j].res = NULL;
401                     }
402                }
403           }
404
405         for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
406           {
407              for (j = 0; j < E_GESTURE_DIRECTION_MAX+1; j++)
408                {
409                   if (gesture->gesture_events.swipes.fingers[i].direction[j].client)
410                     {
411                        goto out;
412                     }
413                }
414              gesture->gesture_events.swipes.fingers[i].enabled = EINA_FALSE;
415           }
416         gesture->grabbed_gesture &= ~TIZEN_GESTURE_TYPE_SWIPE;
417      }
418
419 out:
420    E_FREE(l);
421    l = NULL;
422    EINA_LIST_FOREACH_SAFE(gesture->grab_client_list, l_list, l_next, client_data)
423      {
424         if (client_data->client == client)
425           {
426              gesture->grab_client_list = eina_list_remove(gesture->grab_client_list, client_data);
427              E_FREE(client_data);
428           }
429      }
430 }