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;
28 typedef struct _E_Binding_Edge_Data E_Binding_Edge_Data;
30 struct _E_Binding_Edge_Data
33 E_Event_Zone_Edge *ev;
38 /* externally accessible functions */
43 E_Config_Binding_Signal *ebs;
44 E_Config_Binding_Mouse *ebm;
45 E_Config_Binding_Wheel *ebw;
46 E_Config_Binding_Edge *ebe;
47 E_Config_Binding_Key *ebk;
48 E_Config_Binding_Acpi *eba;
51 mapping_handler = ecore_event_handler_add
52 (ECORE_X_EVENT_MAPPING_CHANGE, _e_bindings_mapping_change_event_cb, NULL);
54 EINA_LIST_FOREACH(e_config->mouse_bindings, l, ebm)
55 e_bindings_mouse_add(ebm->context, ebm->button, ebm->modifiers,
56 ebm->any_mod, ebm->action, ebm->params);
58 EINA_LIST_FOREACH(e_config->key_bindings, l, ebk)
59 e_bindings_key_add(ebk->context, ebk->key, ebk->modifiers,
60 ebk->any_mod, ebk->action, ebk->params);
62 EINA_LIST_FOREACH(e_config->edge_bindings, l, ebe)
63 e_bindings_edge_add(ebe->context, ebe->edge, ebe->modifiers,
64 ebe->any_mod, ebe->action, ebe->params, ebe->delay);
66 EINA_LIST_FOREACH(e_config->signal_bindings, l, ebs)
68 e_bindings_signal_add(ebs->context, ebs->signal, ebs->source, ebs->modifiers,
69 ebs->any_mod, ebs->action, ebs->params);
70 /* FIXME: Can this be solved in a generic way? */
71 /* FIXME: Only change cursor if action is allowed! */
72 if ((ebs->action) && (ebs->signal) && (ebs->source) &&
73 (!strcmp(ebs->action, "window_resize")) &&
74 (!strncmp(ebs->signal, "mouse,down,", 11)) &&
75 (!strncmp(ebs->source, "e.event.resize.", 15)))
79 snprintf(params, sizeof(params), "resize_%s", ebs->params);
80 e_bindings_signal_add(ebs->context, "mouse,in", ebs->source, ebs->modifiers,
81 ebs->any_mod, "pointer_resize_push", params);
82 e_bindings_signal_add(ebs->context, "mouse,out", ebs->source, ebs->modifiers,
83 ebs->any_mod, "pointer_resize_pop", params);
87 EINA_LIST_FOREACH(e_config->wheel_bindings, l, ebw)
88 e_bindings_wheel_add(ebw->context, ebw->direction, ebw->z, ebw->modifiers,
89 ebw->any_mod, ebw->action, ebw->params);
91 EINA_LIST_FOREACH(e_config->acpi_bindings, l, eba)
92 e_bindings_acpi_add(eba->context, eba->type, eba->status,
93 eba->action, eba->params);
99 e_bindings_shutdown(void)
101 E_FREE_LIST(mouse_bindings, _e_bindings_mouse_free);
102 E_FREE_LIST(key_bindings, _e_bindings_key_free);
103 E_FREE_LIST(edge_bindings, _e_bindings_edge_free);
104 E_FREE_LIST(signal_bindings, _e_bindings_signal_free);
105 E_FREE_LIST(wheel_bindings, _e_bindings_wheel_free);
106 E_FREE_LIST(acpi_bindings, _e_bindings_acpi_free);
110 ecore_event_handler_del(mapping_handler);
111 mapping_handler = NULL;
118 e_bindings_mouse_add(E_Binding_Context ctxt, int button, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
120 E_Binding_Mouse *bind;
122 bind = calloc(1, sizeof(E_Binding_Mouse));
124 bind->button = button;
126 bind->any_mod = any_mod;
127 if (action) bind->action = eina_stringshare_add(action);
128 if (params) bind->params = eina_stringshare_add(params);
129 mouse_bindings = eina_list_append(mouse_bindings, bind);
133 e_bindings_mouse_del(E_Binding_Context ctxt, int button, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
135 E_Binding_Mouse *bind;
138 EINA_LIST_FOREACH(mouse_bindings, l, bind)
140 if ((bind->ctxt == ctxt) &&
141 (bind->button == button) &&
142 (bind->mod == mod) &&
143 (bind->any_mod == any_mod) &&
144 (((bind->action) && (action) && (!strcmp(bind->action, action))) ||
145 ((!bind->action) && (!action))) &&
146 (((bind->params) && (params) && (!strcmp(bind->params, params))) ||
147 ((!bind->params) && (!params))))
149 _e_bindings_mouse_free(bind);
150 mouse_bindings = eina_list_remove_list(mouse_bindings, l);
157 e_bindings_mouse_grab(E_Binding_Context ctxt, Ecore_X_Window win)
159 E_Binding_Mouse *bind;
162 EINA_LIST_FOREACH(mouse_bindings, l, bind)
164 if (_e_bindings_context_match(bind->ctxt, ctxt))
166 ecore_x_window_button_grab(win, bind->button,
167 ECORE_X_EVENT_MASK_MOUSE_DOWN |
168 ECORE_X_EVENT_MASK_MOUSE_UP |
169 ECORE_X_EVENT_MASK_MOUSE_MOVE,
170 _e_ecore_modifiers(bind->mod),
177 e_bindings_mouse_ungrab(E_Binding_Context ctxt, Ecore_X_Window win)
179 E_Binding_Mouse *bind;
182 EINA_LIST_FOREACH(mouse_bindings, l, bind)
184 if (_e_bindings_context_match(bind->ctxt, ctxt))
186 ecore_x_window_button_ungrab(win, bind->button,
187 _e_ecore_modifiers(bind->mod), bind->any_mod);
193 e_bindings_mouse_down_find(E_Binding_Context ctxt, E_Object *obj __UNUSED__, Ecore_Event_Mouse_Button *ev, E_Binding_Mouse **bind_ret)
195 E_Binding_Modifier mod = 0;
196 E_Binding_Mouse *bind;
199 mod = _e_bindings_modifiers(ev->modifiers);
200 EINA_LIST_FOREACH(mouse_bindings, l, bind)
202 if ((bind->button == (int) ev->buttons) &&
203 ((bind->any_mod) || (bind->mod == mod)))
205 if (_e_bindings_context_match(bind->ctxt, ctxt))
209 act = e_action_find(bind->action);
210 if (bind_ret) *bind_ret = bind;
219 e_bindings_mouse_down_event_handle(E_Binding_Context ctxt, E_Object *obj, Ecore_Event_Mouse_Button *ev)
222 E_Binding_Mouse *bind;
224 act = e_bindings_mouse_down_find(ctxt, obj, ev, &bind);
227 if (act->func.go_mouse)
228 act->func.go_mouse(obj, bind->params, ev);
229 else if (act->func.go)
230 act->func.go(obj, bind->params);
237 e_bindings_mouse_up_find(E_Binding_Context ctxt, E_Object *obj __UNUSED__, Ecore_Event_Mouse_Button *ev, E_Binding_Mouse **bind_ret)
239 E_Binding_Modifier mod = 0;
240 E_Binding_Mouse *bind;
243 mod = _e_bindings_modifiers(ev->modifiers);
244 EINA_LIST_FOREACH(mouse_bindings, l, bind)
246 if ((bind->button == (int) ev->buttons) &&
247 ((bind->any_mod) || (bind->mod == mod)))
249 if (_e_bindings_context_match(bind->ctxt, ctxt))
253 act = e_action_find(bind->action);
254 if (bind_ret) *bind_ret = bind;
263 e_bindings_mouse_up_event_handle(E_Binding_Context ctxt, E_Object *obj, Ecore_Event_Mouse_Button *ev)
266 E_Binding_Mouse *bind;
268 act = e_bindings_mouse_up_find(ctxt, obj, ev, &bind);
271 if (act->func.end_mouse)
272 act->func.end_mouse(obj, bind->params, ev);
273 else if (act->func.end)
274 act->func.end(obj, bind->params);
281 e_bindings_key_add(E_Binding_Context ctxt, const char *key, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
285 bind = calloc(1, sizeof(E_Binding_Key));
287 bind->key = eina_stringshare_add(key);
289 bind->any_mod = any_mod;
290 if (action) bind->action = eina_stringshare_add(action);
291 if (params) bind->params = eina_stringshare_add(params);
292 key_bindings = eina_list_append(key_bindings, bind);
296 e_bindings_key_get(const char *action)
301 EINA_LIST_FOREACH(key_bindings, l, bind)
303 if (bind->action && action && !strcmp(action, bind->action))
310 e_bindings_key_find(const char *key, E_Binding_Modifier mod, int any_mod)
315 if (!key) return NULL;
317 EINA_LIST_FOREACH(key_bindings, l, bind)
319 if ((bind->key) && (!strcmp(key, bind->key)) &&
320 (bind->mod == mod) && (bind->any_mod == any_mod))
328 e_bindings_key_del(E_Binding_Context ctxt, const char *key, E_Binding_Modifier mod, int any_mod, const char *action, const char *params)
333 EINA_LIST_FOREACH(key_bindings, l, bind)
335 if ((bind->ctxt == ctxt) &&
336 (key) && (bind->key) && (!strcmp(bind->key, key)) &&
337 (bind->mod == mod) &&
338 (bind->any_mod == any_mod) &&
339 (((bind->action) && (action) && (!strcmp(bind->action, action))) ||
340 ((!bind->action) && (!action))) &&
341 (((bind->params) && (params) && (!strcmp(bind->params, params))) ||
342 ((!bind->params) && (!params))))
344 _e_bindings_key_free(bind);
345 key_bindings = eina_list_remove_list(key_bindings, l);
352 e_bindings_key_grab(E_Binding_Context ctxt, Ecore_X_Window win)
357 EINA_LIST_FOREACH(key_bindings, l, bind)
359 if (_e_bindings_context_match(bind->ctxt, ctxt))
361 ecore_x_window_key_grab(win, bind->key,
362 _e_ecore_modifiers(bind->mod), bind->any_mod);
368 e_bindings_key_ungrab(E_Binding_Context ctxt, Ecore_X_Window win)
373 EINA_LIST_FOREACH(key_bindings, l, bind)
375 if (_e_bindings_context_match(bind->ctxt, ctxt))
377 ecore_x_window_key_ungrab(win, bind->key,
378 _e_ecore_modifiers(bind->mod), bind->any_mod);
384 e_bindings_key_down_event_handle(E_Binding_Context ctxt, E_Object *obj, Ecore_Event_Key *ev)
386 E_Binding_Modifier mod = 0;
390 mod = _e_bindings_modifiers(ev->modifiers);
391 EINA_LIST_FOREACH(key_bindings, l, bind)
393 if ((bind->key) && (!strcmp(bind->key, ev->keyname)) &&
394 ((bind->any_mod) || (bind->mod == mod)))
396 if (_e_bindings_context_match(bind->ctxt, ctxt))
400 act = e_action_find(bind->action);
403 if (act->func.go_key)
404 act->func.go_key(obj, bind->params, ev);
405 else if (act->func.go)
406 act->func.go(obj, bind->params);
417 e_bindings_key_up_event_handle(E_Binding_Context ctxt, E_Object *obj, Ecore_Event_Key *ev)
419 E_Binding_Modifier mod = 0;
423 mod = _e_bindings_modifiers(ev->modifiers);
424 EINA_LIST_FOREACH(key_bindings, l, bind)
426 if ((bind->key) && (!strcmp(bind->key, ev->keyname)) &&
427 ((bind->any_mod) || (bind->mod == mod)))
429 if (_e_bindings_context_match(bind->ctxt, ctxt))
433 act = e_action_find(bind->action);
436 if (act->func.end_key)
437 act->func.end_key(obj, bind->params, ev);
438 else if (act->func.end)
439 act->func.end(obj, bind->params);
450 e_bindings_key_down_event_find(E_Binding_Context ctxt, Ecore_Event_Key *ev)
452 E_Binding_Modifier mod = 0;
456 mod = _e_bindings_modifiers(ev->modifiers);
457 EINA_LIST_FOREACH(key_bindings, l, bind)
459 if ((bind->key) && (!strcmp(bind->key, ev->keyname)) &&
460 ((bind->any_mod) || (bind->mod == mod)))
462 if (_e_bindings_context_match(bind->ctxt, ctxt))
466 act = e_action_find(bind->action);
475 e_bindings_key_up_event_find(E_Binding_Context ctxt, Ecore_Event_Key *ev)
477 E_Binding_Modifier mod = 0;
481 mod = _e_bindings_modifiers(ev->modifiers);
482 EINA_LIST_FOREACH(key_bindings, l, bind)
484 if ((bind->key) && (!strcmp(bind->key, ev->keyname)) &&
485 ((bind->any_mod) || (bind->mod == mod)))
487 if (_e_bindings_context_match(bind->ctxt, ctxt))
491 act = e_action_find(bind->action);
500 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)
502 E_Binding_Edge *bind;
504 bind = calloc(1, sizeof(E_Binding_Edge));
508 bind->any_mod = any_mod;
510 if (action) bind->action = eina_stringshare_add(action);
511 if (params) bind->params = eina_stringshare_add(params);
512 edge_bindings = eina_list_append(edge_bindings, bind);
514 e_zone_edge_new(edge);
518 e_bindings_edge_flippable_get(E_Zone_Edge edge)
520 E_Binding_Edge *bind;
523 EINA_LIST_FOREACH(edge_bindings, l, bind)
525 if ((bind->edge == edge) && (bind->action))
527 if ((!strcmp(bind->action, "desk_flip_in_direction")) ||
528 (!strcmp(bind->action, "desk_flip_by")))
535 EAPI E_Binding_Edge *
536 e_bindings_edge_get(const char *action, E_Zone_Edge edge, Eina_Bool click)
538 E_Binding_Edge *bind;
541 EINA_LIST_FOREACH(edge_bindings, l, bind)
543 if ((bind->edge == edge) &&
544 ((click && (bind->delay == -1.0))
545 || (!click && (bind->delay >= 0.0))) &&
546 (bind->action) && (action) &&
547 (!strcmp(action, bind->action)))
554 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)
556 E_Binding_Edge *bind;
560 EINA_LIST_FOREACH(edge_bindings, l, bind)
562 if ((bind->edge == edge))
564 if ((bind->ctxt == ctxt) &&
565 (bind->mod == mod) &&
566 ((bind->delay * 1000) == (delay * 1000)) &&
567 (bind->any_mod == any_mod) &&
568 (((bind->action) && (action) && (!strcmp(bind->action, action))) ||
569 ((!bind->action) && (!action))) &&
570 (((bind->params) && (params) && (!strcmp(bind->params, params))) ||
571 ((!bind->params) && (!params))))
573 _e_bindings_edge_free(bind);
574 edge_bindings = eina_list_remove_list(edge_bindings, l);
581 e_zone_edge_free(edge);
585 e_bindings_edge_in_event_handle(E_Binding_Context ctxt, E_Object *obj, E_Event_Zone_Edge *ev)
587 E_Binding_Modifier mod = 0;
588 E_Binding_Edge *bind;
589 E_Desk *current = NULL;
590 E_Action *act = NULL;
593 current = e_desk_at_xy_get(ev->zone, ev->zone->desk_x_current, ev->zone->desk_y_current);
594 if (current->fullscreen_borders && (!e_config->fullscreen_flip)) return NULL;
596 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT;
597 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL;
598 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT;
599 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN;
600 EINA_LIST_FOREACH(edge_bindings, l, bind)
602 /* A value of -1.0 for the delay indicates it as a mouse-click binding on that edge */
603 if (((bind->edge == ev->edge)) && (bind->delay >= 0.0) &&
604 ((bind->any_mod) || (bind->mod == mod)))
606 if (_e_bindings_context_match(bind->ctxt, ctxt))
608 act = e_action_find(bind->action);
611 E_Binding_Edge_Data *ed = E_NEW(E_Binding_Edge_Data, 1);
612 E_Event_Zone_Edge *ev2 = E_NEW(E_Event_Zone_Edge, 1);
614 /* The original event will be freed before it can be
616 ev2->zone = ev->zone;
617 ev2->edge = ev->edge;
625 bind->timer = ecore_timer_add(((double) bind->delay), _e_bindings_edge_cb_timer, ed);
634 e_bindings_edge_out_event_handle(E_Binding_Context ctxt, E_Object *obj, E_Event_Zone_Edge *ev)
636 E_Binding_Modifier mod = 0;
637 E_Binding_Edge *bind;
638 E_Action *act = NULL;
641 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT;
642 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL;
643 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT;
644 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN;
645 EINA_LIST_FOREACH(edge_bindings, l, bind)
647 /* A value of -1.0 for the delay indicates it as a mouse-click binding on that edge */
648 if ((bind->edge == ev->edge) && (bind->delay >= 0.0) &&
649 ((bind->any_mod) || (bind->mod == mod)))
651 if (_e_bindings_context_match(bind->ctxt, ctxt))
655 E_Binding_Edge_Data *ed;
657 ed = ecore_timer_del(bind->timer);
666 act = e_action_find(bind->action);
667 if (act && act->func.end)
668 act->func.end(obj, bind->params);
676 e_bindings_edge_down_event_handle(E_Binding_Context ctxt, E_Object *obj, E_Event_Zone_Edge *ev)
678 E_Binding_Modifier mod = 0;
679 E_Binding_Edge *bind;
680 E_Desk *current = NULL;
681 E_Action *act = NULL;
684 current = e_desk_at_xy_get(ev->zone, ev->zone->desk_x_current, ev->zone->desk_y_current);
685 if (current->fullscreen_borders && (!e_config->fullscreen_flip)) return NULL;
687 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT;
688 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL;
689 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT;
690 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN;
691 EINA_LIST_FOREACH(edge_bindings, l, bind)
693 if (((bind->edge == ev->edge)) && (bind->delay == -1.0) &&
694 ((bind->any_mod) || (bind->mod == mod)))
696 if (_e_bindings_context_match(bind->ctxt, ctxt))
698 act = e_action_find(bind->action);
701 if (act->func.go_edge)
702 act->func.go_edge(obj, bind->params, ev);
703 else if (act->func.go)
704 act->func.go(obj, bind->params);
713 e_bindings_edge_up_event_handle(E_Binding_Context ctxt, E_Object *obj, E_Event_Zone_Edge *ev)
715 E_Binding_Modifier mod = 0;
716 E_Binding_Edge *bind;
717 E_Action *act = NULL;
720 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT;
721 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL;
722 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT;
723 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN;
724 EINA_LIST_FOREACH(edge_bindings, l, bind)
726 if ((bind->edge == ev->edge) && (bind->delay == -1.0) &&
727 ((bind->any_mod) || (bind->mod == mod)))
729 if (_e_bindings_context_match(bind->ctxt, ctxt))
731 act = e_action_find(bind->action);
732 if (act && act->func.end)
733 act->func.end(obj, bind->params);
741 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)
743 E_Binding_Signal *bind;
745 bind = calloc(1, sizeof(E_Binding_Signal));
747 if (sig) bind->sig = eina_stringshare_add(sig);
748 if (src) bind->src = eina_stringshare_add(src);
750 bind->any_mod = any_mod;
751 if (action) bind->action = eina_stringshare_add(action);
752 if (params) bind->params = eina_stringshare_add(params);
753 signal_bindings = eina_list_append(signal_bindings, bind);
757 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)
759 E_Binding_Signal *bind;
762 EINA_LIST_FOREACH(signal_bindings, l, bind)
764 if ((bind->ctxt == ctxt) &&
765 (((bind->sig) && (sig) && (!strcmp(bind->sig, sig))) ||
766 ((!bind->sig) && (!sig))) &&
767 (((bind->src) && (src) && (!strcmp(bind->src, src))) ||
768 ((!bind->src) && (!src))) &&
769 (bind->mod == mod) &&
770 (bind->any_mod == any_mod) &&
771 (((bind->action) && (action) && (!strcmp(bind->action, action))) ||
772 ((!bind->action) && (!action))) &&
773 (((bind->params) && (params) && (!strcmp(bind->params, params))) ||
774 ((!bind->params) && (!params))))
776 _e_bindings_signal_free(bind);
777 signal_bindings = eina_list_remove_list(signal_bindings, l);
784 e_bindings_signal_find(E_Binding_Context ctxt, E_Object *obj __UNUSED__, const char *sig, const char *src, E_Binding_Signal **bind_ret)
786 E_Binding_Modifier mod = 0;
787 E_Binding_Signal *bind;
790 if (strstr(sig, "MOD:Shift")) mod |= E_BINDING_MODIFIER_SHIFT;
791 if (strstr(sig, "MOD:Control")) mod |= E_BINDING_MODIFIER_CTRL;
792 if (strstr(sig, "MOD:Alt")) mod |= E_BINDING_MODIFIER_ALT;
793 if (strstr(sig, "MOD:Super")) mod |= E_BINDING_MODIFIER_WIN;
794 EINA_LIST_FOREACH(signal_bindings, l, bind)
796 if ((e_util_glob_match(sig, bind->sig)) &&
797 (e_util_glob_match(src, bind->src)) &&
798 ((bind->any_mod) || (bind->mod == mod)))
800 if (_e_bindings_context_match(bind->ctxt, ctxt))
804 act = e_action_find(bind->action);
805 if (bind_ret) *bind_ret = bind;
814 e_bindings_signal_handle(E_Binding_Context ctxt, E_Object *obj, const char *sig, const char *src)
817 E_Binding_Signal *bind;
819 if (sig[0] == 0) sig = NULL;
820 if (src[0] == 0) src = NULL;
821 act = e_bindings_signal_find(ctxt, obj, sig, src, &bind);
824 if (act->func.go_signal)
825 act->func.go_signal(obj, bind->params, sig, src);
826 else if (act->func.go)
827 act->func.go(obj, bind->params);
834 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)
836 E_Binding_Wheel *bind;
838 bind = calloc(1, sizeof(E_Binding_Wheel));
840 bind->direction = direction;
843 bind->any_mod = any_mod;
844 if (action) bind->action = eina_stringshare_add(action);
845 if (params) bind->params = eina_stringshare_add(params);
846 wheel_bindings = eina_list_append(wheel_bindings, bind);
850 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)
852 E_Binding_Wheel *bind;
855 EINA_LIST_FOREACH(wheel_bindings, l, bind)
857 if ((bind->ctxt == ctxt) &&
858 (bind->direction == direction) &&
860 (bind->mod == mod) &&
861 (bind->any_mod == any_mod) &&
862 (((bind->action) && (action) && (!strcmp(bind->action, action))) ||
863 ((!bind->action) && (!action))) &&
864 (((bind->params) && (params) && (!strcmp(bind->params, params))) ||
865 ((!bind->params) && (!params))))
867 _e_bindings_wheel_free(bind);
868 wheel_bindings = eina_list_remove_list(wheel_bindings, l);
875 e_bindings_wheel_grab(E_Binding_Context ctxt, Ecore_X_Window win)
877 E_Binding_Wheel *bind;
880 EINA_LIST_FOREACH(wheel_bindings, l, bind)
882 if (_e_bindings_context_match(bind->ctxt, ctxt))
886 if (bind->direction == 0)
888 if (bind->z < 0) button = 4;
889 else if (bind->z > 0) button = 5;
891 else if (bind->direction == 1)
893 if (bind->z < 0) button = 6;
894 else if (bind->z > 0) button = 7;
897 ecore_x_window_button_grab(win, button,
898 ECORE_X_EVENT_MASK_MOUSE_DOWN,
899 _e_ecore_modifiers(bind->mod), bind->any_mod);
905 e_bindings_wheel_ungrab(E_Binding_Context ctxt, Ecore_X_Window win)
907 E_Binding_Wheel *bind;
910 EINA_LIST_FOREACH(wheel_bindings, l, bind)
912 if (_e_bindings_context_match(bind->ctxt, ctxt))
916 if (bind->direction == 0)
918 if (bind->z < 0) button = 4;
919 else if (bind->z > 0) button = 5;
921 else if (bind->direction == 1)
923 if (bind->z < 0) button = 6;
924 else if (bind->z > 0) button = 7;
927 ecore_x_window_button_ungrab(win, button,
928 _e_ecore_modifiers(bind->mod), bind->any_mod);
934 e_bindings_wheel_find(E_Binding_Context ctxt, E_Object *obj __UNUSED__, Ecore_Event_Mouse_Wheel *ev, E_Binding_Wheel **bind_ret)
936 E_Binding_Modifier mod = 0;
937 E_Binding_Wheel *bind;
940 mod = _e_bindings_modifiers(ev->modifiers);
941 EINA_LIST_FOREACH(wheel_bindings, l, bind)
943 if ((bind->direction == ev->direction) &&
944 (((bind->z < 0) && (ev->z < 0)) || ((bind->z > 0) && (ev->z > 0))) &&
945 ((bind->any_mod) || (bind->mod == mod)))
947 if (_e_bindings_context_match(bind->ctxt, ctxt))
951 act = e_action_find(bind->action);
952 if (bind_ret) *bind_ret = bind;
961 e_bindings_wheel_event_handle(E_Binding_Context ctxt, E_Object *obj, Ecore_Event_Mouse_Wheel *ev)
964 E_Binding_Wheel *bind;
966 act = e_bindings_wheel_find(ctxt, obj, ev, &bind);
969 if (act->func.go_wheel)
970 act->func.go_wheel(obj, bind->params, ev);
971 else if (act->func.go)
972 act->func.go(obj, bind->params);
979 e_bindings_acpi_add(E_Binding_Context ctxt, int type, int status, const char *action, const char *params)
981 E_Binding_Acpi *bind;
983 bind = E_NEW(E_Binding_Acpi, 1);
986 bind->status = status;
987 if (action) bind->action = eina_stringshare_add(action);
988 if (params) bind->params = eina_stringshare_add(params);
989 acpi_bindings = eina_list_append(acpi_bindings, bind);
993 e_bindings_acpi_del(E_Binding_Context ctxt, int type, int status, const char *action, const char *params)
995 E_Binding_Acpi *bind;
998 EINA_LIST_FOREACH(acpi_bindings, l, bind)
1000 if ((bind->ctxt == ctxt) &&
1001 (bind->type == type) && (bind->status == status) &&
1002 (((bind->action) && (action) && (!strcmp(bind->action, action))) ||
1003 ((!bind->action) && (!action))) &&
1004 (((bind->params) && (params) && (!strcmp(bind->params, params))) ||
1005 ((!bind->params) && (!params))))
1007 _e_bindings_acpi_free(bind);
1008 acpi_bindings = eina_list_remove_list(acpi_bindings, l);
1015 e_bindings_acpi_find(E_Binding_Context ctxt, E_Object *obj __UNUSED__, E_Event_Acpi *ev, E_Binding_Acpi **bind_ret)
1017 E_Binding_Acpi *bind;
1020 EINA_LIST_FOREACH(acpi_bindings, l, bind)
1022 if (bind->type == ev->type)
1024 /* if binding status is -1, then we don't compare event status */
1025 if (bind->status != -1)
1027 /* binding status is set to something, compare event status */
1028 if (bind->status != ev->status) continue;
1030 if (_e_bindings_context_match(bind->ctxt, ctxt))
1034 act = e_action_find(bind->action);
1035 if (bind_ret) *bind_ret = bind;
1044 e_bindings_acpi_event_handle(E_Binding_Context ctxt, E_Object *obj, E_Event_Acpi *ev)
1047 E_Binding_Acpi *bind;
1049 act = e_bindings_acpi_find(ctxt, obj, ev, &bind);
1052 if (act->func.go_acpi)
1053 act->func.go_acpi(obj, bind->params, ev);
1054 else if (act->func.go)
1055 act->func.go(obj, bind->params);
1061 /* local subsystem functions */
1063 _e_bindings_mapping_change_event_cb(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
1065 // Ecore_X_Event_Mapping_Change *ev = event;
1066 e_managers_keys_ungrab();
1067 e_border_button_bindings_ungrab_all();
1068 e_border_button_bindings_grab_all();
1069 e_managers_keys_grab();
1070 return ECORE_CALLBACK_PASS_ON;
1074 _e_bindings_mouse_free(E_Binding_Mouse *bind)
1076 if (bind->action) eina_stringshare_del(bind->action);
1077 if (bind->params) eina_stringshare_del(bind->params);
1082 _e_bindings_key_free(E_Binding_Key *bind)
1084 if (bind->key) eina_stringshare_del(bind->key);
1085 if (bind->action) eina_stringshare_del(bind->action);
1086 if (bind->params) eina_stringshare_del(bind->params);
1091 _e_bindings_edge_free(E_Binding_Edge *bind)
1093 if (bind->action) eina_stringshare_del(bind->action);
1094 if (bind->params) eina_stringshare_del(bind->params);
1097 E_Binding_Edge_Data *ed;
1099 ed = ecore_timer_del(bind->timer);
1106 _e_bindings_signal_free(E_Binding_Signal *bind)
1108 if (bind->sig) eina_stringshare_del(bind->sig);
1109 if (bind->src) eina_stringshare_del(bind->src);
1110 if (bind->action) eina_stringshare_del(bind->action);
1111 if (bind->params) eina_stringshare_del(bind->params);
1116 _e_bindings_wheel_free(E_Binding_Wheel *bind)
1118 if (bind->action) eina_stringshare_del(bind->action);
1119 if (bind->params) eina_stringshare_del(bind->params);
1124 _e_bindings_acpi_free(E_Binding_Acpi *bind)
1126 if (bind->action) eina_stringshare_del(bind->action);
1127 if (bind->params) eina_stringshare_del(bind->params);
1132 _e_bindings_context_match(E_Binding_Context bctxt, E_Binding_Context ctxt)
1134 if (bctxt == E_BINDING_CONTEXT_ANY &&
1135 !(ctxt == E_BINDING_CONTEXT_ZONE)) return 1;
1136 if (ctxt == E_BINDING_CONTEXT_UNKNOWN) return 0;
1137 if (bctxt == ctxt) return 1;
1141 static E_Binding_Modifier
1142 _e_bindings_modifiers(unsigned int modifiers)
1144 E_Binding_Modifier mod = 0;
1146 if (modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT;
1147 if (modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL;
1148 if (modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT;
1149 if (modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN;
1150 /* FIXME: there is a good reason numlock was ignored. sometimes people
1151 * have it on, sometimes they don't, and often they have no idea. waaaay
1152 * back in E 0.1->0.13 or so days this caused issues thus numlock,
1153 * scrollock and capslock are not usable modifiers.
1155 * if we REALLY want to be able to use numlock we need to add more binding
1156 * flags and config that says "REALLY pay attention to numlock for this
1157 * binding" field in the binding (like there is a "any_mod" flag - we need a
1158 * "num_lock_respect" field)
1160 * also it should be an E_BINDING_MODIFIER_LOCK_NUM as the ecore lock flag
1161 * may vary from system to system as different xservers may have differing
1162 * modifier masks for numlock (it is queried at startup).
1164 if (ev->modifiers & ECORE_X_LOCK_NUM) mod |= ECORE_X_LOCK_NUM;
1171 _e_ecore_modifiers(E_Binding_Modifier modifiers)
1175 if (modifiers & E_BINDING_MODIFIER_SHIFT) mod |= ECORE_EVENT_MODIFIER_SHIFT;
1176 if (modifiers & E_BINDING_MODIFIER_CTRL) mod |= ECORE_EVENT_MODIFIER_CTRL;
1177 if (modifiers & E_BINDING_MODIFIER_ALT) mod |= ECORE_EVENT_MODIFIER_ALT;
1178 if (modifiers & E_BINDING_MODIFIER_WIN) mod |= ECORE_EVENT_MODIFIER_WIN;
1179 /* see comment in e_bindings on numlock
1180 if (modifiers & ECORE_X_LOCK_NUM) mod |= ECORE_X_LOCK_NUM;
1187 _e_bindings_edge_cb_timer(void *data)
1189 E_Binding_Edge_Data *ed;
1190 E_Event_Zone_Edge *ev;
1191 E_Binding_Edge *bind;
1203 if (act->func.go_edge)
1204 act->func.go_edge(obj, bind->params, ev);
1205 else if (act->func.go)
1206 act->func.go(obj, bind->params);
1210 /* Duplicate event */
1213 return ECORE_CALLBACK_CANCEL;