3 /* local subsystem functions */
4 static Eina_Bool _e_bindings_mapping_change_event_cb(void *data, int type, void *event);
6 static void _e_bindings_mouse_free(E_Binding_Mouse *bind);
7 static void _e_bindings_key_free(E_Binding_Key *bind);
8 static void _e_bindings_edge_free(E_Binding_Edge *bind);
9 static void _e_bindings_signal_free(E_Binding_Signal *bind);
10 static void _e_bindings_wheel_free(E_Binding_Wheel *bind);
11 static void _e_bindings_acpi_free(E_Binding_Acpi *bind);
12 static int _e_bindings_context_match(E_Binding_Context bctxt, E_Binding_Context ctxt);
13 static E_Binding_Modifier _e_bindings_modifiers(unsigned int modifiers);
14 static int _e_ecore_modifiers(E_Binding_Modifier modifiers);
15 static Eina_Bool _e_bindings_edge_cb_timer(void *data);
17 /* local subsystem globals */
19 static Ecore_Event_Handler *mapping_handler = NULL;
21 static Eina_List *mouse_bindings = NULL;
22 static Eina_List *key_bindings = NULL;
23 static Eina_List *edge_bindings = NULL;
24 static Eina_List *signal_bindings = NULL;
25 static Eina_List *wheel_bindings = NULL;
26 static Eina_List *acpi_bindings = NULL;
27 static int _e_bindings_mapping_change_enabled = 1;
29 typedef struct _E_Binding_Edge_Data E_Binding_Edge_Data;
31 struct _E_Binding_Edge_Data
34 E_Event_Zone_Edge *ev;
39 /* externally accessible functions */
44 E_Config_Binding_Signal *ebs;
45 E_Config_Binding_Mouse *ebm;
46 E_Config_Binding_Wheel *ebw;
47 E_Config_Binding_Edge *ebe;
48 E_Config_Binding_Key *ebk;
49 E_Config_Binding_Acpi *eba;
52 mapping_handler = ecore_event_handler_add
53 (ECORE_X_EVENT_MAPPING_CHANGE, _e_bindings_mapping_change_event_cb, NULL);
55 EINA_LIST_FOREACH(e_config->mouse_bindings, l, ebm)
56 e_bindings_mouse_add(ebm->context, ebm->button, ebm->modifiers,
57 ebm->any_mod, ebm->action, ebm->params);
59 EINA_LIST_FOREACH(e_config->key_bindings, l, ebk)
60 e_bindings_key_add(ebk->context, ebk->key, ebk->modifiers,
61 ebk->any_mod, ebk->action, ebk->params);
63 EINA_LIST_FOREACH(e_config->edge_bindings, l, ebe)
64 e_bindings_edge_add(ebe->context, ebe->edge, ebe->modifiers,
65 ebe->any_mod, ebe->action, ebe->params, ebe->delay);
67 EINA_LIST_FOREACH(e_config->signal_bindings, l, ebs)
69 e_bindings_signal_add(ebs->context, ebs->signal, ebs->source, ebs->modifiers,
70 ebs->any_mod, ebs->action, ebs->params);
71 /* FIXME: Can this be solved in a generic way? */
72 /* FIXME: Only change cursor if action is allowed! */
73 if ((ebs->action) && (ebs->signal) && (ebs->source) &&
74 (!strcmp(ebs->action, "window_resize")) &&
75 (!strncmp(ebs->signal, "mouse,down,", 11)) &&
76 (!strncmp(ebs->source, "e.event.resize.", 15)))
80 snprintf(params, sizeof(params), "resize_%s", ebs->params);
81 e_bindings_signal_add(ebs->context, "mouse,in", ebs->source, ebs->modifiers,
82 ebs->any_mod, "pointer_resize_push", params);
83 e_bindings_signal_add(ebs->context, "mouse,out", ebs->source, ebs->modifiers,
84 ebs->any_mod, "pointer_resize_pop", params);
88 EINA_LIST_FOREACH(e_config->wheel_bindings, l, ebw)
89 e_bindings_wheel_add(ebw->context, ebw->direction, ebw->z, ebw->modifiers,
90 ebw->any_mod, ebw->action, ebw->params);
92 EINA_LIST_FOREACH(e_config->acpi_bindings, l, eba)
93 e_bindings_acpi_add(eba->context, eba->type, eba->status,
94 eba->action, eba->params);
100 e_bindings_shutdown(void)
102 E_FREE_LIST(mouse_bindings, _e_bindings_mouse_free);
103 E_FREE_LIST(key_bindings, _e_bindings_key_free);
104 E_FREE_LIST(edge_bindings, _e_bindings_edge_free);
105 E_FREE_LIST(signal_bindings, _e_bindings_signal_free);
106 E_FREE_LIST(wheel_bindings, _e_bindings_wheel_free);
107 E_FREE_LIST(acpi_bindings, _e_bindings_acpi_free);
111 ecore_event_handler_del(mapping_handler);
112 mapping_handler = NULL;
119 e_bindings_signal_reset(void)
121 E_Config_Binding_Signal *ebs;
123 E_FREE_LIST(signal_bindings, _e_bindings_signal_free);
125 EINA_LIST_FOREACH(e_config->signal_bindings, l, ebs)
127 e_bindings_signal_add(ebs->context, ebs->signal, ebs->source, ebs->modifiers,
128 ebs->any_mod, ebs->action, ebs->params);
129 /* FIXME: Can this be solved in a generic way? */
130 /* FIXME: Only change cursor if action is allowed! */
131 if ((ebs->action) && (ebs->signal) && (ebs->source) &&
132 (!strcmp(ebs->action, "window_resize")) &&
133 (!strncmp(ebs->signal, "mouse,down,", 11)) &&
134 (!strncmp(ebs->source, "e.event.resize.", 15)))
138 snprintf(params, sizeof(params), "resize_%s", ebs->params);
139 e_bindings_signal_add(ebs->context, "mouse,in", ebs->source, ebs->modifiers,
140 ebs->any_mod, "pointer_resize_push", params);
141 e_bindings_signal_add(ebs->context, "mouse,out", ebs->source, ebs->modifiers,
142 ebs->any_mod, "pointer_resize_pop", params);
148 e_bindings_acpi_reset(void)
150 E_Config_Binding_Acpi *eba;
153 E_FREE_LIST(acpi_bindings, _e_bindings_acpi_free);
155 EINA_LIST_FOREACH(e_config->acpi_bindings, l, eba)
156 e_bindings_acpi_add(eba->context, eba->type, eba->status,
157 eba->action, eba->params);
161 e_bindings_wheel_reset(void)
163 E_Config_Binding_Wheel *ebw;
166 E_FREE_LIST(wheel_bindings, _e_bindings_wheel_free);
168 EINA_LIST_FOREACH(e_config->wheel_bindings, l, ebw)
169 e_bindings_wheel_add(ebw->context, ebw->direction, ebw->z, ebw->modifiers,
170 ebw->any_mod, ebw->action, ebw->params);
174 e_bindings_edge_reset(void)
176 E_Config_Binding_Edge *ebe;
179 E_FREE_LIST(edge_bindings, _e_bindings_edge_free);
181 EINA_LIST_FOREACH(e_config->edge_bindings, l, ebe)
182 e_bindings_edge_add(ebe->context, ebe->edge, ebe->modifiers,
183 ebe->any_mod, ebe->action, ebe->params, ebe->delay);
187 e_bindings_mouse_reset(void)
189 E_Config_Binding_Mouse *ebm;
192 E_FREE_LIST(mouse_bindings, _e_bindings_mouse_free);
194 EINA_LIST_FOREACH(e_config->mouse_bindings, l, ebm)
195 e_bindings_mouse_add(ebm->context, ebm->button, ebm->modifiers,
196 ebm->any_mod, ebm->action, ebm->params);
201 e_bindings_key_reset(void)
203 E_Config_Binding_Key *ebk;
206 e_managers_keys_ungrab();
207 E_FREE_LIST(key_bindings, _e_bindings_key_free);
209 EINA_LIST_FOREACH(e_config->key_bindings, l, ebk)
210 e_bindings_key_add(ebk->context, ebk->key, ebk->modifiers,
211 ebk->any_mod, ebk->action, ebk->params);
212 e_managers_keys_grab();
216 e_bindings_reset(void)
218 e_bindings_signal_reset();
219 e_bindings_mouse_reset();
220 e_bindings_wheel_reset();
221 e_bindings_edge_reset();
222 e_bindings_key_reset();
226 e_bindings_mouse_add(E_Binding_Context ctxt, int button, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
228 E_Binding_Mouse *binding;
230 binding = calloc(1, sizeof(E_Binding_Mouse));
231 binding->ctxt = ctxt;
232 binding->button = button;
234 binding->any_mod = any_mod;
235 if (action) binding->action = eina_stringshare_add(action);
236 if (params) binding->params = eina_stringshare_add(params);
237 mouse_bindings = eina_list_append(mouse_bindings, binding);
241 e_bindings_mouse_del(E_Binding_Context ctxt, int button, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
243 E_Binding_Mouse *binding;
246 EINA_LIST_FOREACH(mouse_bindings, l, binding)
248 if ((binding->ctxt == ctxt) &&
249 (binding->button == button) &&
250 (binding->mod == mod) &&
251 (binding->any_mod == any_mod) &&
252 (((binding->action) && (action) && (!strcmp(binding->action, action))) ||
253 ((!binding->action) && (!action))) &&
254 (((binding->params) && (params) && (!strcmp(binding->params, params))) ||
255 ((!binding->params) && (!params))))
257 _e_bindings_mouse_free(binding);
258 mouse_bindings = eina_list_remove_list(mouse_bindings, l);
265 e_bindings_mouse_grab(E_Binding_Context ctxt, Ecore_X_Window win)
267 E_Binding_Mouse *binding;
270 EINA_LIST_FOREACH(mouse_bindings, l, binding)
272 if (_e_bindings_context_match(binding->ctxt, ctxt))
274 ecore_x_window_button_grab(win, binding->button,
275 ECORE_X_EVENT_MASK_MOUSE_DOWN |
276 ECORE_X_EVENT_MASK_MOUSE_UP |
277 ECORE_X_EVENT_MASK_MOUSE_MOVE,
278 _e_ecore_modifiers(binding->mod),
285 e_bindings_mouse_ungrab(E_Binding_Context ctxt, Ecore_X_Window win)
287 E_Binding_Mouse *binding;
290 EINA_LIST_FOREACH(mouse_bindings, l, binding)
292 if (_e_bindings_context_match(binding->ctxt, ctxt))
294 ecore_x_window_button_ungrab(win, binding->button,
295 _e_ecore_modifiers(binding->mod), binding->any_mod);
301 e_bindings_mouse_down_find(E_Binding_Context ctxt, E_Object *obj __UNUSED__, Ecore_Event_Mouse_Button *ev, E_Binding_Mouse **bind_ret)
303 E_Binding_Modifier mod = 0;
304 E_Binding_Mouse *binding;
307 mod = _e_bindings_modifiers(ev->modifiers);
308 EINA_LIST_FOREACH(mouse_bindings, l, binding)
310 if ((binding->button == (int) ev->buttons) &&
311 ((binding->any_mod) || (binding->mod == mod)))
313 if (_e_bindings_context_match(binding->ctxt, ctxt))
317 act = e_action_find(binding->action);
318 if (bind_ret) *bind_ret = binding;
327 e_bindings_mouse_down_event_handle(E_Binding_Context ctxt, E_Object *obj, Ecore_Event_Mouse_Button *ev)
330 E_Binding_Mouse *binding;
332 act = e_bindings_mouse_down_find(ctxt, obj, ev, &binding);
335 if (act->func.go_mouse)
336 act->func.go_mouse(obj, binding->params, ev);
337 else if (act->func.go)
338 act->func.go(obj, binding->params);
345 e_bindings_mouse_up_find(E_Binding_Context ctxt, E_Object *obj __UNUSED__, Ecore_Event_Mouse_Button *ev, E_Binding_Mouse **bind_ret)
347 E_Binding_Modifier mod = 0;
348 E_Binding_Mouse *binding;
351 mod = _e_bindings_modifiers(ev->modifiers);
352 EINA_LIST_FOREACH(mouse_bindings, l, binding)
354 if ((binding->button == (int) ev->buttons) &&
355 ((binding->any_mod) || (binding->mod == mod)))
357 if (_e_bindings_context_match(binding->ctxt, ctxt))
361 act = e_action_find(binding->action);
362 if (bind_ret) *bind_ret = binding;
371 e_bindings_mouse_up_event_handle(E_Binding_Context ctxt, E_Object *obj, Ecore_Event_Mouse_Button *ev)
374 E_Binding_Mouse *binding;
376 act = e_bindings_mouse_up_find(ctxt, obj, ev, &binding);
379 if (act->func.end_mouse)
380 act->func.end_mouse(obj, binding->params, ev);
381 else if (act->func.end)
382 act->func.end(obj, binding->params);
389 e_bindings_key_add(E_Binding_Context ctxt, const char *key, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
391 E_Binding_Key *binding;
393 binding = calloc(1, sizeof(E_Binding_Key));
394 binding->ctxt = ctxt;
395 binding->key = eina_stringshare_add(key);
397 binding->any_mod = any_mod;
398 if (action) binding->action = eina_stringshare_add(action);
399 if (params) binding->params = eina_stringshare_add(params);
400 key_bindings = eina_list_append(key_bindings, binding);
404 e_bindings_key_get(const char *action)
406 E_Binding_Key *binding;
409 EINA_LIST_FOREACH(key_bindings, l, binding)
411 if (binding->action && action && !strcmp(action, binding->action))
418 e_bindings_key_find(const char *key, E_Binding_Modifier mod, int any_mod)
420 E_Binding_Key *binding;
423 if (!key) return NULL;
425 EINA_LIST_FOREACH(key_bindings, l, binding)
427 if ((binding->key) && (!strcmp(key, binding->key)) &&
428 (binding->mod == mod) && (binding->any_mod == any_mod))
436 e_bindings_key_del(E_Binding_Context ctxt, const char *key, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
438 E_Binding_Key *binding;
441 EINA_LIST_FOREACH(key_bindings, l, binding)
443 if ((binding->ctxt == ctxt) &&
444 (key) && (binding->key) && (!strcmp(binding->key, key)) &&
445 (binding->mod == mod) &&
446 (binding->any_mod == any_mod) &&
447 (((binding->action) && (action) && (!strcmp(binding->action, action))) ||
448 ((!binding->action) && (!action))) &&
449 (((binding->params) && (params) && (!strcmp(binding->params, params))) ||
450 ((!binding->params) && (!params))))
452 _e_bindings_key_free(binding);
453 key_bindings = eina_list_remove_list(key_bindings, l);
460 e_bindings_key_grab(E_Binding_Context ctxt, Ecore_X_Window win)
462 E_Binding_Key *binding;
465 EINA_LIST_FOREACH(key_bindings, l, binding)
467 if (_e_bindings_context_match(binding->ctxt, ctxt))
469 ecore_x_window_key_grab(win, binding->key,
470 _e_ecore_modifiers(binding->mod), binding->any_mod);
476 e_bindings_key_ungrab(E_Binding_Context ctxt, Ecore_X_Window win)
478 E_Binding_Key *binding;
481 EINA_LIST_FOREACH(key_bindings, l, binding)
483 if (_e_bindings_context_match(binding->ctxt, ctxt))
485 ecore_x_window_key_ungrab(win, binding->key,
486 _e_ecore_modifiers(binding->mod), binding->any_mod);
492 e_bindings_key_down_event_handle(E_Binding_Context ctxt, E_Object *obj, Ecore_Event_Key *ev)
494 E_Binding_Modifier mod = 0;
495 E_Binding_Key *binding;
498 mod = _e_bindings_modifiers(ev->modifiers);
499 EINA_LIST_FOREACH(key_bindings, l, binding)
501 if ((binding->key) && (!strcmp(binding->key, ev->keyname)) &&
502 ((binding->any_mod) || (binding->mod == mod)))
504 if (_e_bindings_context_match(binding->ctxt, ctxt))
508 act = e_action_find(binding->action);
511 if (act->func.go_key)
512 act->func.go_key(obj, binding->params, ev);
513 else if (act->func.go)
514 act->func.go(obj, binding->params);
525 e_bindings_key_up_event_handle(E_Binding_Context ctxt, E_Object *obj, Ecore_Event_Key *ev)
527 E_Binding_Modifier mod = 0;
528 E_Binding_Key *binding;
531 mod = _e_bindings_modifiers(ev->modifiers);
532 EINA_LIST_FOREACH(key_bindings, l, binding)
534 if ((binding->key) && (!strcmp(binding->key, ev->keyname)) &&
535 ((binding->any_mod) || (binding->mod == mod)))
537 if (_e_bindings_context_match(binding->ctxt, ctxt))
541 act = e_action_find(binding->action);
544 if (act->func.end_key)
545 act->func.end_key(obj, binding->params, ev);
546 else if (act->func.end)
547 act->func.end(obj, binding->params);
558 e_bindings_key_down_event_find(E_Binding_Context ctxt, Ecore_Event_Key *ev)
560 E_Binding_Modifier mod = 0;
561 E_Binding_Key *binding;
564 mod = _e_bindings_modifiers(ev->modifiers);
565 EINA_LIST_FOREACH(key_bindings, l, binding)
567 if ((binding->key) && (!strcmp(binding->key, ev->keyname)) &&
568 ((binding->any_mod) || (binding->mod == mod)))
570 if (_e_bindings_context_match(binding->ctxt, ctxt))
574 act = e_action_find(binding->action);
583 e_bindings_key_up_event_find(E_Binding_Context ctxt, Ecore_Event_Key *ev)
585 E_Binding_Modifier mod = 0;
586 E_Binding_Key *binding;
589 mod = _e_bindings_modifiers(ev->modifiers);
590 EINA_LIST_FOREACH(key_bindings, l, binding)
592 if ((binding->key) && (!strcmp(binding->key, ev->keyname)) &&
593 ((binding->any_mod) || (binding->mod == mod)))
595 if (_e_bindings_context_match(binding->ctxt, ctxt))
599 act = e_action_find(binding->action);
608 e_bindings_edge_add(E_Binding_Context ctxt, E_Zone_Edge edge, E_Binding_Modifier mod, int any_mod, const char *action, const char *params, float delay)
610 E_Binding_Edge *binding;
612 binding = calloc(1, sizeof(E_Binding_Edge));
613 binding->ctxt = ctxt;
614 binding->edge = edge;
616 binding->any_mod = any_mod;
617 binding->delay = delay;
618 if (action) binding->action = eina_stringshare_add(action);
619 if (params) binding->params = eina_stringshare_add(params);
620 edge_bindings = eina_list_append(edge_bindings, binding);
622 e_zone_edge_new(edge);
626 e_bindings_edge_flippable_get(E_Zone_Edge edge)
628 E_Binding_Edge *binding;
631 EINA_LIST_FOREACH(edge_bindings, l, binding)
633 if ((binding->edge == edge) && (binding->action))
635 if ((!strcmp(binding->action, "desk_flip_in_direction")) ||
636 (!strcmp(binding->action, "desk_flip_by")))
644 e_bindings_edge_non_flippable_get(E_Zone_Edge edge)
646 E_Binding_Edge *binding;
649 EINA_LIST_FOREACH(edge_bindings, l, binding)
651 if ((binding->edge == edge) && (binding->action))
653 if ((!strcmp(binding->action, "desk_flip_in_direction")) ||
654 (!strcmp(binding->action, "desk_flip_by")))
662 EAPI E_Binding_Edge *
663 e_bindings_edge_get(const char *action, E_Zone_Edge edge, int click)
665 E_Binding_Edge *binding;
668 EINA_LIST_FOREACH(edge_bindings, l, binding)
670 if ((binding->edge == edge) &&
671 ((click && (binding->delay == -1.0 * click))
672 || (!click && (binding->delay >= 0.0))) &&
673 (binding->action) && (action) &&
674 (!strcmp(action, binding->action)))
681 e_bindings_edge_del(E_Binding_Context ctxt, E_Zone_Edge edge, E_Binding_Modifier mod, int any_mod, const char *action, const char *params, float delay)
683 E_Binding_Edge *binding;
687 EINA_LIST_FOREACH(edge_bindings, l, binding)
689 if (binding->edge == edge)
691 if ((binding->ctxt == ctxt) &&
692 (binding->mod == mod) &&
693 ((binding->delay * 1000) == (delay * 1000)) &&
694 (binding->any_mod == any_mod) &&
695 (((binding->action) && (action) && (!strcmp(binding->action, action))) ||
696 ((!binding->action) && (!action))) &&
697 (((binding->params) && (params) && (!strcmp(binding->params, params))) ||
698 ((!binding->params) && (!params))))
700 _e_bindings_edge_free(binding);
701 edge_bindings = eina_list_remove_list(edge_bindings, l);
708 e_zone_edge_free(edge);
712 e_bindings_edge_in_event_handle(E_Binding_Context ctxt, E_Object *obj, E_Event_Zone_Edge *ev)
714 E_Binding_Modifier mod = 0;
715 E_Binding_Edge *binding;
716 E_Desk *current = NULL;
717 E_Action *act = NULL;
720 current = e_desk_at_xy_get(ev->zone, ev->zone->desk_x_current, ev->zone->desk_y_current);
721 if (current->fullscreen_borders && (!e_config->fullscreen_flip)) return NULL;
723 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT;
724 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL;
725 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT;
726 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN;
727 EINA_LIST_FOREACH(edge_bindings, l, binding)
729 /* A value of <= -1.0 for the delay indicates it as a mouse-click binding on that edge */
730 if (((binding->edge == ev->edge)) && (binding->delay >= 0.0) &&
731 ((binding->any_mod) || (binding->mod == mod)))
733 if (_e_bindings_context_match(binding->ctxt, ctxt))
735 act = e_action_find(binding->action);
738 E_Binding_Edge_Data *ed = E_NEW(E_Binding_Edge_Data, 1);
739 E_Event_Zone_Edge *ev2 = E_NEW(E_Event_Zone_Edge, 1);
741 /* The original event will be freed before it can be
743 ev2->zone = ev->zone;
744 ev2->edge = ev->edge;
752 binding->timer = ecore_timer_add(((double) binding->delay), _e_bindings_edge_cb_timer, ed);
761 e_bindings_edge_out_event_handle(E_Binding_Context ctxt, E_Object *obj, E_Event_Zone_Edge *ev)
763 E_Binding_Modifier mod = 0;
764 E_Binding_Edge *binding;
765 E_Action *act = NULL;
768 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT;
769 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL;
770 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT;
771 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN;
772 EINA_LIST_FOREACH(edge_bindings, l, binding)
774 /* A value of <= -1.0 for the delay indicates it as a mouse-click binding on that edge */
775 if ((binding->edge == ev->edge) && (binding->delay >= 0.0) &&
776 ((binding->any_mod) || (binding->mod == mod)))
778 if (_e_bindings_context_match(binding->ctxt, ctxt))
782 E_Binding_Edge_Data *ed;
784 ed = ecore_timer_del(binding->timer);
791 binding->timer = NULL;
793 act = e_action_find(binding->action);
794 if (act && act->func.end)
795 act->func.end(obj, binding->params);
803 e_bindings_edge_down_event_handle(E_Binding_Context ctxt, E_Object *obj, E_Event_Zone_Edge *ev)
805 E_Binding_Modifier mod = 0;
806 E_Binding_Edge *binding;
807 E_Desk *current = NULL;
808 E_Action *act = NULL;
811 current = e_desk_at_xy_get(ev->zone, ev->zone->desk_x_current, ev->zone->desk_y_current);
812 if (current->fullscreen_borders && (!e_config->fullscreen_flip)) return NULL;
814 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT;
815 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL;
816 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT;
817 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN;
818 EINA_LIST_FOREACH(edge_bindings, l, binding)
820 if (((binding->edge == ev->edge)) && (binding->delay == -1.0 * ev->button) &&
821 ((binding->any_mod) || (binding->mod == mod)))
823 if (_e_bindings_context_match(binding->ctxt, ctxt))
825 act = e_action_find(binding->action);
828 if (act->func.go_edge)
829 act->func.go_edge(obj, binding->params, ev);
830 else if (act->func.go)
831 act->func.go(obj, binding->params);
840 e_bindings_edge_up_event_handle(E_Binding_Context ctxt, E_Object *obj, E_Event_Zone_Edge *ev)
842 E_Binding_Modifier mod = 0;
843 E_Binding_Edge *binding;
844 E_Action *act = NULL;
847 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT;
848 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL;
849 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT;
850 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN;
851 EINA_LIST_FOREACH(edge_bindings, l, binding)
853 if (((binding->edge == ev->edge)) && (binding->delay == -1.0 * ev->button) &&
854 ((binding->any_mod) || (binding->mod == mod)))
856 if (_e_bindings_context_match(binding->ctxt, ctxt))
858 act = e_action_find(binding->action);
859 if (act && act->func.end)
860 act->func.end(obj, binding->params);
868 e_bindings_signal_add(E_Binding_Context ctxt, const char *sig, const char *src, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
870 E_Binding_Signal *binding;
872 binding = calloc(1, sizeof(E_Binding_Signal));
873 binding->ctxt = ctxt;
874 if (sig) binding->sig = eina_stringshare_add(sig);
875 if (src) binding->src = eina_stringshare_add(src);
877 binding->any_mod = any_mod;
878 if (action) binding->action = eina_stringshare_add(action);
879 if (params) binding->params = eina_stringshare_add(params);
880 signal_bindings = eina_list_append(signal_bindings, binding);
884 e_bindings_signal_del(E_Binding_Context ctxt, const char *sig, const char *src, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
886 E_Binding_Signal *binding;
889 EINA_LIST_FOREACH(signal_bindings, l, binding)
891 if ((binding->ctxt == ctxt) &&
892 (((binding->sig) && (sig) && (!strcmp(binding->sig, sig))) ||
893 ((!binding->sig) && (!sig))) &&
894 (((binding->src) && (src) && (!strcmp(binding->src, src))) ||
895 ((!binding->src) && (!src))) &&
896 (binding->mod == mod) &&
897 (binding->any_mod == any_mod) &&
898 (((binding->action) && (action) && (!strcmp(binding->action, action))) ||
899 ((!binding->action) && (!action))) &&
900 (((binding->params) && (params) && (!strcmp(binding->params, params))) ||
901 ((!binding->params) && (!params))))
903 _e_bindings_signal_free(binding);
904 signal_bindings = eina_list_remove_list(signal_bindings, l);
911 e_bindings_signal_find(E_Binding_Context ctxt, E_Object *obj __UNUSED__, const char *sig, const char *src, E_Binding_Signal **bind_ret)
913 E_Binding_Modifier mod = 0;
914 E_Binding_Signal *binding;
917 if (strstr(sig, "MOD:Shift")) mod |= E_BINDING_MODIFIER_SHIFT;
918 if (strstr(sig, "MOD:Control")) mod |= E_BINDING_MODIFIER_CTRL;
919 if (strstr(sig, "MOD:Alt")) mod |= E_BINDING_MODIFIER_ALT;
920 if (strstr(sig, "MOD:Super")) mod |= E_BINDING_MODIFIER_WIN;
921 EINA_LIST_FOREACH(signal_bindings, l, binding)
923 if ((e_util_glob_match(sig, binding->sig)) &&
924 (e_util_glob_match(src, binding->src)) &&
925 ((binding->any_mod) || (binding->mod == mod)))
927 if (_e_bindings_context_match(binding->ctxt, ctxt))
931 act = e_action_find(binding->action);
932 if (bind_ret) *bind_ret = binding;
941 e_bindings_signal_handle(E_Binding_Context ctxt, E_Object *obj, const char *sig, const char *src)
944 E_Binding_Signal *binding;
946 if (sig[0] == 0) sig = NULL;
947 if (src[0] == 0) src = NULL;
948 act = e_bindings_signal_find(ctxt, obj, sig, src, &binding);
951 if (act->func.go_signal)
952 act->func.go_signal(obj, binding->params, sig, src);
953 else if (act->func.go)
954 act->func.go(obj, binding->params);
961 e_bindings_wheel_add(E_Binding_Context ctxt, int direction, int z, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
963 E_Binding_Wheel *binding;
965 binding = calloc(1, sizeof(E_Binding_Wheel));
966 binding->ctxt = ctxt;
967 binding->direction = direction;
970 binding->any_mod = any_mod;
971 if (action) binding->action = eina_stringshare_add(action);
972 if (params) binding->params = eina_stringshare_add(params);
973 wheel_bindings = eina_list_append(wheel_bindings, binding);
977 e_bindings_wheel_del(E_Binding_Context ctxt, int direction, int z, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
979 E_Binding_Wheel *binding;
982 EINA_LIST_FOREACH(wheel_bindings, l, binding)
984 if ((binding->ctxt == ctxt) &&
985 (binding->direction == direction) &&
987 (binding->mod == mod) &&
988 (binding->any_mod == any_mod) &&
989 (((binding->action) && (action) && (!strcmp(binding->action, action))) ||
990 ((!binding->action) && (!action))) &&
991 (((binding->params) && (params) && (!strcmp(binding->params, params))) ||
992 ((!binding->params) && (!params))))
994 _e_bindings_wheel_free(binding);
995 wheel_bindings = eina_list_remove_list(wheel_bindings, l);
1002 e_bindings_wheel_grab(E_Binding_Context ctxt, Ecore_X_Window win)
1004 E_Binding_Wheel *binding;
1007 EINA_LIST_FOREACH(wheel_bindings, l, binding)
1009 if (_e_bindings_context_match(binding->ctxt, ctxt))
1013 if (binding->direction == 0)
1015 if (binding->z < 0) button = 4;
1016 else if (binding->z > 0) button = 5;
1018 else if (binding->direction == 1)
1020 if (binding->z < 0) button = 6;
1021 else if (binding->z > 0) button = 7;
1024 ecore_x_window_button_grab(win, button,
1025 ECORE_X_EVENT_MASK_MOUSE_DOWN,
1026 _e_ecore_modifiers(binding->mod), binding->any_mod);
1032 e_bindings_wheel_ungrab(E_Binding_Context ctxt, Ecore_X_Window win)
1034 E_Binding_Wheel *binding;
1037 EINA_LIST_FOREACH(wheel_bindings, l, binding)
1039 if (_e_bindings_context_match(binding->ctxt, ctxt))
1043 if (binding->direction == 0)
1045 if (binding->z < 0) button = 4;
1046 else if (binding->z > 0) button = 5;
1048 else if (binding->direction == 1)
1050 if (binding->z < 0) button = 6;
1051 else if (binding->z > 0) button = 7;
1054 ecore_x_window_button_ungrab(win, button,
1055 _e_ecore_modifiers(binding->mod), binding->any_mod);
1061 e_bindings_wheel_find(E_Binding_Context ctxt, E_Object *obj __UNUSED__, Ecore_Event_Mouse_Wheel *ev, E_Binding_Wheel **bind_ret)
1063 E_Binding_Modifier mod = 0;
1064 E_Binding_Wheel *binding;
1067 mod = _e_bindings_modifiers(ev->modifiers);
1068 EINA_LIST_FOREACH(wheel_bindings, l, binding)
1070 if ((binding->direction == ev->direction) &&
1071 (((binding->z < 0) && (ev->z < 0)) || ((binding->z > 0) && (ev->z > 0))) &&
1072 ((binding->any_mod) || (binding->mod == mod)))
1074 if (_e_bindings_context_match(binding->ctxt, ctxt))
1078 act = e_action_find(binding->action);
1079 if (bind_ret) *bind_ret = binding;
1088 e_bindings_wheel_event_handle(E_Binding_Context ctxt, E_Object *obj, Ecore_Event_Mouse_Wheel *ev)
1091 E_Binding_Wheel *binding;
1093 act = e_bindings_wheel_find(ctxt, obj, ev, &binding);
1096 if (act->func.go_wheel)
1097 act->func.go_wheel(obj, binding->params, ev);
1098 else if (act->func.go)
1099 act->func.go(obj, binding->params);
1106 e_bindings_acpi_add(E_Binding_Context ctxt, int type, int status, const char *action, const char *params)
1108 E_Binding_Acpi *binding;
1110 binding = E_NEW(E_Binding_Acpi, 1);
1111 binding->ctxt = ctxt;
1112 binding->type = type;
1113 binding->status = status;
1114 if (action) binding->action = eina_stringshare_add(action);
1115 if (params) binding->params = eina_stringshare_add(params);
1116 acpi_bindings = eina_list_append(acpi_bindings, binding);
1120 e_bindings_acpi_del(E_Binding_Context ctxt, int type, int status, const char *action, const char *params)
1122 E_Binding_Acpi *binding;
1125 EINA_LIST_FOREACH(acpi_bindings, l, binding)
1127 if ((binding->ctxt == ctxt) &&
1128 (binding->type == type) && (binding->status == status) &&
1129 (((binding->action) && (action) && (!strcmp(binding->action, action))) ||
1130 ((!binding->action) && (!action))) &&
1131 (((binding->params) && (params) && (!strcmp(binding->params, params))) ||
1132 ((!binding->params) && (!params))))
1134 _e_bindings_acpi_free(binding);
1135 acpi_bindings = eina_list_remove_list(acpi_bindings, l);
1142 e_bindings_acpi_find(E_Binding_Context ctxt, E_Object *obj __UNUSED__, E_Event_Acpi *ev, E_Binding_Acpi **bind_ret)
1144 E_Binding_Acpi *binding;
1147 EINA_LIST_FOREACH(acpi_bindings, l, binding)
1149 if (binding->type == ev->type)
1151 /* if binding status is -1, then we don't compare event status */
1152 if (binding->status != -1)
1154 /* binding status is set to something, compare event status */
1155 if (binding->status != ev->status) continue;
1157 if (_e_bindings_context_match(binding->ctxt, ctxt))
1161 act = e_action_find(binding->action);
1162 if (bind_ret) *bind_ret = binding;
1171 e_bindings_acpi_event_handle(E_Binding_Context ctxt, E_Object *obj, E_Event_Acpi *ev)
1174 E_Binding_Acpi *binding;
1176 act = e_bindings_acpi_find(ctxt, obj, ev, &binding);
1179 if (act->func.go_acpi)
1180 act->func.go_acpi(obj, binding->params, ev);
1181 else if (act->func.go)
1182 act->func.go(obj, binding->params);
1189 e_bindings_mapping_change_enable(Eina_Bool enable)
1192 _e_bindings_mapping_change_enabled++;
1194 _e_bindings_mapping_change_enabled--;
1195 if (_e_bindings_mapping_change_enabled < 0)
1196 _e_bindings_mapping_change_enabled = 0;
1199 /* local subsystem functions */
1201 _e_bindings_mapping_change_event_cb(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
1203 if (!_e_bindings_mapping_change_enabled) return ECORE_CALLBACK_RENEW;
1204 e_managers_keys_ungrab();
1205 e_border_button_bindings_ungrab_all();
1206 e_border_button_bindings_grab_all();
1207 e_managers_keys_grab();
1208 return ECORE_CALLBACK_PASS_ON;
1212 _e_bindings_mouse_free(E_Binding_Mouse *binding)
1214 if (binding->action) eina_stringshare_del(binding->action);
1215 if (binding->params) eina_stringshare_del(binding->params);
1220 _e_bindings_key_free(E_Binding_Key *binding)
1222 if (binding->key) eina_stringshare_del(binding->key);
1223 if (binding->action) eina_stringshare_del(binding->action);
1224 if (binding->params) eina_stringshare_del(binding->params);
1229 _e_bindings_edge_free(E_Binding_Edge *binding)
1231 if (binding->action) eina_stringshare_del(binding->action);
1232 if (binding->params) eina_stringshare_del(binding->params);
1235 E_Binding_Edge_Data *ed;
1237 ed = ecore_timer_del(binding->timer);
1244 _e_bindings_signal_free(E_Binding_Signal *binding)
1246 if (binding->sig) eina_stringshare_del(binding->sig);
1247 if (binding->src) eina_stringshare_del(binding->src);
1248 if (binding->action) eina_stringshare_del(binding->action);
1249 if (binding->params) eina_stringshare_del(binding->params);
1254 _e_bindings_wheel_free(E_Binding_Wheel *binding)
1256 if (binding->action) eina_stringshare_del(binding->action);
1257 if (binding->params) eina_stringshare_del(binding->params);
1262 _e_bindings_acpi_free(E_Binding_Acpi *binding)
1264 if (binding->action) eina_stringshare_del(binding->action);
1265 if (binding->params) eina_stringshare_del(binding->params);
1270 _e_bindings_context_match(E_Binding_Context bctxt, E_Binding_Context ctxt)
1272 if (bctxt == E_BINDING_CONTEXT_ANY &&
1273 !(ctxt == E_BINDING_CONTEXT_ZONE)) return 1;
1274 if (ctxt == E_BINDING_CONTEXT_UNKNOWN) return 0;
1275 if (bctxt == ctxt) return 1;
1279 static E_Binding_Modifier
1280 _e_bindings_modifiers(unsigned int modifiers)
1282 E_Binding_Modifier mod = 0;
1284 if (modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT;
1285 if (modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL;
1286 if (modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT;
1287 if (modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN;
1288 /* FIXME: there is a good reason numlock was ignored. sometimes people
1289 * have it on, sometimes they don't, and often they have no idea. waaaay
1290 * back in E 0.1->0.13 or so days this caused issues thus numlock,
1291 * scrollock and capslock are not usable modifiers.
1293 * if we REALLY want to be able to use numlock we need to add more binding
1294 * flags and config that says "REALLY pay attention to numlock for this
1295 * binding" field in the binding (like there is a "any_mod" flag - we need a
1296 * "num_lock_respect" field)
1298 * also it should be an E_BINDING_MODIFIER_LOCK_NUM as the ecore lock flag
1299 * may vary from system to system as different xservers may have differing
1300 * modifier masks for numlock (it is queried at startup).
1302 if (ev->modifiers & ECORE_X_LOCK_NUM) mod |= ECORE_X_LOCK_NUM;
1309 _e_ecore_modifiers(E_Binding_Modifier modifiers)
1313 if (modifiers & E_BINDING_MODIFIER_SHIFT) mod |= ECORE_EVENT_MODIFIER_SHIFT;
1314 if (modifiers & E_BINDING_MODIFIER_CTRL) mod |= ECORE_EVENT_MODIFIER_CTRL;
1315 if (modifiers & E_BINDING_MODIFIER_ALT) mod |= ECORE_EVENT_MODIFIER_ALT;
1316 if (modifiers & E_BINDING_MODIFIER_WIN) mod |= ECORE_EVENT_MODIFIER_WIN;
1317 /* see comment in e_bindings on numlock
1318 if (modifiers & ECORE_X_LOCK_NUM) mod |= ECORE_X_LOCK_NUM;
1325 _e_bindings_edge_cb_timer(void *data)
1327 E_Binding_Edge_Data *ed;
1328 E_Event_Zone_Edge *ev;
1329 E_Binding_Edge *binding;
1341 if (act->func.go_edge)
1342 act->func.go_edge(obj, binding->params, ev);
1343 else if (act->func.go)
1344 act->func.go(obj, binding->params);
1346 binding->timer = NULL;
1348 /* Duplicate event */
1351 return ECORE_CALLBACK_CANCEL;