2 #include "e_mod_main.h"
4 #include "e_service_quickpanel.h"
6 E_GesturePtr gesture = NULL;
7 E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Gesture Module of Window Manager" };
9 static E_Gesture_Config_Data *_e_gesture_init(E_Module *m);
10 static void _e_gesture_init_handlers(void);
13 static void _e_gesture_wl_client_cb_destroy(struct wl_listener *l, void *data);
16 _e_gesture_edge_swipe_set_client_to_list(struct wl_client *client, E_Gesture_Event_Edge_Swipe_Finger *fingers, unsigned int edge)
18 if (edge & TIZEN_GESTURE_EDGE_TOP)
19 fingers->edge[E_GESTURE_EDGE_TOP].client = client;
20 if (edge & TIZEN_GESTURE_EDGE_RIGHT)
21 fingers->edge[E_GESTURE_EDGE_RIGHT].client = client;
22 if (edge & TIZEN_GESTURE_EDGE_BOTTOM)
23 fingers->edge[E_GESTURE_EDGE_BOTTOM].client = client;
24 if (edge & TIZEN_GESTURE_EDGE_LEFT)
25 fingers->edge[E_GESTURE_EDGE_LEFT].client = client;
28 /* Function for registering wl_client destroy listener */
30 e_gesture_add_client_destroy_listener(struct wl_client *client, int mode EINA_UNUSED, int fingers, unsigned int edge)
32 struct wl_listener *destroy_listener = NULL;
34 E_Gesture_Grabbed_Client *grabbed_client, *data;
36 EINA_LIST_FOREACH(gesture->grab_client_list, l, data)
38 if (data->client == client)
40 _e_gesture_edge_swipe_set_client_to_list(client, &data->edge_swipe_fingers[fingers], edge);
42 return TIZEN_GESTURE_ERROR_NONE;
46 destroy_listener = E_NEW(struct wl_listener, 1);
47 if (!destroy_listener)
49 GTERR("Failed to allocate memory for wl_client destroy listener !\n");
50 return TIZEN_GESTURE_ERROR_NO_SYSTEM_RESOURCES;
53 grabbed_client = E_NEW(E_Gesture_Grabbed_Client, 1);
56 GTERR("Failed to allocate memory to save client information !\n");
57 return TIZEN_GESTURE_ERROR_NO_SYSTEM_RESOURCES;
60 destroy_listener->notify = _e_gesture_wl_client_cb_destroy;
61 wl_client_add_destroy_listener(client, destroy_listener);
62 grabbed_client->client = client;
63 grabbed_client->destroy_listener = destroy_listener;
64 _e_gesture_edge_swipe_set_client_to_list(client, &grabbed_client->edge_swipe_fingers[fingers], edge);
66 gesture->grab_client_list = eina_list_append(gesture->grab_client_list, grabbed_client);
68 return TIZEN_KEYROUTER_ERROR_NONE;
72 _e_gesture_remove_client_destroy_listener(struct wl_client *client, unsigned int fingers, unsigned int edge)
74 Eina_List *l, *l_next;
75 E_Gesture_Grabbed_Client *data;
78 EINA_LIST_FOREACH_SAFE(gesture->grab_client_list, l, l_next, data)
80 if (data->client == client)
82 _e_gesture_edge_swipe_set_client_to_list(NULL, &data->edge_swipe_fingers[fingers], edge);
84 for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
86 if (data->edge_swipe_fingers[i].edge[E_GESTURE_EDGE_TOP].client ||
87 data->edge_swipe_fingers[i].edge[E_GESTURE_EDGE_RIGHT].client ||
88 data->edge_swipe_fingers[i].edge[E_GESTURE_EDGE_BOTTOM].client ||
89 data->edge_swipe_fingers[i].edge[E_GESTURE_EDGE_LEFT].client)
94 wl_list_remove(&data->destroy_listener->link);
95 E_FREE(data->destroy_listener);
96 gesture->grab_client_list = eina_list_remove(gesture->grab_client_list, data);
103 _e_gesture_cb_grab_edge_swipe(struct wl_client *client,
104 struct wl_resource *resource,
105 uint32_t fingers, uint32_t edge)
107 E_Gesture_Event *gev;
108 unsigned int grabbed_edge = 0x0;
110 GTINF("client %p is request grab gesture, fingers: %d, edge: 0x%x\n", client, fingers, edge);
111 if (fingers > E_GESTURE_FINGER_MAX)
113 GTWRN("Do not support %d fingers (max: %d)\n", fingers, E_GESTURE_FINGER_MAX);
114 tizen_gesture_send_grab_edge_swipe_notify(resource, fingers, edge, TIZEN_GESTURE_ERROR_INVALID_DATA);
118 gev = &gesture->gesture_events;
120 if (edge & TIZEN_GESTURE_EDGE_TOP)
122 if (gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_TOP].client)
124 grabbed_edge |= TIZEN_GESTURE_EDGE_TOP;
128 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_TOP].client = client;
129 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_TOP].res = resource;
132 if (edge & TIZEN_GESTURE_EDGE_RIGHT)
134 if (gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_RIGHT].client)
136 grabbed_edge |= TIZEN_GESTURE_EDGE_RIGHT;
140 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_RIGHT].client = client;
141 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_RIGHT].res = resource;
144 if (edge & TIZEN_GESTURE_EDGE_BOTTOM)
146 if (gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_BOTTOM].client)
148 grabbed_edge |= TIZEN_GESTURE_EDGE_BOTTOM;
152 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_BOTTOM].client = client;
153 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_BOTTOM].res = resource;
156 if (edge & TIZEN_GESTURE_EDGE_LEFT)
158 if (gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_LEFT].client)
160 grabbed_edge |= TIZEN_GESTURE_EDGE_LEFT;
164 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_LEFT].client = client;
165 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_LEFT].res = resource;
170 tizen_gesture_send_grab_edge_swipe_notify(resource, fingers, grabbed_edge, TIZEN_GESTURE_ERROR_GRABBED_ALREADY);
172 e_gesture_add_client_destroy_listener(client, TIZEN_GESTURE_TYPE_EDGE_SWIPE, fingers, edge & ~grabbed_edge);
173 gesture->grabbed_gesture |= TIZEN_GESTURE_TYPE_EDGE_SWIPE;
174 gev->edge_swipes.fingers[fingers].enabled = EINA_TRUE;
175 if (gev->edge_swipes.event_keep) gesture->event_state = E_GESTURE_EVENT_STATE_KEEP;
176 gev->edge_swipes.enabled_edge |= grabbed_edge;
179 tizen_gesture_send_grab_edge_swipe_notify(resource, fingers, edge, TIZEN_GESTURE_ERROR_NONE);
186 _e_gesture_cb_ungrab_edge_swipe(struct wl_client *client,
187 struct wl_resource *resouce,
188 uint32_t fingers, uint32_t edge)
191 E_Gesture_Event *gev;
192 unsigned int ungrabbed_edge = 0x0;
193 int ret = TIZEN_GESTURE_ERROR_NONE;
195 GTINF("client %p is request ungrab edge swipe gesture, fingers: %d, edge: 0x%x, client: %p\n", client, fingers, edge, gesture->gesture_events.edge_swipes.fingers[0].edge[3].client);
197 if (fingers > E_GESTURE_FINGER_MAX)
199 GTWRN("Do not support %d fingers (max: %d)\n", fingers, E_GESTURE_FINGER_MAX);
200 ret = TIZEN_GESTURE_ERROR_INVALID_DATA;
204 gev = &gesture->gesture_events;
206 if (edge & TIZEN_GESTURE_EDGE_TOP)
208 if ((gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_TOP].client) &&
209 (gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_TOP].client == client))
211 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_TOP].client = NULL;
212 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_TOP].res = NULL;
216 ungrabbed_edge |= TIZEN_GESTURE_EDGE_TOP;
219 if (edge & TIZEN_GESTURE_EDGE_RIGHT)
221 if ((gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_RIGHT].client) &&
222 (gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_RIGHT].client == client))
224 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_RIGHT].client = NULL;
225 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_RIGHT].res = NULL;
229 ungrabbed_edge |= TIZEN_GESTURE_EDGE_RIGHT;
232 if (edge & TIZEN_GESTURE_EDGE_BOTTOM)
234 if ((gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_BOTTOM].client) &&
235 (gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_BOTTOM].client == client))
237 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_BOTTOM].client = NULL;
238 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_BOTTOM].res = NULL;
242 ungrabbed_edge |= TIZEN_GESTURE_EDGE_BOTTOM;
245 if (edge & TIZEN_GESTURE_EDGE_LEFT)
247 if ((gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_LEFT].client) &&
248 (gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_LEFT].client == client))
250 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_LEFT].client = NULL;
251 gev->edge_swipes.fingers[fingers].edge[E_GESTURE_EDGE_LEFT].res = NULL;
255 ungrabbed_edge |= TIZEN_GESTURE_EDGE_LEFT;
259 if (edge & ~ungrabbed_edge)
261 _e_gesture_remove_client_destroy_listener(client, fingers, edge & ~ungrabbed_edge);
262 for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
264 for (j = 0; j < E_GESTURE_EDGE_MAX+1; j++)
266 if (gev->edge_swipes.fingers[i].edge[j].client)
271 gev->edge_swipes.fingers[i].enabled = EINA_FALSE;
273 gesture->grabbed_gesture &= ~TIZEN_GESTURE_TYPE_EDGE_SWIPE;
274 if (gev->edge_swipes.event_keep) gesture->event_state = E_GESTURE_EVENT_STATE_PROPAGATE;
278 gev->edge_swipes.enabled_edge &= ~edge;
279 for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
281 for (j = 1; j < E_GESTURE_EDGE_MAX+1; j++)
283 if (gev->edge_swipes.fingers[i].edge[j].client)
285 gev->edge_swipes.enabled_edge |= (1 << (j - 1));
288 if (gev->edge_swipes.enabled_edge == E_GESTURE_EDGE_ALL) break;
292 tizen_gesture_send_grab_edge_swipe_notify(resouce, fingers, edge, ret);
296 static const struct tizen_gesture_interface _e_gesture_implementation = {
297 _e_gesture_cb_grab_edge_swipe,
298 _e_gesture_cb_ungrab_edge_swipe
301 /* tizen_gesture global object destroy function */
303 _e_gesture_cb_destory(struct wl_resource *resource)
305 /* TODO : destroy resources if exist */
308 /* tizen_keyrouter global object bind function */
310 _e_gesture_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
312 E_GesturePtr gesture_instance = data;
313 struct wl_resource *resource;
315 resource = wl_resource_create(client, &tizen_gesture_interface, MIN(version, 1), id);
317 GTDBG("wl_resource_create(...,tizen_gesture_interface,...)\n");
321 GTERR("Failed to create resource ! (version :%d, id:%d)\n", version, id);
322 wl_client_post_no_memory(client);
326 wl_resource_set_implementation(resource, &_e_gesture_implementation, gesture_instance, _e_gesture_cb_destory);
330 _e_gesture_event_filter(void *data, void *loop_data EINA_UNUSED, int type, void *event)
334 if (type == ECORE_EVENT_MOUSE_BUTTON_DOWN)
336 gesture->gesture_events.num_pressed++;
338 else if (type == ECORE_EVENT_MOUSE_BUTTON_UP)
340 gesture->gesture_events.num_pressed--;
341 if (gesture->gesture_events.num_pressed < 0)
342 gesture->gesture_events.num_pressed = 0;
343 if (gesture->gesture_events.num_pressed == 0)
345 if (!gesture->enable && gesture->enabled_window)
347 e_gesture_event_filter_enable(EINA_TRUE);
350 else if (gesture->enable && !gesture->enabled_window)
352 e_gesture_event_filter_enable(EINA_FALSE);
353 return e_gesture_process_events(event, type);
357 if (!gesture->enable) return EINA_TRUE;
359 return e_gesture_process_events(event, type);
363 _e_gesture_window_gesture_disabled_change(E_Client *ec)
365 if (ec->gesture_disable && gesture->enable)
367 GTINF("Gesture disabled window\n");
368 gesture->enabled_window = EINA_FALSE;
370 else if (!ec->gesture_disable && !gesture->enable)
372 GTINF("Gesture enabled window\n");
373 gesture->enabled_window = EINA_TRUE;
376 if (gesture->gesture_events.num_pressed == 0)
378 e_gesture_event_filter_enable(gesture->enabled_window);
383 _e_gesture_cb_client_focus_in(void *data, int type, void *event)
386 E_Event_Client *ev = (E_Event_Client *)event;
388 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
390 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_PASS_ON);
391 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, ECORE_CALLBACK_PASS_ON);
393 _e_gesture_window_gesture_disabled_change(ec);
395 return ECORE_CALLBACK_PASS_ON;
399 _e_gesture_cb_aux_hint_change(void *data EINA_UNUSED, E_Client *ec)
402 if (e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) return;
403 if (!ec->comp_data->aux_hint.changed) return;
405 qp_ec = e_service_quickpanel_client_get();
407 /* Return if the aux hint change didn't happen to the focused ec */
409 (ec != e_client_focused_get()))
412 _e_gesture_window_gesture_disabled_change(ec);
416 _e_gesture_init_handlers(void)
418 gesture->ef_handler = ecore_event_filter_add(NULL, _e_gesture_event_filter, NULL, NULL);
420 gesture->handlers = eina_list_append(gesture->handlers,
421 ecore_event_handler_add(E_EVENT_CLIENT_FOCUS_IN,
422 _e_gesture_cb_client_focus_in, NULL));
424 gesture->hooks = eina_list_append(gesture->hooks,
425 e_client_hook_add(E_CLIENT_HOOK_AUX_HINT_CHANGE,
426 _e_gesture_cb_aux_hint_change, NULL));
430 _e_gesture_deinit_handlers(void)
432 Ecore_Event_Handler *event_handler;
435 ecore_event_filter_del(gesture->ef_handler);
437 EINA_LIST_FREE(gesture->handlers, event_handler)
439 ecore_event_handler_del(event_handler);
442 EINA_LIST_FREE(gesture->hooks, hook)
444 e_client_hook_del(hook);
448 static E_Gesture_Config_Data *
449 _e_gesture_init(E_Module *m)
451 E_Gesture_Config_Data *gconfig = NULL;
452 gesture = E_NEW(E_Gesture, 1);
456 GTERR("Failed to allocate memory for gesture !\n");
462 GTERR("Failed to initialize gesture module ! (e_comp == NULL)\n");
466 /* Add filtering mechanism
467 * FIXME: Add handlers after first gesture is grabbed
469 _e_gesture_init_handlers();
472 gconfig = E_NEW(E_Gesture_Config_Data, 1);
473 EINA_SAFETY_ON_NULL_GOTO(gconfig, err);
476 e_gesture_conf_init(gconfig);
477 EINA_SAFETY_ON_NULL_GOTO(gconfig->conf, err);
478 gesture->config = gconfig;
480 GTDBG("config value\n");
481 GTDBG("keyboard: %s, time_done: %lf, time_begin: %lf\n", gconfig->conf->key_device_name, gconfig->conf->edge_swipe.time_done, gconfig->conf->edge_swipe.time_begin);
482 GTDBG("area_offset: %d, min_length: %d, max_length: %d\n", gconfig->conf->edge_swipe.area_offset, gconfig->conf->edge_swipe.min_length, gconfig->conf->edge_swipe.max_length);
483 GTDBG("compose key: %d, back: %d, default: %d\n", gconfig->conf->edge_swipe.compose_key, gconfig->conf->edge_swipe.back_key, gconfig->conf->edge_swipe.default_enable_back);
485 gesture->global = wl_global_create(e_comp_wl->wl.disp, &tizen_gesture_interface, 1, gesture, _e_gesture_cb_bind);
486 if (!gesture->global)
488 GTERR("Failed to create global !\n");
492 gesture->gesture_filter = E_GESTURE_TYPE_MAX;
494 gesture->gesture_events.edge_swipes.event_keep = gconfig->conf->edge_swipe.event_keep;
495 if (gconfig->conf->edge_swipe.default_enable_back)
497 gesture->grabbed_gesture |= TIZEN_GESTURE_TYPE_EDGE_SWIPE;
498 gesture->gesture_events.edge_swipes.fingers[1].enabled = EINA_TRUE;
499 gesture->gesture_events.edge_swipes.fingers[1].edge[E_GESTURE_EDGE_TOP].client = (void *)0x1;
500 gesture->gesture_events.edge_swipes.fingers[1].edge[E_GESTURE_EDGE_TOP].res = (void *)0x1;
501 gesture->gesture_events.edge_swipes.enabled_edge |= TIZEN_GESTURE_EDGE_TOP;
502 if (gesture->gesture_events.edge_swipes.event_keep)
504 gesture->event_state = E_GESTURE_EVENT_STATE_KEEP;
508 e_gesture_device_keydev_set(gesture->config->conf->key_device_name);
509 gesture->enable = EINA_TRUE;
514 if (gconfig) e_gesture_conf_deinit(gconfig);
515 if (gesture && gesture->ef_handler) ecore_event_filter_del(gesture->ef_handler);
516 if (gesture) E_FREE(gesture);
522 e_modapi_init(E_Module *m)
524 return _e_gesture_init(m);
528 e_modapi_shutdown(E_Module *m)
530 E_Gesture_Config_Data *gconfig = m->data;
531 e_gesture_conf_deinit(gconfig);
532 e_gesture_device_shutdown();
533 _e_gesture_deinit_handlers();
538 e_modapi_save(E_Module *m)
540 /* Save something to be kept */
541 E_Gesture_Config_Data *gconfig = m->data;
542 e_config_domain_save("module.gesture",
549 _e_gesture_wl_client_cb_destroy(struct wl_listener *l, void *data)
551 struct wl_client *client = data;
553 Eina_List *l_list, *l_next;
554 E_Gesture_Grabbed_Client *client_data;
556 if (gesture->grabbed_gesture & TIZEN_GESTURE_TYPE_EDGE_SWIPE)
558 for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
560 for (j = 0; j < E_GESTURE_EDGE_MAX+1; j++)
562 if (gesture->gesture_events.edge_swipes.fingers[i].edge[j].client == client)
564 gesture->gesture_events.edge_swipes.fingers[i].edge[j].client = NULL;
565 gesture->gesture_events.edge_swipes.fingers[i].edge[j].res = NULL;
570 for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
572 for (j = 0; j < E_GESTURE_EDGE_MAX+1; j++)
574 if (gesture->gesture_events.edge_swipes.fingers[i].edge[j].client)
579 gesture->gesture_events.edge_swipes.fingers[i].enabled = EINA_FALSE;
581 gesture->grabbed_gesture &= ~TIZEN_GESTURE_TYPE_EDGE_SWIPE;
587 EINA_LIST_FOREACH_SAFE(gesture->grab_client_list, l_list, l_next, client_data)
589 if (client_data->client == client)
591 gesture->grab_client_list = eina_list_remove(gesture->grab_client_list, client_data);
598 e_gesture_event_filter_enable(Eina_Bool enabled)
600 if (enabled && !gesture->enable)
602 GTINF("Gestures will be enabled by for now.\n");
603 gesture->enable = EINA_TRUE;
605 else if (!enabled && gesture->enable)
607 GTINF("Gestures will be enabled from now.\n");
608 gesture->enable = EINA_FALSE;