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