1 #include "e.h"
2 
3 #define TEXT_NO_PARAMS                     _("<None>")
4 #define EXAMPLE_STRING                     "example : "
5 
6 static void        *_create_data(E_Config_Dialog *cfd);
7 static void         _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
8 static int          _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
9 static Evas_Object *_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
10 
11 static void         _fill_data(E_Config_Dialog_Data *cfdata);
12 static void         _fill_actions_list(E_Config_Dialog_Data *cfdata);
13 
14 /******************* Callbacks *************/
15 static void         _binding_change_cb(void *data);
16 static void         _action_change_cb(void *data);
17 static void         _delete_mouse_binding_cb(void *data, void *data2);
18 static void         _delete_all_mouse_binding_cb(void *data, void *data2);
19 static void         _restore_mouse_binding_defaults_cb(void *data, void *data2);
20 static void         _add_mouse_binding_cb(void *data, void *data2);
21 static void         _modify_mouse_binding_cb(void *data, void *data2);
22 
23 /******************* Updates *****************/
24 static void         _update_action_list(E_Config_Dialog_Data *cfdata);
25 static void         _update_action_params(E_Config_Dialog_Data *cfdata);
26 static void         _update_mouse_binding_list(E_Config_Dialog_Data *cfdata);
27 static void         _update_buttons(E_Config_Dialog_Data *cfdata);
28 static void         _update_binding_context(E_Config_Dialog_Data *cfdata);
29 
30 /****************** Helper *****************/
31 static void         _find_key_binding_action(const char *action, const char *params, int *g, int *a, int *n);
32 static char        *_helper_button_name_get(E_Config_Binding_Mouse *eb);
33 static char        *_helper_wheel_name_get(E_Config_Binding_Wheel *bw);
34 static char        *_helper_modifier_name_get(int mod);
35 static void         _auto_apply_changes(E_Config_Dialog_Data *cfdata);
36 
37 /********* Sorting ***************/
38 static int          _mouse_binding_sort_cb(const void *d1, const void *d2);
39 static int          _wheel_binding_sort_cb(const void *d1, const void *d2);
40 
41 /********* grab window **********/
42 static void         _grab_wnd_show(E_Config_Dialog_Data *cfdata);
43 static Eina_Bool    _grab_mouse_down_cb(void *data, int type, void *event);
44 static Eina_Bool    _grab_mouse_wheel_cb(void *data, int type, void *event);
45 
46 struct _E_Config_Dialog_Data
47 {
48    E_Config_Dialog *cfd;
49 
50    Evas            *evas;
51 
52    struct
53    {
54       Eina_List *mouse;
55       Eina_List *wheel;
56    } binding;
57 
58    struct
59    {
60       const char    *binding;
61       const char    *action;
62       char          *params;
63       int            context;
64 
65       const char    *cur;
66       int            add; /*just to distinguesh among two buttons add/modify */
67 
68       E_Grab_Dialog *eg;
69    } locals;
70 
71    struct
72    {
73       Evas_Object *o_binding_list;
74       Evas_Object *o_action_list;
75       Evas_Object *o_params;
76       Evas_Object *o_del;
77       Evas_Object *o_mod;
78       Evas_Object *o_del_all;
79       struct
80       {
81          Evas_Object *o_any, *o_window, *o_menu, *o_winlist, *o_popup, *o_zone,
82                      *o_container, *o_manager, *o_none;
83       } context;
84    } gui;
85 };
86 
87 E_Config_Dialog *
e_int_config_mousebindings(Evas_Object * parent EINA_UNUSED,const char * params EINA_UNUSED)88 e_int_config_mousebindings(Evas_Object *parent EINA_UNUSED, const char *params EINA_UNUSED)
89 {
90    E_Config_Dialog *cfd;
91    E_Config_Dialog_View *v;
92 
93    if (e_config_dialog_find("E", "keyboard_and_mouse/mouse_bindings")) return NULL;
94    v = E_NEW(E_Config_Dialog_View, 1);
95 
96    v->create_cfdata = _create_data;
97    v->free_cfdata = _free_data;
98    v->basic.apply_cfdata = _basic_apply_data;
99    v->basic.create_widgets = _basic_create_widgets;
100    v->override_auto_apply = 0;
101 
102    cfd = e_config_dialog_new(NULL,
103                              _("Mouse Bindings Settings"),
104                              "E", "keyboard_and_mouse/mouse_bindings",
105                              "preferences-desktop-mouse", 0, v, NULL);
106    return cfd;
107 }
108 
109 static void
_fill_data(E_Config_Dialog_Data * cfdata)110 _fill_data(E_Config_Dialog_Data *cfdata)
111 {
112    Eina_List *l;
113    E_Config_Binding_Mouse *eb, *eb2;
114    E_Config_Binding_Wheel *bw, *bw2;
115 
116    cfdata->locals.binding = eina_stringshare_add("");
117    cfdata->locals.action = eina_stringshare_add("");
118    cfdata->locals.params = strdup("");
119    cfdata->locals.context = E_BINDING_CONTEXT_ANY;
120    cfdata->binding.mouse = NULL;
121    cfdata->binding.wheel = NULL;
122    cfdata->locals.eg = NULL;
123 
124    EINA_LIST_FOREACH(e_bindings->mouse_bindings, l, eb)
125      {
126         eb2 = E_NEW(E_Config_Binding_Mouse, 1);
127         eb2->context = eb->context;
128         eb2->button = eb->button;
129         eb2->modifiers = eb->modifiers;
130         eb2->any_mod = eb->any_mod;
131         eb2->action = !eb->action ? NULL : eina_stringshare_add(eb->action);
132         eb2->params = !eb->params ? NULL : eina_stringshare_add(eb->params);
133 
134         cfdata->binding.mouse = eina_list_append(cfdata->binding.mouse, eb2);
135      }
136 
137    EINA_LIST_FOREACH(e_bindings->wheel_bindings, l, bw)
138      {
139         bw2 = E_NEW(E_Config_Binding_Wheel, 1);
140         bw2->context = bw->context;
141         bw2->direction = bw->direction;
142         bw2->z = bw->z;
143         bw2->modifiers = bw->modifiers;
144         bw2->any_mod = bw->any_mod;
145         bw2->action = !bw->action ? NULL : eina_stringshare_add(bw->action);
146         bw2->params = !bw->params ? NULL : eina_stringshare_add(bw->params);
147 
148         cfdata->binding.wheel = eina_list_append(cfdata->binding.wheel, bw2);
149      }
150 }
151 
152 static void *
_create_data(E_Config_Dialog * cfd)153 _create_data(E_Config_Dialog *cfd)
154 {
155    E_Config_Dialog_Data *cfdata;
156 
157    cfdata = E_NEW(E_Config_Dialog_Data, 1);
158 
159    _fill_data(cfdata);
160    cfdata->cfd = cfd;
161    return cfdata;
162 }
163 
164 static void
_free_data(E_Config_Dialog * cfd EINA_UNUSED,E_Config_Dialog_Data * cfdata)165 _free_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
166 {
167    E_Config_Binding_Mouse *eb;
168    E_Config_Binding_Wheel *bw;
169 
170    EINA_LIST_FREE(cfdata->binding.mouse, eb)
171      {
172         eina_stringshare_del(eb->action);
173         eina_stringshare_del(eb->params);
174         E_FREE(eb);
175      }
176 
177    EINA_LIST_FREE(cfdata->binding.wheel, bw)
178      {
179         eina_stringshare_del(bw->action);
180         eina_stringshare_del(bw->params);
181         E_FREE(bw);
182      }
183 
184    eina_stringshare_del(cfdata->locals.binding);
185    eina_stringshare_del(cfdata->locals.action);
186    eina_stringshare_del(cfdata->locals.cur);
187 
188    free(cfdata->locals.params);
189    E_FREE(cfdata);
190 }
191 
192 static int
_basic_apply_data(E_Config_Dialog * cfd EINA_UNUSED,E_Config_Dialog_Data * cfdata)193 _basic_apply_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
194 {
195    Eina_List *l, *l2;
196    E_Config_Binding_Mouse *eb, *eb2;
197    E_Config_Binding_Wheel *bw, *bw2;
198 
199    _auto_apply_changes(cfdata);
200 
201    e_comp_button_bindings_ungrab_all();
202    e_comp_canvas_keys_ungrab();
203 
204    EINA_LIST_FREE(e_bindings->mouse_bindings, eb)
205      {
206         e_bindings_mouse_del(eb->context, eb->button, eb->modifiers, eb->any_mod,
207                              eb->action, eb->params);
208         eina_stringshare_del(eb->action);
209         eina_stringshare_del(eb->params);
210         E_FREE(eb);
211      }
212 
213    EINA_LIST_FOREACH(cfdata->binding.mouse, l, eb)
214      {
215         eb2 = E_NEW(E_Config_Binding_Mouse, 1);
216         eb2->context = eb->context;
217         eb2->button = eb->button;
218         eb2->modifiers = eb->modifiers;
219         eb2->any_mod = eb->any_mod;
220         eb2->action = !eb->action ? NULL : eina_stringshare_add(eb->action);
221         eb2->params = !eb->params ? NULL : eina_stringshare_add(eb->params);
222 
223         e_bindings->mouse_bindings = eina_list_append(e_bindings->mouse_bindings, eb2);
224         e_bindings_mouse_add(eb2->context, eb2->button, eb2->modifiers, eb2->any_mod,
225                              eb2->action, eb2->params);
226      }
227 
228    EINA_LIST_FREE(e_bindings->wheel_bindings, bw)
229      {
230         e_bindings_wheel_del(bw->context, bw->direction, bw->z, bw->modifiers, bw->any_mod,
231                              bw->action, bw->params);
232         eina_stringshare_del(bw->action);
233         eina_stringshare_del(bw->params);
234         E_FREE(bw);
235      }
236 
237    EINA_LIST_FOREACH_SAFE(cfdata->binding.wheel, l, l2, bw)
238      {
239         if ((!bw->modifiers) &&
240             (bw->direction == 0) &&
241             ((bw->context == E_BINDING_CONTEXT_WINDOW) || (bw->context == E_BINDING_CONTEXT_ANY)))
242           {
243              const char *msg = _("Unable to set a mouse wheel binding without modifiers<ps/>"
244                                   "on a window: conflict with existing edje signal bindings.<ps/>"
245                                   "FIXME!!!");
246              e_util_dialog_internal(_("Mouse Binding Error"), msg);
247              cfdata->binding.wheel = eina_list_remove_list(cfdata->binding.wheel, l);
248              eina_stringshare_del(bw->action);
249              eina_stringshare_del(bw->params);
250              E_FREE(bw);
251              _update_mouse_binding_list(cfdata);
252              continue;
253           }
254         bw2 = E_NEW(E_Config_Binding_Wheel, 1);
255         bw2->context = bw->context;
256         bw2->direction = bw->direction;
257         bw2->z = bw->z;
258         bw2->modifiers = bw->modifiers;
259         bw2->any_mod = bw->any_mod;
260         bw2->action = !bw->action ? NULL : eina_stringshare_add(bw->action);
261         bw2->params = !bw->params ? NULL : eina_stringshare_add(bw->params);
262 
263         e_bindings->wheel_bindings = eina_list_append(e_bindings->wheel_bindings, bw2);
264         e_bindings_wheel_add(bw2->context, bw2->direction, bw2->z, bw2->modifiers,
265                              bw2->any_mod, bw2->action, bw2->params);
266      }
267    e_comp_button_bindings_grab_all();
268    e_comp_canvas_keys_grab();
269 
270    e_config_save_queue();
271    return 1;
272 }
273 
274 static Evas_Object *
_basic_create_widgets(E_Config_Dialog * cfd,Evas * evas,E_Config_Dialog_Data * cfdata)275 _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
276 {
277    Evas_Object *o, *of, *ot, *ob;
278    E_Radio_Group *rg;
279 
280    cfdata->evas = evas;
281    o = e_widget_list_add(evas, 0, 1);
282    ot = e_widget_frametable_add(evas, _("Mouse Bindings"), 0);
283    ob = e_widget_ilist_add(evas, 32, 32, &(cfdata->locals.binding));
284    cfdata->gui.o_binding_list = ob;
285    e_widget_size_min_set(ob, 200, 200);
286    e_widget_frametable_object_append(ot, ob, 0, 0, 2, 1, 1, 1, 1, 1);
287 
288    ob = e_widget_button_add(evas, _("Add"), "list-add", _add_mouse_binding_cb, cfdata, NULL);
289    e_widget_frametable_object_append(ot, ob, 0, 1, 1, 1, 1, 0, 1, 0);
290    ob = e_widget_button_add(evas, _("Delete"), "list-remove", _delete_mouse_binding_cb, cfdata, NULL);
291    cfdata->gui.o_del = ob;
292    e_widget_disabled_set(ob, 1);
293    e_widget_frametable_object_append(ot, ob, 1, 1, 1, 1, 1, 0, 1, 0);
294    ob = e_widget_button_add(evas, _("Modify"), NULL, _modify_mouse_binding_cb, cfdata, NULL);
295    cfdata->gui.o_mod = ob;
296    e_widget_disabled_set(ob, 1);
297    e_widget_frametable_object_append(ot, ob, 0, 2, 1, 1, 1, 0, 1, 0);
298    ob = e_widget_button_add(evas, _("Delete All"), "edit-clear", _delete_all_mouse_binding_cb, cfdata, NULL);
299    cfdata->gui.o_del_all = ob;
300    e_widget_disabled_set(ob, 1);
301    e_widget_frametable_object_append(ot, ob, 1, 2, 1, 1, 1, 0, 1, 0);
302    ob = e_widget_button_add(evas, _("Restore Default Bindings"), "enlightenment",
303                             _restore_mouse_binding_defaults_cb, cfdata, NULL);
304    e_widget_frametable_object_append(ot, ob, 0, 3, 2, 1, 1, 0, 1, 0);
305    e_widget_list_object_append(o, ot, 1, 1, 0.5);
306 
307    ot = e_widget_table_add(e_win_evas_win_get(evas), 0);
308    of = e_widget_framelist_add(evas, _("Action"), 0);
309    ob = e_widget_ilist_add(evas, 24, 24, &(cfdata->locals.action));
310    cfdata->gui.o_action_list = ob;
311    e_widget_size_min_set(ob, 200, 200);
312    e_widget_framelist_object_append(of, ob);
313    e_widget_table_object_append(ot, of, 0, 0, 3, 1, 1, 1, 1, 1);
314 
315    of = e_widget_framelist_add(evas, _("Action Params"), 0);
316    ob = e_widget_entry_add(cfd->dia->win, &(cfdata->locals.params), NULL, NULL, NULL);
317    e_widget_disabled_set(ob, 1);
318    cfdata->gui.o_params = ob;
319    e_widget_framelist_object_append(of, ob);
320    e_widget_table_object_append(ot, of, 0, 1, 3, 1, 1, 1, 1, 0);
321 
322    of = e_widget_frametable_add(evas, _("Action Context"), 1);
323    rg = e_widget_radio_group_new(&(cfdata->locals.context));
324    ob = e_widget_radio_add(evas, _("Any"), E_BINDING_CONTEXT_ANY, rg);
325    cfdata->gui.context.o_any = ob;
326    e_widget_disabled_set(ob, 1);
327    e_widget_frametable_object_append(of, ob, 0, 0, 1, 1, 1, 1, 1, 1);
328    ob = e_widget_radio_add(evas, _("Window"), E_BINDING_CONTEXT_WINDOW, rg);
329    cfdata->gui.context.o_window = ob;
330    e_widget_disabled_set(ob, 1);
331    e_widget_frametable_object_append(of, ob, 0, 1, 1, 1, 1, 1, 1, 1);
332    ob = e_widget_radio_add(evas, _("Menu"), E_BINDING_CONTEXT_MENU, rg);
333    cfdata->gui.context.o_menu = ob;
334    e_widget_disabled_set(ob, 1);
335    e_widget_frametable_object_append(of, ob, 0, 2, 1, 1, 1, 1, 1, 1);
336    ob = e_widget_radio_add(evas, _("Win List"), E_BINDING_CONTEXT_WINLIST, rg);
337    cfdata->gui.context.o_winlist = ob;
338    e_widget_disabled_set(ob, 1);
339    e_widget_frametable_object_append(of, ob, 1, 0, 1, 1, 1, 1, 1, 1);
340    ob = e_widget_radio_add(evas, _("Popup"), E_BINDING_CONTEXT_POPUP, rg);
341    cfdata->gui.context.o_popup = ob;
342    e_widget_disabled_set(ob, 1);
343    e_widget_frametable_object_append(of, ob, 1, 1, 1, 1, 1, 1, 1, 1);
344    ob = e_widget_radio_add(evas, _("Zone"), E_BINDING_CONTEXT_ZONE, rg);
345    cfdata->gui.context.o_zone = ob;
346    e_widget_disabled_set(ob, 1);
347    e_widget_frametable_object_append(of, ob, 1, 2, 1, 1, 1, 1, 1, 1);
348    ob = e_widget_radio_add(evas, _("Compositor"), E_BINDING_CONTEXT_COMPOSITOR, rg);
349    cfdata->gui.context.o_container = ob;
350    e_widget_disabled_set(ob, 1);
351    e_widget_frametable_object_append(of, ob, 2, 0, 1, 1, 1, 1, 1, 1);
352    ob = e_widget_radio_add(evas, _("Manager"), E_BINDING_CONTEXT_MANAGER, rg);
353    cfdata->gui.context.o_manager = ob;
354    e_widget_disabled_set(ob, 1);
355    e_widget_frametable_object_append(of, ob, 2, 1, 1, 1, 1, 1, 1, 1);
356    ob = e_widget_radio_add(evas, _("None"), E_BINDING_CONTEXT_NONE, rg);
357    cfdata->gui.context.o_none = ob;
358    e_widget_disabled_set(ob, 1);
359    e_widget_frametable_object_append(of, ob, 2, 2, 1, 1, 1, 1, 1, 1);
360    e_widget_table_object_append(ot, of, 0, 2, 3, 1, 1, 1, 1, 0);
361    e_widget_list_object_append(o, ot, 1, 1, 0.5);
362 
363    _update_mouse_binding_list(cfdata);
364    _fill_actions_list(cfdata);
365 
366    e_dialog_resizable_set(cfd->dia, 1);
367    return o;
368 }
369 
370 static void
_fill_actions_list(E_Config_Dialog_Data * cfdata)371 _fill_actions_list(E_Config_Dialog_Data *cfdata)
372 {
373    char buf[1024];
374    Eina_List *l, *l2;
375    E_Action_Group *actg;
376    E_Action_Description *actd;
377    int g, a;
378 
379    evas_event_freeze(evas_object_evas_get(cfdata->gui.o_action_list));
380    edje_freeze();
381    e_widget_ilist_freeze(cfdata->gui.o_action_list);
382 
383    e_widget_ilist_clear(cfdata->gui.o_action_list);
384    for (l = e_action_groups_get(), g = 0; l; l = l->next, g++)
385      {
386         actg = l->data;
387 
388         if (!actg->acts) continue;
389 
390         e_widget_ilist_header_append(cfdata->gui.o_action_list, NULL, _(actg->act_grp));
391 
392         for (l2 = actg->acts, a = 0; l2; l2 = l2->next, a++)
393           {
394              actd = l2->data;
395 
396              snprintf(buf, sizeof(buf), "%d %d", g, a);
397              e_widget_ilist_append(cfdata->gui.o_action_list, NULL, _(actd->act_name),
398                                    _action_change_cb, cfdata, buf);
399           }
400      }
401    e_widget_ilist_go(cfdata->gui.o_action_list);
402    e_widget_ilist_thaw(cfdata->gui.o_action_list);
403    edje_thaw();
404    evas_event_thaw(evas_object_evas_get(cfdata->gui.o_action_list));
405 }
406 
407 /******************* Callbacks *************/
408 static void
_add_mouse_binding_cb(void * data,void * data2 EINA_UNUSED)409 _add_mouse_binding_cb(void *data, void *data2 EINA_UNUSED)
410 {
411    E_Config_Dialog_Data *cfdata;
412 
413    cfdata = data;
414    _auto_apply_changes(cfdata);
415 
416    cfdata->locals.add = 1;
417    _grab_wnd_show(cfdata);
418 }
419 
420 static void
_modify_mouse_binding_cb(void * data,void * data2 EINA_UNUSED)421 _modify_mouse_binding_cb(void *data, void *data2 EINA_UNUSED)
422 {
423    E_Config_Dialog_Data *cfdata;
424 
425    cfdata = data;
426    _auto_apply_changes(cfdata);
427 
428    cfdata->locals.add = 0;
429    _grab_wnd_show(cfdata);
430 }
431 
432 static void
_action_change_cb(void * data)433 _action_change_cb(void *data)
434 {
435    E_Config_Dialog_Data *cfdata;
436 
437    cfdata = data;
438    _update_action_params(cfdata);
439 }
440 
441 static void
_binding_change_cb(void * data)442 _binding_change_cb(void *data)
443 {
444    E_Config_Dialog_Data *cfdata;
445 
446    cfdata = data;
447 
448    _auto_apply_changes(cfdata);
449 
450    eina_stringshare_del(cfdata->locals.cur);
451    cfdata->locals.cur = NULL;
452 
453    if (cfdata->locals.binding[0])
454      cfdata->locals.cur = eina_stringshare_ref(cfdata->locals.binding);
455 
456    _update_buttons(cfdata);
457    _update_action_list(cfdata);
458    _update_binding_context(cfdata);
459 }
460 
461 static void
_delete_all_mouse_binding_cb(void * data,void * data2 EINA_UNUSED)462 _delete_all_mouse_binding_cb(void *data, void *data2 EINA_UNUSED)
463 {
464    E_Config_Dialog_Data *cfdata;
465    E_Config_Binding_Mouse *eb;
466    E_Config_Binding_Wheel *bw;
467 
468    cfdata = data;
469 
470    /* FIXME: need confirmation dialog */
471    EINA_LIST_FREE(cfdata->binding.mouse, eb)
472      {
473         eina_stringshare_del(eb->action);
474         eina_stringshare_del(eb->params);
475         E_FREE(eb);
476      }
477 
478    EINA_LIST_FREE(cfdata->binding.wheel, bw)
479      {
480         eina_stringshare_del(bw->action);
481         eina_stringshare_del(bw->params);
482         E_FREE(bw);
483      }
484 
485    eina_stringshare_del(cfdata->locals.cur);
486    cfdata->locals.cur = NULL;
487 
488    e_widget_ilist_clear(cfdata->gui.o_binding_list);
489    e_widget_ilist_go(cfdata->gui.o_binding_list);
490    e_widget_ilist_unselect(cfdata->gui.o_action_list);
491    e_widget_entry_clear(cfdata->gui.o_params);
492    e_widget_disabled_set(cfdata->gui.o_params, 1);
493 
494    _update_buttons(cfdata);
495    _update_binding_context(cfdata);
496 }
497 
498 static void
_delete_mouse_binding_cb(void * data,void * data2 EINA_UNUSED)499 _delete_mouse_binding_cb(void *data, void *data2 EINA_UNUSED)
500 {
501    Eina_List *l;
502    int sel, n;
503    E_Config_Dialog_Data *cfdata;
504    E_Config_Binding_Mouse *eb;
505    E_Config_Binding_Wheel *bw;
506 
507    cfdata = data;
508 
509    sel = e_widget_ilist_selected_get(cfdata->gui.o_binding_list);
510    if (cfdata->locals.binding[0] == 'm')
511      {
512         sscanf(cfdata->locals.binding, "m%d", &n);
513         l = eina_list_nth_list(cfdata->binding.mouse, n);
514         if (l)
515           {
516              eb = eina_list_data_get(l);
517              eina_stringshare_del(eb->action);
518              eina_stringshare_del(eb->params);
519              E_FREE(eb);
520 
521              cfdata->binding.mouse = eina_list_remove_list(cfdata->binding.mouse, l);
522           }
523      }
524    else if (cfdata->locals.binding[0] == 'w')
525      {
526         sscanf(cfdata->locals.binding, "w%d", &n);
527         l = eina_list_nth_list(cfdata->binding.wheel, n);
528         if (l)
529           {
530              bw = eina_list_data_get(l);
531              eina_stringshare_del(bw->action);
532              eina_stringshare_del(bw->params);
533              E_FREE(bw);
534 
535              cfdata->binding.wheel = eina_list_remove_list(cfdata->binding.wheel, l);
536           }
537      }
538    else
539      return;
540 
541    _update_mouse_binding_list(cfdata);
542    if (sel >= e_widget_ilist_count(cfdata->gui.o_binding_list))
543      sel = e_widget_ilist_count(cfdata->gui.o_binding_list) - 1;
544 
545    eina_stringshare_del(cfdata->locals.cur);
546    cfdata->locals.cur = NULL;
547 
548    if (!e_widget_ilist_count(cfdata->gui.o_binding_list))
549      {
550         _update_binding_context(cfdata);
551         _update_buttons(cfdata);
552 
553         e_widget_ilist_unselect(cfdata->gui.o_action_list);
554         e_widget_entry_clear(cfdata->gui.o_params);
555         e_widget_disabled_set(cfdata->gui.o_params, 1);
556      }
557    else
558      {
559         if (e_widget_ilist_nth_is_header(cfdata->gui.o_binding_list, sel)) sel++;
560         e_widget_ilist_selected_set(cfdata->gui.o_binding_list, sel);
561         e_widget_ilist_nth_show(cfdata->gui.o_binding_list, sel, 0);
562      }
563 }
564 
565 static void
_restore_mouse_binding_defaults_cb(void * data,void * data2 EINA_UNUSED)566 _restore_mouse_binding_defaults_cb(void *data, void *data2 EINA_UNUSED)
567 {
568    E_Config_Bindings *ecb;
569    Eina_Stringshare *prof;
570    E_Config_Dialog_Data *cfdata = data;
571 
572    ecb = e_config_domain_system_load("e_bindings", e_config_descriptor_find("E_Config_Bindings"));
573    if (!ecb)
574      {
575         const char *type;
576 
577         prof = eina_stringshare_ref(e_config_profile_get());
578         switch (e_config->config_type)
579           {
580            case E_CONFIG_PROFILE_TYPE_DESKTOP:
581              type = "standard";
582              break;
583            case E_CONFIG_PROFILE_TYPE_MOBILE:
584              type = "mobile";
585              break;
586            //case E_CONFIG_PROFILE_TYPE_TABLET: FIXME - not used
587            default:
588              type = "default";
589              break;
590           }
591         e_config_profile_set(type);
592         ecb = e_config_domain_system_load("e_bindings", e_config_descriptor_find("E_Config_Bindings"));
593         e_config_profile_set(prof);
594         eina_stringshare_del(prof);
595      }
596    if (!ecb) return;
597    E_FREE_LIST(cfdata->binding.mouse, e_config_binding_mouse_free);
598    E_FREE_LIST(cfdata->binding.wheel, e_config_binding_wheel_free);
599 
600    cfdata->binding.mouse = ecb->mouse_bindings, ecb->mouse_bindings = NULL;
601    cfdata->binding.wheel = ecb->wheel_bindings, ecb->wheel_bindings = NULL;
602    e_config_bindings_free(ecb);
603 
604    eina_stringshare_del(cfdata->locals.cur);
605    cfdata->locals.cur = NULL;
606 
607    _update_mouse_binding_list(cfdata);
608    _update_buttons(cfdata);
609    _update_binding_context(cfdata);
610 
611    e_widget_ilist_unselect(cfdata->gui.o_action_list);
612    e_widget_entry_clear(cfdata->gui.o_params);
613    e_widget_disabled_set(cfdata->gui.o_params, 1);
614 }
615 
616 /******************* Updates *****************/
617 static void
_update_action_list(E_Config_Dialog_Data * cfdata)618 _update_action_list(E_Config_Dialog_Data *cfdata)
619 {
620    E_Config_Binding_Mouse *eb;
621    E_Config_Binding_Wheel *bw;
622    const char *action, *params;
623    int j = -1, i, n;
624 
625    if (!cfdata->locals.cur) return;
626 
627    if (cfdata->locals.cur[0] == 'm')
628      {
629         sscanf(cfdata->locals.cur, "m%d", &n);
630         eb = eina_list_nth(cfdata->binding.mouse, n);
631         if (!eb)
632           {
633              e_widget_ilist_unselect(cfdata->gui.o_action_list);
634              e_widget_entry_clear(cfdata->gui.o_params);
635              e_widget_disabled_set(cfdata->gui.o_params, 1);
636              return;
637           }
638         action = eb->action;
639         params = eb->params;
640      }
641    else if (cfdata->locals.cur[0] == 'w')
642      {
643         sscanf(cfdata->locals.cur, "w%d", &n);
644         bw = eina_list_nth(cfdata->binding.wheel, n);
645         if (!bw)
646           {
647              e_widget_ilist_unselect(cfdata->gui.o_action_list);
648              e_widget_entry_clear(cfdata->gui.o_params);
649              e_widget_disabled_set(cfdata->gui.o_params, 1);
650              return;
651           }
652         action = bw->action;
653         params = bw->params;
654      }
655    else
656      return;
657 
658    _find_key_binding_action(action, params, NULL, NULL, &j);
659    if (j >= 0)
660      {
661         for (i = 0; i < e_widget_ilist_count(cfdata->gui.o_action_list); i++)
662           {
663              if (i > j) break;
664              if (e_widget_ilist_nth_is_header(cfdata->gui.o_action_list, i)) j++;
665           }
666      }
667 
668    if (j >= 0)
669      {
670         if (j == e_widget_ilist_selected_get(cfdata->gui.o_action_list))
671           _update_action_params(cfdata);
672         else
673           e_widget_ilist_selected_set(cfdata->gui.o_action_list, j);
674      }
675    else
676      {
677         e_widget_ilist_unselect(cfdata->gui.o_action_list);
678         eina_stringshare_del(cfdata->locals.action);
679         cfdata->locals.action = eina_stringshare_add("");
680         e_widget_entry_clear(cfdata->gui.o_params);
681      }
682 }
683 
684 static void
_update_mouse_binding_list(E_Config_Dialog_Data * cfdata)685 _update_mouse_binding_list(E_Config_Dialog_Data *cfdata)
686 {
687    char *icon = NULL, *button, *mods;
688    char label[1024], val[16];
689    int i = 0;
690    Eina_List *l;
691    E_Config_Binding_Mouse *eb;
692    E_Config_Binding_Wheel *bw;
693 
694    evas_event_freeze(evas_object_evas_get(cfdata->gui.o_binding_list));
695    edje_freeze();
696    e_widget_ilist_freeze(cfdata->gui.o_binding_list);
697 
698    e_widget_ilist_clear(cfdata->gui.o_binding_list);
699 
700    if (cfdata->binding.mouse)
701      {
702         cfdata->binding.mouse = eina_list_sort(cfdata->binding.mouse,
703                                                eina_list_count(cfdata->binding.mouse), _mouse_binding_sort_cb);
704 
705         e_widget_ilist_header_append(cfdata->gui.o_binding_list, NULL, _("Mouse Buttons"));
706      }
707 
708    EINA_LIST_FOREACH(cfdata->binding.mouse, l, eb)
709      {
710         Evas_Object *ic;
711 
712         button = _helper_button_name_get(eb);
713         mods = _helper_modifier_name_get(eb->modifiers);
714 
715         if (mods && mods[0])
716           snprintf(label, sizeof(label), "%s + %s", button ? button : "", mods);
717         else
718           snprintf(label, sizeof(label), "%s", button ? button : "");
719         free(button);
720         free(mods);
721 
722         switch (eb->button)
723           {
724            case 1:
725              if (e_config->mouse_hand == E_MOUSE_HAND_RIGHT)
726                icon = "preferences-desktop-mouse-left";
727              else if (e_config->mouse_hand == E_MOUSE_HAND_LEFT)
728                icon = "preferences-desktop-mouse-right";
729              else
730                icon = "preferences-desktop-mouse-extra";
731              break;
732 
733            case 2:
734              icon = "preferences-desktop-mouse-middle";
735              break;
736 
737            case 3:
738              if (e_config->mouse_hand == E_MOUSE_HAND_RIGHT)
739                icon = "preferences-desktop-mouse-right";
740              else if (e_config->mouse_hand == E_MOUSE_HAND_LEFT)
741                icon = "preferences-desktop-mouse-left";
742              else
743                icon = "preferences-desktop-mouse-extra";
744              break;
745 
746            default:
747              icon = "preferences-desktop-mouse-extra";
748           }
749 
750         snprintf(val, sizeof(val), "m%d", i);
751 
752         ic = e_icon_add(cfdata->evas);
753         e_util_icon_theme_set(ic, icon);
754         e_widget_ilist_append(cfdata->gui.o_binding_list, ic, label, _binding_change_cb,
755                               cfdata, val);
756 
757         i++;
758      }
759 
760    if (cfdata->binding.wheel)
761      {
762         cfdata->binding.wheel = eina_list_sort(cfdata->binding.wheel,
763                                                eina_list_count(cfdata->binding.wheel), _wheel_binding_sort_cb);
764 
765         e_widget_ilist_header_append(cfdata->gui.o_binding_list, NULL, _("Mouse Wheels"));
766      }
767 
768    i = 0;
769    EINA_LIST_FOREACH(cfdata->binding.wheel, l, bw)
770      {
771         Evas_Object *ic;
772 
773         button = _helper_wheel_name_get(bw);
774         mods = _helper_modifier_name_get(bw->modifiers);
775 
776         if (mods && mods[0])
777           snprintf(label, sizeof(label), "%s + %s", button ? button : "", mods);
778         else
779           snprintf(label, sizeof(label), "%s", button ? button : "");
780         free(button);
781         free(mods);
782 
783         snprintf(val, sizeof(val), "w%d", i);
784 
785         ic = e_icon_add(cfdata->evas);
786         e_util_icon_theme_set(ic, "preferences-desktop-mouse-wheel");
787         e_widget_ilist_append(cfdata->gui.o_binding_list, ic, label, _binding_change_cb,
788                               cfdata, val);
789 
790         i++;
791      }
792 
793    e_widget_ilist_go(cfdata->gui.o_binding_list);
794    e_widget_ilist_thaw(cfdata->gui.o_binding_list);
795    edje_thaw();
796    evas_event_thaw(evas_object_evas_get(cfdata->gui.o_binding_list));
797 
798    if (eina_list_count(cfdata->binding.mouse) + eina_list_count(cfdata->binding.wheel))
799      e_widget_disabled_set(cfdata->gui.o_del_all, 0);
800    else
801      e_widget_disabled_set(cfdata->gui.o_del_all, 1);
802 }
803 
804 static void
_update_action_params(E_Config_Dialog_Data * cfdata)805 _update_action_params(E_Config_Dialog_Data *cfdata)
806 {
807    int g, a, b;
808    E_Action_Group *actg;
809    E_Action_Description *actd;
810    E_Config_Binding_Mouse *eb;
811    E_Config_Binding_Wheel *bw;
812    const char *action, *params;
813 
814 #define MB_EXAMPLE_PARAMS                                           \
815   if ((!actd->param_example) || (!actd->param_example[0]))          \
816     e_widget_entry_text_set(cfdata->gui.o_params, TEXT_NO_PARAMS);  \
817   else                                                              \
818     e_widget_entry_text_set(cfdata->gui.o_params, actd->param_example)
819 
820    if ((!cfdata->locals.action) || (!cfdata->locals.action[0]))
821      {
822         e_widget_disabled_set(cfdata->gui.o_params, 1);
823         e_widget_entry_clear(cfdata->gui.o_params);
824         return;
825      }
826    sscanf(cfdata->locals.action, "%d %d", &g, &a);
827 
828    actg = eina_list_nth(e_action_groups_get(), g);
829    if (!actg) return;
830    actd = eina_list_nth(actg->acts, a);
831    if (!actd) return;
832 
833    if (actd->act_params)
834      {
835         e_widget_disabled_set(cfdata->gui.o_params, 1);
836         e_widget_entry_text_set(cfdata->gui.o_params, actd->act_params);
837         return;
838      }
839 
840    if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0]))
841      {
842         e_widget_disabled_set(cfdata->gui.o_params, 1);
843         MB_EXAMPLE_PARAMS;
844         return;
845      }
846 
847    if (!actd->editable)
848      e_widget_disabled_set(cfdata->gui.o_params, 1);
849    else
850      e_widget_disabled_set(cfdata->gui.o_params, 0);
851 
852    if (cfdata->locals.cur[0] == 'm')
853      {
854         sscanf(cfdata->locals.cur, "m%d", &b);
855         eb = eina_list_nth(cfdata->binding.mouse, b);
856         if (!eb)
857           {
858              e_widget_disabled_set(cfdata->gui.o_params, 1);
859              MB_EXAMPLE_PARAMS;
860              return;
861           }
862         action = eb->action;
863         params = eb->params;
864      }
865    else if (cfdata->locals.cur[0] == 'w')
866      {
867         sscanf(cfdata->locals.cur, "w%d", &b);
868         bw = eina_list_nth(cfdata->binding.wheel, b);
869         if (!bw)
870           {
871              e_widget_disabled_set(cfdata->gui.o_params, 1);
872              MB_EXAMPLE_PARAMS;
873              return;
874           }
875         action = bw->action;
876         params = bw->params;
877      }
878    else
879      {
880         e_widget_disabled_set(cfdata->gui.o_params, 1);
881         MB_EXAMPLE_PARAMS;
882         return;
883      }
884 
885    if (action)
886      {
887         if (!strcmp(action, actd->act_cmd))
888           {
889              if ((!params) || (!params[0]))
890                MB_EXAMPLE_PARAMS;
891              else
892                e_widget_entry_text_set(cfdata->gui.o_params, params);
893           }
894         else
895           MB_EXAMPLE_PARAMS;
896      }
897    else
898      MB_EXAMPLE_PARAMS;
899 }
900 
901 static void
_update_buttons(E_Config_Dialog_Data * cfdata)902 _update_buttons(E_Config_Dialog_Data *cfdata)
903 {
904    if (e_widget_ilist_count(cfdata->gui.o_binding_list))
905      e_widget_disabled_set(cfdata->gui.o_del_all, 0);
906    else
907      e_widget_disabled_set(cfdata->gui.o_del_all, 1);
908 
909    if (!cfdata->locals.cur)
910      {
911         e_widget_disabled_set(cfdata->gui.o_mod, 1);
912         e_widget_disabled_set(cfdata->gui.o_del, 1);
913         return;
914      }
915 
916    e_widget_disabled_set(cfdata->gui.o_mod, 0);
917    e_widget_disabled_set(cfdata->gui.o_del, 0);
918 }
919 
920 static void
_update_binding_context(E_Config_Dialog_Data * cfdata)921 _update_binding_context(E_Config_Dialog_Data *cfdata)
922 {
923    int n;
924    E_Config_Binding_Mouse *eb;
925    E_Config_Binding_Wheel *bw;
926    E_Binding_Context ctxt;
927 
928    /* disable all the radios. */
929    e_widget_radio_toggle_set(cfdata->gui.context.o_any, 1);
930    e_widget_disabled_set(cfdata->gui.context.o_any, 1);
931    e_widget_disabled_set(cfdata->gui.context.o_window, 1);
932    e_widget_disabled_set(cfdata->gui.context.o_menu, 1);
933    e_widget_disabled_set(cfdata->gui.context.o_winlist, 1);
934    e_widget_disabled_set(cfdata->gui.context.o_popup, 1);
935    e_widget_disabled_set(cfdata->gui.context.o_zone, 1);
936    e_widget_disabled_set(cfdata->gui.context.o_container, 1);
937    e_widget_disabled_set(cfdata->gui.context.o_manager, 1);
938    e_widget_disabled_set(cfdata->gui.context.o_none, 1);
939 
940    if (!cfdata->locals.cur) return;
941 
942    if (cfdata->locals.cur[0] == 'm')
943      {
944         sscanf(cfdata->locals.cur, "m%d", &n);
945         eb = eina_list_nth(cfdata->binding.mouse, n);
946         if (!eb) return;
947         ctxt = eb->context;
948      }
949    else if (cfdata->locals.cur[0] == 'w')
950      {
951         sscanf(cfdata->locals.cur, "w%d", &n);
952         bw = eina_list_nth(cfdata->binding.wheel, n);
953         if (!bw) return;
954         ctxt = bw->context;
955      }
956    else
957      return;
958 
959    e_widget_disabled_set(cfdata->gui.context.o_any, 0);
960    e_widget_disabled_set(cfdata->gui.context.o_window, 0);
961    e_widget_disabled_set(cfdata->gui.context.o_menu, 0);
962    e_widget_disabled_set(cfdata->gui.context.o_winlist, 0);
963    e_widget_disabled_set(cfdata->gui.context.o_popup, 0);
964    e_widget_disabled_set(cfdata->gui.context.o_zone, 0);
965    e_widget_disabled_set(cfdata->gui.context.o_container, 0);
966    e_widget_disabled_set(cfdata->gui.context.o_manager, 0);
967    e_widget_disabled_set(cfdata->gui.context.o_none, 0);
968 
969    if (ctxt == E_BINDING_CONTEXT_ANY)
970      e_widget_radio_toggle_set(cfdata->gui.context.o_any, 1);
971    else if (ctxt == E_BINDING_CONTEXT_WINDOW)
972      e_widget_radio_toggle_set(cfdata->gui.context.o_window, 1);
973    else if (ctxt == E_BINDING_CONTEXT_MENU)
974      e_widget_radio_toggle_set(cfdata->gui.context.o_menu, 1);
975    else if (ctxt == E_BINDING_CONTEXT_WINLIST)
976      e_widget_radio_toggle_set(cfdata->gui.context.o_winlist, 1);
977    else if (ctxt == E_BINDING_CONTEXT_POPUP)
978      e_widget_radio_toggle_set(cfdata->gui.context.o_popup, 1);
979    else if (ctxt == E_BINDING_CONTEXT_ZONE)
980      e_widget_radio_toggle_set(cfdata->gui.context.o_zone, 1);
981    else if (ctxt == E_BINDING_CONTEXT_COMPOSITOR)
982      e_widget_radio_toggle_set(cfdata->gui.context.o_container, 1);
983    else if (ctxt == E_BINDING_CONTEXT_MANAGER)
984      e_widget_radio_toggle_set(cfdata->gui.context.o_manager, 1);
985    else if (ctxt == E_BINDING_CONTEXT_NONE)
986      e_widget_radio_toggle_set(cfdata->gui.context.o_none, 1);
987 }
988 
989 /****************** Helper *****************/
990 static void
_auto_apply_changes(E_Config_Dialog_Data * cfdata)991 _auto_apply_changes(E_Config_Dialog_Data *cfdata)
992 {
993    int n, g, a;
994    E_Config_Binding_Mouse *eb = NULL;
995    E_Config_Binding_Wheel *bw = NULL;
996 
997    E_Action_Group *actg;
998    E_Action_Description *actd;
999    const char **action = NULL, **params = NULL;
1000 
1001    if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0])) return;
1002 
1003    if (cfdata->locals.cur[0] == 'm')
1004      {
1005         sscanf(cfdata->locals.cur, "m%d", &n);
1006         eb = eina_list_nth(cfdata->binding.mouse, n);
1007         if (!eb) return;
1008 
1009         eb->context = cfdata->locals.context;
1010         action = &(eb->action);
1011         params = &(eb->params);
1012      }
1013    else if (cfdata->locals.cur[0] == 'w')
1014      {
1015         sscanf(cfdata->locals.cur, "w%d", &n);
1016         bw = eina_list_nth(cfdata->binding.wheel, n);
1017         if (!bw) return;
1018 
1019         bw->context = cfdata->locals.context;
1020         action = &(bw->action);
1021         params = &(bw->params);
1022      }
1023    else return;
1024 
1025    if (action && *action) eina_stringshare_del(*action);
1026    if (params && *params) eina_stringshare_del(*params);
1027    if (action) *action = NULL;
1028    if (params) *params = NULL;
1029 
1030    if ((!cfdata->locals.action) || (!cfdata->locals.action[0])) return;
1031 
1032    sscanf(cfdata->locals.action, "%d %d", &g, &a);
1033 
1034    actg = eina_list_nth(e_action_groups_get(), g);
1035    if (!actg) return;
1036    actd = eina_list_nth(actg->acts, a);
1037    if (!actd) return;
1038 
1039    if (actd->act_cmd) *action = eina_stringshare_add(actd->act_cmd);
1040    if (actd->act_params)
1041      *params = eina_stringshare_add(actd->act_params);
1042    else
1043      {
1044         int ok = 1;
1045         if (cfdata->locals.params)
1046           {
1047              if (!strcmp(cfdata->locals.params, TEXT_NO_PARAMS)) ok = 0;
1048 
1049              if ((actd->param_example) && (!strcmp(cfdata->locals.params, actd->param_example)))
1050                ok = 0;
1051           }
1052         else
1053           ok = 0;
1054 
1055         if (ok)
1056           *params = eina_stringshare_add(cfdata->locals.params);
1057      }
1058 }
1059 
1060 static void
_find_key_binding_action(const char * action,const char * params,int * g,int * a,int * n)1061 _find_key_binding_action(const char *action, const char *params, int *g, int *a, int *n)
1062 {
1063    Eina_List *l, *l2;
1064    int gg = -1, aa = -1, nn = -1, found;
1065    E_Action_Group *actg;
1066    E_Action_Description *actd;
1067 
1068    if (g) *g = -1;
1069    if (a) *a = -1;
1070    if (n) *n = -1;
1071 
1072    found = 0;
1073    for (l = e_action_groups_get(), gg = 0, nn = 0; l; l = l->next, gg++)
1074      {
1075         actg = l->data;
1076 
1077         for (l2 = actg->acts, aa = 0; l2; l2 = l2->next, aa++)
1078           {
1079              actd = l2->data;
1080 
1081              if (!strcmp((!action ? "" : action), (!actd->act_cmd ? "" : actd->act_cmd)))
1082                {
1083                   if (!params || !params[0])
1084                     {
1085                        if ((!actd->act_params) || (!actd->act_params[0]))
1086                          {
1087                             if (g) *g = gg;
1088                             if (a) *a = aa;
1089                             if (n) *n = nn;
1090                             return;
1091                          }
1092                        else
1093                          continue;
1094                     }
1095                   else
1096                     {
1097                        if ((!actd->act_params) || (!actd->act_params[0]))
1098                          {
1099                             if (g) *g = gg;
1100                             if (a) *a = aa;
1101                             if (n) *n = nn;
1102                             found = 1;
1103                          }
1104                        else
1105                          {
1106                             if (!strcmp(params, actd->act_params))
1107                               {
1108                                  if (g) *g = gg;
1109                                  if (a) *a = aa;
1110                                  if (n) *n = nn;
1111                                  return;
1112                               }
1113                          }
1114                     }
1115                }
1116              nn++;
1117           }
1118         if (found) break;
1119      }
1120 
1121    if (!found)
1122      {
1123         if (g) *g = -1;
1124         if (a) *a = -1;
1125         if (n) *n = -1;
1126      }
1127 }
1128 
1129 static char *
_helper_button_name_get(E_Config_Binding_Mouse * eb)1130 _helper_button_name_get(E_Config_Binding_Mouse *eb)
1131 {
1132    char *name = NULL;
1133    char buf[1024];
1134 
1135    switch (eb->button)
1136      {
1137       case 1:
1138         if (e_config->mouse_hand == E_MOUSE_HAND_RIGHT)
1139           name = strdup(_("Left button"));
1140         else if (e_config->mouse_hand == E_MOUSE_HAND_LEFT)
1141           name = strdup(_("Right button"));
1142         else
1143           {
1144              snprintf(buf, sizeof(buf), _("Button %i"), eb->button);
1145              name = strdup(buf);
1146           }
1147         break;
1148 
1149       case 2:
1150         name = strdup(_("Middle button"));
1151         break;
1152 
1153       case 3:
1154         if (e_config->mouse_hand == E_MOUSE_HAND_RIGHT)
1155           name = strdup(_("Right button"));
1156         else if (e_config->mouse_hand == E_MOUSE_HAND_LEFT)
1157           name = strdup(_("Left button"));
1158         else
1159           {
1160              snprintf(buf, sizeof(buf), _("Button %i"), eb->button);
1161              name = strdup(buf);
1162           }
1163         break;
1164 
1165       case 4:
1166       case 5:
1167       case 6:
1168       case 7:
1169         break;
1170 
1171       default:
1172         snprintf(buf, sizeof(buf), _("Extra button (%d)"), eb->button);
1173         name = strdup(buf);
1174      }
1175    return name;
1176 }
1177 
1178 static char *
_helper_wheel_name_get(E_Config_Binding_Wheel * bw)1179 _helper_wheel_name_get(E_Config_Binding_Wheel *bw)
1180 {
1181    char *name = NULL;
1182    char buf[1024] = "";
1183 
1184    switch (bw->direction)
1185      {
1186       case 0:
1187 	 if (bw->z < 0)
1188 	   name = strdup(_("Mouse Wheel Up"));
1189 	 else
1190 	   name = strdup(_("Mouse Wheel Down"));
1191 	 break;
1192       default:
1193 	 if (bw->z < 0)
1194 	   snprintf(buf, sizeof(buf), _("Extra Wheel (%d) Up"), bw->direction);
1195 	 else
1196 	   snprintf(buf, sizeof(buf), _("Extra Wheel (%d) Down"), bw->direction);
1197 	 name = strdup(buf);
1198      }
1199    return name;
1200 }
1201 
1202 static char *
_helper_modifier_name_get(int mod)1203 _helper_modifier_name_get(int mod)
1204 {
1205    char mods[1024] = "";
1206 
1207    if (mod & E_BINDING_MODIFIER_SHIFT)
1208      snprintf(mods, sizeof(mods), "SHIFT");
1209 
1210    if (mod & E_BINDING_MODIFIER_CTRL)
1211      {
1212         if (mods[0]) strcat(mods, " + ");
1213         strcat(mods, "CTRL");
1214      }
1215 
1216    if (mod & E_BINDING_MODIFIER_ALT)
1217      {
1218         if (mods[0]) strcat(mods, " + ");
1219         strcat(mods, "ALT");
1220      }
1221 
1222    if (mod & E_BINDING_MODIFIER_WIN)
1223      {
1224         if (mods[0]) strcat(mods, " + ");
1225         strcat(mods, "WIN");
1226      }
1227 
1228    return strdup(mods);
1229 }
1230 
1231 /********* Sorting ***************/
1232 static int
_mouse_binding_sort_cb(const void * d1,const void * d2)1233 _mouse_binding_sort_cb(const void *d1, const void *d2)
1234 {
1235    const E_Config_Binding_Mouse *eb, *eb2;
1236 
1237    eb = d1;
1238    eb2 = d2;
1239 
1240    if (eb->button < eb2->button) return -1;
1241    else if (eb->button > eb2->button)
1242      return 1;
1243    else
1244      {
1245         if (eb->modifiers < eb2->modifiers) return -1;
1246         else if (eb->modifiers > eb2->modifiers)
1247           return 1;
1248      }
1249    return 0;
1250 }
1251 
1252 static int
_wheel_binding_sort_cb(const void * d1,const void * d2)1253 _wheel_binding_sort_cb(const void *d1, const void *d2)
1254 {
1255    const E_Config_Binding_Wheel *bw, *bw2;
1256 
1257    bw = d1;
1258    bw2 = d2;
1259 
1260    if (bw->direction < bw2->direction) return -1;
1261    else if (bw->direction > bw2->direction)
1262      return 1;
1263    else
1264      {
1265         if ((bw->z < 0) && (bw2->z > 0)) return 1;
1266         else if ((bw->z > 0) && (bw2->z < 0))
1267           return -1;
1268         else if (((bw->z < 0) && (bw2->z < 0)) ||
1269                  ((bw->z > 0) && (bw2->z > 0)))
1270           {
1271              if (bw->modifiers < bw2->modifiers) return -1;
1272              else if (bw->modifiers > bw2->modifiers)
1273                return 1;
1274           }
1275      }
1276    return 0;
1277 }
1278 
1279 
1280 static void
_grab_wnd_hide(void * data)1281 _grab_wnd_hide(void *data)
1282 {
1283    E_Config_Dialog_Data *cfdata;
1284 
1285    cfdata = e_object_data_get(data);
1286    cfdata->locals.eg = NULL;
1287 }
1288 
1289 static void
_grab_wnd_show(E_Config_Dialog_Data * cfdata)1290 _grab_wnd_show(E_Config_Dialog_Data *cfdata)
1291 {
1292    if (cfdata->locals.eg) return;
1293    cfdata->locals.eg = e_grab_dialog_show(cfdata->cfd->dia->win, EINA_TRUE, NULL, _grab_mouse_down_cb, _grab_mouse_wheel_cb, cfdata);
1294    e_object_data_set(E_OBJECT(cfdata->locals.eg), cfdata);
1295    e_object_del_attach_func_set(E_OBJECT(cfdata->locals.eg), _grab_wnd_hide);
1296 }
1297 
1298 static Eina_Bool
_grab_mouse_down_cb(void * data,EINA_UNUSED int type,void * event)1299 _grab_mouse_down_cb(void *data, EINA_UNUSED int type, void *event)
1300 {
1301    Eina_List *l;
1302    E_Config_Dialog_Data *cfdata;
1303    E_Config_Binding_Mouse *eb = NULL;
1304    E_Config_Binding_Wheel *bw;
1305    int mod = E_BINDING_MODIFIER_NONE, n;
1306    Ecore_Event_Mouse_Button *ev;
1307 
1308    ev = event;
1309    cfdata = data;
1310 
1311    if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
1312      mod |= E_BINDING_MODIFIER_SHIFT;
1313    if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
1314      mod |= E_BINDING_MODIFIER_CTRL;
1315    if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT)
1316      mod |= E_BINDING_MODIFIER_ALT;
1317    if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN)
1318      mod |= E_BINDING_MODIFIER_WIN;
1319 
1320    if (cfdata->locals.add)
1321      {
1322         eb = E_NEW(E_Config_Binding_Mouse, 1);
1323         eb->context = E_BINDING_CONTEXT_ANY;
1324         eb->button = ev->buttons;
1325         eb->modifiers = mod;
1326         eb->any_mod = 0;
1327         eb->action = NULL;
1328         eb->params = NULL;
1329 
1330         cfdata->binding.mouse = eina_list_append(cfdata->binding.mouse, eb);
1331      }
1332    else
1333      {
1334         if (cfdata->locals.cur[0] == 'm')
1335           {
1336              sscanf(cfdata->locals.cur, "m%d", &n);
1337              eb = eina_list_nth(cfdata->binding.mouse, n);
1338              if (eb)
1339                {
1340                   eb->button = ev->buttons;
1341                   eb->modifiers = mod;
1342                }
1343           }
1344         else if (cfdata->locals.cur[0] == 'w')
1345           {
1346              sscanf(cfdata->locals.cur, "w%d", &n);
1347              l = eina_list_nth_list(cfdata->binding.wheel, n);
1348              bw = eina_list_data_get(l);
1349 
1350              eb = E_NEW(E_Config_Binding_Mouse, 1);
1351              eb->context = bw->context;
1352              eb->button = ev->buttons;
1353              eb->modifiers = mod;
1354              eb->any_mod = 0;
1355              eb->action = bw->action;
1356              eb->params = bw->params;
1357 
1358              cfdata->binding.mouse = eina_list_append(cfdata->binding.mouse, eb);
1359 
1360              bw->action = NULL;
1361              bw->params = NULL;
1362              E_FREE(bw);
1363              cfdata->binding.wheel = eina_list_remove_list(cfdata->binding.wheel, l);
1364           }
1365      }
1366    _update_mouse_binding_list(cfdata);
1367 
1368    if (cfdata->locals.add)
1369      {
1370         for (l = cfdata->binding.mouse, n = 0; l; l = l->next, n++)
1371           if (l->data == eb) break;
1372 
1373         e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n + 1);
1374 
1375         eina_stringshare_del(cfdata->locals.action);
1376         cfdata->locals.action = eina_stringshare_add("");
1377         e_widget_ilist_unselect(cfdata->gui.o_action_list);
1378         e_widget_entry_clear(cfdata->gui.o_params);
1379         e_widget_disabled_set(cfdata->gui.o_params, 1);
1380      }
1381    else
1382      {
1383         for (l = cfdata->binding.mouse, n = 0; l; l = l->next, n++)
1384           if (l->data == eb) break;
1385 
1386         eina_stringshare_del(cfdata->locals.cur);
1387         cfdata->locals.cur = NULL;
1388 
1389         e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n + 1);
1390      }
1391    _update_buttons(cfdata);
1392    e_object_del(E_OBJECT(cfdata->locals.eg));
1393 
1394    return ECORE_CALLBACK_PASS_ON;
1395 }
1396 
1397 static Eina_Bool
_grab_mouse_wheel_cb(void * data,int type EINA_UNUSED,void * event)1398 _grab_mouse_wheel_cb(void *data, int type EINA_UNUSED, void *event)
1399 {
1400    Eina_List *l;
1401    E_Config_Binding_Wheel *bw = NULL;
1402    E_Config_Binding_Mouse *eb = NULL;
1403    E_Config_Dialog_Data *cfdata;
1404    Ecore_Event_Mouse_Wheel *ev;
1405    int mod = E_BINDING_MODIFIER_NONE, n;
1406 
1407    ev = event;
1408    cfdata = data;
1409 
1410    if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
1411      mod |= E_BINDING_MODIFIER_SHIFT;
1412    if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
1413      mod |= E_BINDING_MODIFIER_CTRL;
1414    if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT)
1415      mod |= E_BINDING_MODIFIER_ALT;
1416    if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN)
1417      mod |= E_BINDING_MODIFIER_WIN;
1418 
1419    if (cfdata->locals.add)
1420      {
1421         bw = E_NEW(E_Config_Binding_Wheel, 1);
1422         bw->context = E_BINDING_CONTEXT_ANY;
1423         bw->direction = ev->direction;
1424         bw->z = ev->z;
1425         bw->modifiers = mod;
1426         bw->any_mod = 0;
1427         bw->action = NULL;
1428         bw->params = NULL;
1429 
1430         cfdata->binding.wheel = eina_list_append(cfdata->binding.wheel, bw);
1431      }
1432    else
1433      {
1434         if (cfdata->locals.cur[0] == 'm')
1435           {
1436              sscanf(cfdata->locals.cur, "m%d", &n);
1437              l = eina_list_nth_list(cfdata->binding.mouse, n);
1438              eb = eina_list_data_get(l);
1439 
1440              bw = E_NEW(E_Config_Binding_Wheel, 1);
1441              bw->context = eb->context;
1442              bw->direction = ev->direction;
1443              bw->z = ev->z;
1444              bw->modifiers = mod;
1445              bw->any_mod = 0;
1446              bw->action = eb->action;
1447              bw->params = eb->params;
1448 
1449              cfdata->binding.wheel = eina_list_append(cfdata->binding.wheel, bw);
1450 
1451              E_FREE(eb);
1452              cfdata->binding.mouse = eina_list_remove_list(cfdata->binding.mouse, l);
1453           }
1454         else if (cfdata->locals.cur[0] == 'w')
1455           {
1456              sscanf(cfdata->locals.cur, "w%d", &n);
1457              bw = eina_list_nth(cfdata->binding.wheel, n);
1458              if (bw)
1459                {
1460                   bw->direction = ev->direction;
1461                   bw->z = ev->z;
1462                   bw->modifiers = mod;
1463                }
1464           }
1465      }
1466    _update_mouse_binding_list(cfdata);
1467 
1468    if (cfdata->locals.add)
1469      {
1470         for (l = cfdata->binding.wheel, n = 0; l; l = l->next, n++)
1471           if (l->data == bw) break;
1472 
1473         if (eina_list_count(cfdata->binding.mouse))
1474           {
1475              n += eina_list_count(cfdata->binding.mouse) + 2;
1476              e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n);
1477           }
1478         else
1479           e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n + 1);
1480 
1481         e_widget_ilist_unselect(cfdata->gui.o_action_list);
1482         eina_stringshare_del(cfdata->locals.action);
1483         cfdata->locals.action = eina_stringshare_add("");
1484         e_widget_entry_clear(cfdata->gui.o_params);
1485         e_widget_disabled_set(cfdata->gui.o_params, 1);
1486      }
1487    else
1488      {
1489         for (l = cfdata->binding.wheel, n = 0; l; l = l->next, n++)
1490           if (l->data == bw) break;
1491 
1492         eina_stringshare_del(cfdata->locals.cur);
1493         cfdata->locals.cur = NULL;
1494 
1495         if (eina_list_count(cfdata->binding.mouse))
1496           {
1497              n += eina_list_count(cfdata->binding.mouse) + 2;
1498              e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n);
1499           }
1500         else
1501           e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n + 1);
1502      }
1503    _update_buttons(cfdata);
1504 
1505    e_object_del(E_OBJECT(cfdata->locals.eg));
1506    return ECORE_CALLBACK_PASS_ON;
1507 }
1508