#include "e.h" #define TEXT_NO_PARAMS _("") struct _E_Config_Dialog_Data { Evas *evas; struct { Eina_List *swipe; } binding; struct { const char *binding, *action; char *params; const char *cur; int button; int cur_act; const char *swipe; const char *source; E_Dialog *dia; double degree; double error; double length; unsigned int fingers; int gesture_open_input_devices; } locals; struct { Evas_Object *o_add, *o_del, *o_del_all; Evas_Object *o_binding_list, *o_action_list; Evas_Object *o_params, *o_selector; } gui; const char *params; int fullscreen_flip; int multiscreen_flip; E_Config_Dialog *cfd; }; static E_Config_Binding_Swipe * _swipe_binding_copy(E_Config_Binding_Swipe *bi) { E_Config_Binding_Swipe *bi2; if (!bi) return NULL; bi2 = E_NEW(E_Config_Binding_Swipe, 1); bi2->context = bi->context; bi2->direction = bi->direction; bi2->length = bi->length; bi2->fingers = bi->fingers; bi2->error = bi->error; bi2->action = bi->action; bi2->params = bi->params; return bi2; } static void _swipe_binding_free(E_Config_Binding_Swipe *bi) { if (!bi) return; eina_stringshare_del(bi->action); eina_stringshare_del(bi->params); free(bi); } static void _auto_apply_changes(E_Config_Dialog_Data *cfdata) { int n, g, a, ok; E_Config_Binding_Swipe *bi; E_Action_Group *actg; E_Action_Description *actd; if (cfdata->locals.gesture_open_input_devices != e_config->gesture_open_input_devices) { E_Action *act; e_config->gesture_open_input_devices = cfdata->locals.gesture_open_input_devices; act = e_action_find("restart"); if ((act) && (act->func.go)) act->func.go(NULL, NULL); } if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0]) || (!cfdata->locals.action) || (!cfdata->locals.action[0])) return; if (sscanf(cfdata->locals.cur, "s%d", &n) != 1) return; if (sscanf(cfdata->locals.action, "%d %d", &g, &a) != 2) return; bi = eina_list_nth(cfdata->binding.swipe, n); if (!bi) return; actg = eina_list_nth(e_action_groups_get(), g); if (!actg) return; actd = eina_list_nth(actg->acts, a); if (!actd) return; eina_stringshare_del(bi->action); bi->action = NULL; if (actd->act_cmd) bi->action = eina_stringshare_add(actd->act_cmd); eina_stringshare_del(bi->params); bi->params = NULL; if (actd->act_params) bi->params = eina_stringshare_add(actd->act_params); else { ok = 1; if (cfdata->locals.params) { if (!strcmp(cfdata->locals.params, TEXT_NO_PARAMS)) ok = 0; if ((actd->param_example) && (!strcmp(cfdata->locals.params, actd->param_example))) ok = 0; } else ok = 0; if (ok) bi->params = eina_stringshare_add(cfdata->locals.params); } } static void _fill_data(E_Config_Dialog_Data *cfdata) { E_Config_Binding_Swipe *bi, *bi2; Eina_List *l; cfdata->locals.params = strdup(""); cfdata->locals.action = eina_stringshare_add(""); cfdata->locals.binding = eina_stringshare_add(""); cfdata->locals.swipe = eina_stringshare_add(""); cfdata->locals.source = eina_stringshare_add(""); cfdata->locals.cur = NULL; cfdata->locals.dia = NULL; cfdata->locals.gesture_open_input_devices = e_config->gesture_open_input_devices; cfdata->binding.swipe = NULL; EINA_LIST_FOREACH(e_bindings->swipe_bindings, l, bi) { if (!bi) continue; bi2 = _swipe_binding_copy(bi); cfdata->binding.swipe = eina_list_append(cfdata->binding.swipe, bi2); } } static void * _create_data(E_Config_Dialog *cfd) { E_Config_Dialog_Data *cfdata; cfdata = E_NEW(E_Config_Dialog_Data, 1); cfdata->cfd = cfd; _fill_data(cfdata); return cfdata; } static void _free_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata) { E_FREE_LIST(cfdata->binding.swipe, _swipe_binding_free); eina_stringshare_del(cfdata->locals.cur); eina_stringshare_del(cfdata->params); eina_stringshare_del(cfdata->locals.binding); eina_stringshare_del(cfdata->locals.action); eina_stringshare_del(cfdata->locals.swipe); eina_stringshare_del(cfdata->locals.source); if (cfdata->locals.dia) e_object_del(E_OBJECT(cfdata->locals.dia)); free(cfdata->locals.params); E_FREE(cfdata); } static void _update_action_params(E_Config_Dialog_Data *cfdata) { int g, a, b; E_Action_Group *actg; E_Action_Description *actd; E_Config_Binding_Swipe *bi; const char *action, *params; #define SIGNAL_EXAMPLE_PARAMS \ if ((!actd->param_example) || (!actd->param_example[0])) \ e_widget_entry_text_set(cfdata->gui.o_params, TEXT_NO_PARAMS); \ else \ e_widget_entry_text_set(cfdata->gui.o_params, actd->param_example) if ((!cfdata->locals.action) || (!cfdata->locals.action[0])) { e_widget_disabled_set(cfdata->gui.o_params, 1); e_widget_entry_clear(cfdata->gui.o_params); return; } if (sscanf(cfdata->locals.action, "%d %d", &g, &a) != 2) return; actg = eina_list_nth(e_action_groups_get(), g); if (!actg) return; actd = eina_list_nth(actg->acts, a); if (!actd) return; if (actd->act_params) { e_widget_disabled_set(cfdata->gui.o_params, 1); e_widget_entry_text_set(cfdata->gui.o_params, actd->act_params); return; } if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0])) { e_widget_disabled_set(cfdata->gui.o_params, 1); SIGNAL_EXAMPLE_PARAMS; return; } if (!actd->editable) e_widget_disabled_set(cfdata->gui.o_params, 1); else e_widget_disabled_set(cfdata->gui.o_params, 0); if (cfdata->locals.cur[0] == 's') { if (sscanf(cfdata->locals.cur, "s%d", &b) != 1) { e_widget_disabled_set(cfdata->gui.o_params, 1); SIGNAL_EXAMPLE_PARAMS; return; } bi = eina_list_nth(cfdata->binding.swipe, b); if (!bi) { e_widget_disabled_set(cfdata->gui.o_params, 1); SIGNAL_EXAMPLE_PARAMS; return; } action = bi->action; params = bi->params; } else { e_widget_disabled_set(cfdata->gui.o_params, 1); SIGNAL_EXAMPLE_PARAMS; return; } if (action) { if (!strcmp(action, actd->act_cmd)) { if ((!params) || (!params[0])) SIGNAL_EXAMPLE_PARAMS; else e_widget_entry_text_set(cfdata->gui.o_params, params); } else SIGNAL_EXAMPLE_PARAMS; } else SIGNAL_EXAMPLE_PARAMS; } static void _action_change_cb(void *data) { E_Config_Dialog_Data *cfdata; cfdata = data; _update_action_params(cfdata); } static int _swipe_binding_sort_cb(E_Config_Binding_Swipe *a, E_Config_Binding_Swipe *b) { int finger_diff = a->fingers - b->fingers; if (!finger_diff) { return a->direction - b->direction; } return finger_diff*-1; } static void _update_buttons(E_Config_Dialog_Data *cfdata) { if (e_widget_ilist_count(cfdata->gui.o_binding_list)) e_widget_disabled_set(cfdata->gui.o_del_all, 0); else e_widget_disabled_set(cfdata->gui.o_del_all, 1); if (!cfdata->locals.cur) { e_widget_disabled_set(cfdata->gui.o_del, 1); return; } e_widget_disabled_set(cfdata->gui.o_del, 0); } static void _find_swipe_binding_action(const char *action, const char *params, int *g, int *a, int *n) { Eina_List *l, *l2; int gg = -1, aa = -1, nn = -1, found; E_Action_Group *actg; E_Action_Description *actd; if (g) *g = -1; if (a) *a = -1; if (n) *n = -1; found = 0; for (l = e_action_groups_get(), gg = 0, nn = 0; l; l = l->next, gg++) { actg = l->data; for (l2 = actg->acts, aa = 0; l2; l2 = l2->next, aa++) { actd = l2->data; if (!strcmp((!action ? "" : action), (!actd->act_cmd ? "" : actd->act_cmd))) { if (!params || !params[0]) { if ((!actd->act_params) || (!actd->act_params[0])) { if (g) *g = gg; if (a) *a = aa; if (n) *n = nn; return; } else continue; } else { if ((!actd->act_params) || (!actd->act_params[0])) { if (g) *g = gg; if (a) *a = aa; if (n) *n = nn; found = 1; } else { if (!strcmp(params, actd->act_params)) { if (g) *g = gg; if (a) *a = aa; if (n) *n = nn; return; } } } } nn++; } if (found) break; } if (!found) { if (g) *g = -1; if (a) *a = -1; if (n) *n = -1; } } static void _update_action_list(E_Config_Dialog_Data *cfdata) { E_Config_Binding_Swipe *bi; int j = -1, i, n; const char *action, *params; if (!cfdata->locals.cur) return; if (cfdata->locals.cur[0] == 's') { if (sscanf(cfdata->locals.cur, "s%d", &n) != 1) return; bi = eina_list_nth(cfdata->binding.swipe, n); if (!bi) { e_widget_ilist_unselect(cfdata->gui.o_action_list); e_widget_entry_clear(cfdata->gui.o_params); e_widget_disabled_set(cfdata->gui.o_params, 1); return; } action = bi->action; params = bi->params; } else return; _find_swipe_binding_action(action, params, NULL, NULL, &j); if (j >= 0) { for (i = 0; i < e_widget_ilist_count(cfdata->gui.o_action_list); i++) { if (i > j) break; if (e_widget_ilist_nth_is_header(cfdata->gui.o_action_list, i)) j++; } } if (j >= 0) { if (j == e_widget_ilist_selected_get(cfdata->gui.o_action_list)) _update_action_params(cfdata); else e_widget_ilist_selected_set(cfdata->gui.o_action_list, j); } else { e_widget_ilist_unselect(cfdata->gui.o_action_list); eina_stringshare_del(cfdata->locals.action); cfdata->locals.action = eina_stringshare_add(""); e_widget_entry_clear(cfdata->gui.o_params); } } static void _binding_change_cb(void *data) { E_Config_Dialog_Data *cfdata; cfdata = data; _auto_apply_changes(cfdata); if (cfdata->locals.cur) eina_stringshare_del(cfdata->locals.cur); cfdata->locals.cur = NULL; if ((!cfdata->locals.binding) || (!cfdata->locals.binding[0])) return; cfdata->locals.cur = eina_stringshare_ref(cfdata->locals.binding); _update_buttons(cfdata); _update_action_list(cfdata); } static int _basic_apply_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata) { Eina_List *l; E_Config_Binding_Swipe *bi, *bi2; _auto_apply_changes(cfdata); E_FREE_LIST(e_bindings->swipe_bindings, _swipe_binding_free); EINA_LIST_FOREACH(cfdata->binding.swipe, l, bi2) { bi = _swipe_binding_copy(bi2); e_bindings->swipe_bindings = eina_list_append(e_bindings->swipe_bindings, bi); } e_bindings_swipe_reset(); e_config_save_queue(); return 1; } static Evas_Object* create_visualisation(Evas *e, double direction, double error) { Evas_Vg_Container *vg = NULL; Evas_Vg_Shape *container, *shape, *viewport = NULL; double center_x = 15, center_y = 15; vg = evas_object_vg_add(e); evas_object_vg_viewbox_set(vg, EINA_RECT(0, 0, 50, 50)); container = evas_vg_container_add(vg); viewport = evas_vg_shape_add(container); evas_vg_shape_append_rect(viewport, 0, 0, 51, 51, 0, 0); evas_vg_shape_stroke_cap_set(viewport, EVAS_VG_CAP_SQUARE); evas_vg_shape_stroke_color_set(viewport, 0, 0, 0, 0); evas_vg_shape_stroke_width_set(viewport, 1); shape = evas_vg_shape_add(container); evas_vg_shape_append_rect(shape, 1, 1, 29, 29, 0, 0); evas_vg_shape_stroke_cap_set(shape, EVAS_VG_CAP_SQUARE); evas_vg_shape_stroke_color_set(shape, 100, 100, 100, 255); evas_vg_shape_stroke_width_set(shape, 1); shape = evas_vg_shape_add(container); evas_vg_shape_append_line_to(shape, center_x, center_y); evas_vg_shape_append_line_to(shape, center_x + cos(direction - error)*11, center_y + sin(direction - error)*11); evas_vg_shape_append_arc_to(shape, center_x + cos(direction + error)*11, center_y + sin(direction + error)*11, 11, 11, 0, EINA_FALSE, EINA_TRUE); evas_vg_shape_append_line_to(shape, center_x, center_y); evas_vg_shape_stroke_cap_set(shape, EVAS_VG_CAP_ROUND); evas_vg_shape_stroke_color_set(shape, 255, 0, 0, 255); evas_vg_shape_stroke_width_set(shape, 2); evas_object_vg_root_node_set(vg, container); evas_object_show(vg); return vg; } static void _update_swipe_binding_list(E_Config_Dialog_Data *cfdata) { int i = 0; char b2[64], b3[64]; Eina_List *l; E_Config_Binding_Swipe *bi; unsigned int previous_fingers = 0; evas_event_freeze(evas_object_evas_get(cfdata->gui.o_binding_list)); edje_freeze(); e_widget_ilist_freeze(cfdata->gui.o_binding_list); e_widget_ilist_clear(cfdata->gui.o_binding_list); e_widget_ilist_go(cfdata->gui.o_binding_list); if (cfdata->binding.swipe) cfdata->binding.swipe = eina_list_sort(cfdata->binding.swipe, 0, (Eina_Compare_Cb)_swipe_binding_sort_cb); EINA_LIST_FOREACH(cfdata->binding.swipe, l, bi) { Evas_Object *vis; vis = create_visualisation(evas_object_evas_get(cfdata->gui.o_binding_list), bi->direction, bi->error); if (bi->fingers != previous_fingers) { snprintf(b3, sizeof(b3), "%d Fingers", bi->fingers); previous_fingers = bi->fingers; e_widget_ilist_header_append(cfdata->gui.o_binding_list, NULL, b3); } snprintf(b2, sizeof(b2), "s%d", i); snprintf(b3, sizeof(b3), "Length: %.2f Error: %.2f", bi->length, bi->error); e_widget_ilist_append(cfdata->gui.o_binding_list, vis, b3, _binding_change_cb, cfdata, b2); i++; } e_widget_ilist_go(cfdata->gui.o_binding_list); e_widget_ilist_thaw(cfdata->gui.o_binding_list); edje_thaw(); evas_event_thaw(evas_object_evas_get(cfdata->gui.o_binding_list)); if (eina_list_count(cfdata->binding.swipe)) e_widget_disabled_set(cfdata->gui.o_del_all, 0); else e_widget_disabled_set(cfdata->gui.o_del_all, 1); } static void _fill_actions_list(E_Config_Dialog_Data *cfdata) { char buf[1024]; Eina_List *l, *l2; E_Action_Group *actg; E_Action_Description *actd; int g, a; evas_event_freeze(evas_object_evas_get(cfdata->gui.o_action_list)); edje_freeze(); e_widget_ilist_freeze(cfdata->gui.o_action_list); e_widget_ilist_clear(cfdata->gui.o_action_list); for (l = e_action_groups_get(), g = 0; l; l = l->next, g++) { actg = l->data; if (!actg->acts) continue; e_widget_ilist_header_append(cfdata->gui.o_action_list, NULL, _(actg->act_grp)); for (l2 = actg->acts, a = 0; l2; l2 = l2->next, a++) { actd = l2->data; snprintf(buf, sizeof(buf), "%d %d", g, a); e_widget_ilist_append(cfdata->gui.o_action_list, NULL, _(actd->act_name), _action_change_cb, cfdata, buf); } } e_widget_ilist_go(cfdata->gui.o_action_list); e_widget_ilist_thaw(cfdata->gui.o_action_list); edje_thaw(); evas_event_thaw(evas_object_evas_get(cfdata->gui.o_action_list)); } static void _flush_binding_swipe(E_Config_Dialog_Data *cfdata) { E_Config_Binding_Swipe *bi; bi = E_NEW(E_Config_Binding_Swipe, 1); bi->context = E_BINDING_CONTEXT_NONE; bi->length = cfdata->locals.length; bi->direction = cfdata->locals.degree; bi->error = cfdata->locals.error; bi->fingers = cfdata->locals.fingers; cfdata->binding.swipe = eina_list_append(cfdata->binding.swipe, bi); _update_swipe_binding_list(cfdata); } static void _swipe_add_cb_ok(void *data, E_Dialog *dia) { E_Config_Dialog_Data *cfdata = data; _flush_binding_swipe(cfdata); e_object_del(E_OBJECT(dia)); } static void _swipe_add_cb_cancel(void *data EINA_UNUSED, E_Dialog *dia) { e_object_del(E_OBJECT(dia)); } static void _swipe_add_del(void *data) { E_Dialog *dia = data; E_Config_Dialog_Data *cfdata; if (!dia->data) return; cfdata = dia->data; cfdata->locals.dia = NULL; } static void _double_getter(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) { double *container = data; double tmp = elm_spinner_value_get(obj); *container = tmp; } static void _int_getter(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) { unsigned int *container = data; double tmp = elm_spinner_value_get(obj); *container = tmp; } static void _swipe_add_show(E_Config_Dialog_Data *cfdata) { Evas_Object *o, *obg, *ol, *entry; Evas *evas; int w, h; if (cfdata->locals.dia) return; cfdata->locals.dia = e_dialog_new(cfdata->cfd->dia->win, "E", "_swipebind_new_dialog"); e_dialog_resizable_set(cfdata->locals.dia, 1); e_dialog_title_set(cfdata->locals.dia, _("Add Swipe Binding")); e_dialog_icon_set(cfdata->locals.dia, "enlightenment/swipes", 48); e_dialog_button_add(cfdata->locals.dia, _("OK"), NULL, _swipe_add_cb_ok, cfdata); e_dialog_button_add(cfdata->locals.dia, _("Cancel"), NULL, _swipe_add_cb_cancel, cfdata); e_object_del_attach_func_set(E_OBJECT(cfdata->locals.dia), _swipe_add_del); cfdata->locals.dia->data = cfdata; elm_win_center(cfdata->locals.dia->win, 1, 1); evas = evas_object_evas_get(cfdata->locals.dia->win); obg = e_widget_list_add(evas, 1, 0); ol = e_widget_framelist_add(evas, _("Direction:"), 0); entry = o = elm_spinner_add(cfdata->locals.dia->win); evas_object_smart_callback_add(o, "changed", _double_getter, &cfdata->locals.degree); elm_spinner_min_max_set(o, 0, 2*M_PI); elm_spinner_label_format_set(o, "%f"); elm_spinner_step_set(o, 0.1); elm_spinner_editable_set(o, EINA_TRUE); e_widget_framelist_object_append(ol, o); e_widget_list_object_append(obg, ol, 1, 0, 0.5); ol = e_widget_framelist_add(evas, _("Error:"), 0); entry = o = elm_spinner_add(cfdata->locals.dia->win); evas_object_smart_callback_add(o, "changed", _double_getter, &cfdata->locals.error); elm_spinner_min_max_set(o, 0, 2*M_PI); elm_spinner_label_format_set(o, "%f"); elm_spinner_step_set(o, 0.1); elm_spinner_editable_set(o, EINA_TRUE); e_widget_framelist_object_append(ol, o); e_widget_list_object_append(obg, ol, 1, 0, 0.5); ol = e_widget_framelist_add(evas, _("Length:"), 0); entry = o = elm_spinner_add(cfdata->locals.dia->win); evas_object_smart_callback_add(o, "changed", _double_getter, &cfdata->locals.length); elm_spinner_min_max_set(o, 0, 200); elm_spinner_step_set(o, 5); elm_spinner_editable_set(o, EINA_TRUE); e_widget_framelist_object_append(ol, o); e_widget_list_object_append(obg, ol, 1, 0, 0.5); cfdata->locals.fingers = 3; ol = e_widget_framelist_add(evas, _("Fingers:"), 0); entry = o = elm_spinner_add(cfdata->locals.dia->win); evas_object_smart_callback_add(o, "changed", _int_getter, &cfdata->locals.fingers); elm_spinner_min_max_set(o, 3, 10); elm_spinner_value_set(o, 3.0); elm_spinner_editable_set(o, EINA_TRUE); e_widget_framelist_object_append(ol, o); e_widget_list_object_append(obg, ol, 1, 0, 0.5); e_widget_size_min_get(obg, &w, &h); e_dialog_content_set(cfdata->locals.dia, obg, MAX(w, 200), MAX(h, 100)); e_dialog_show(cfdata->locals.dia); e_widget_focus_set(entry, 1); } static void _add_swipe_binding_cb(void *data, void *data2 EINA_UNUSED) { E_Config_Dialog_Data *cfdata = data; _auto_apply_changes(cfdata); _swipe_add_show(cfdata); } static void _update_swipe_cb(void *data, Eina_Bool end, double direction, double length, double error, unsigned int fingers) { E_Config_Dialog_Data *cfdata = data; if (end) { e_object_del(E_OBJECT(cfdata->locals.dia)); cfdata->locals.dia = NULL; cfdata->locals.degree = direction; cfdata->locals.length = length; cfdata->locals.error = error; cfdata->locals.fingers = fingers; _flush_binding_swipe(cfdata); e_bindings_swipe_live_update_hook_set(NULL, NULL); } else { char text_buf[1000]; Evas_Object *vis; vis = create_visualisation(evas_object_evas_get(cfdata->locals.dia->win), direction, error); evas_object_size_hint_align_set(vis, 0.0, 0.5); snprintf(text_buf, sizeof(text_buf), _("Using %d Fingers
Direction %f Length %f Error %f"), fingers, direction, length, error); e_dialog_text_set(cfdata->locals.dia, text_buf); elm_object_part_content_set(cfdata->locals.dia->bg_object, "e.swallow.icon", vis); evas_object_size_hint_min_set(vis, 30 * e_scale, 30 * e_scale); elm_layout_signal_emit(cfdata->locals.dia->bg_object, "e,state,icon", "e"); elm_layout_signal_emit(cfdata->locals.dia->bg_object, "e,icon,enabled", "e"); } } static void _add_swipe_binding_by_sample_cb(void *data, void *data2 EINA_UNUSED) { E_Config_Dialog_Data *cfdata = data; cfdata->locals.dia = e_dialog_new(cfdata->cfd->dia->win, "E", "_swipe_recognition"); e_dialog_icon_set(cfdata->locals.dia, "preferences-desktop-swipe-bindings", 48); e_dialog_title_set(cfdata->locals.dia, _("Swipe recognition")); e_dialog_text_set(cfdata->locals.dia, _("Do your swipe gesture.

Press Escape to abort")); elm_win_center(cfdata->locals.dia->win, 1, 1); elm_win_borderless_set(cfdata->locals.dia->win, 1); e_dialog_resizable_set(cfdata->locals.dia, 0); e_dialog_show(cfdata->locals.dia); evas_object_layer_set(e_win_client_get(cfdata->locals.dia->win)->frame, E_LAYER_CLIENT_PRIO); e_bindings_swipe_live_update_hook_set(_update_swipe_cb, data); } static void _delete_swipe_binding_cb(void *data, void *data2 EINA_UNUSED) { Eina_List *l = NULL; int sel, n; E_Config_Dialog_Data *cfdata; cfdata = data; sel = e_widget_ilist_selected_get(cfdata->gui.o_binding_list); if (cfdata->locals.binding[0] == 's') { if (sscanf(cfdata->locals.binding, "s%d", &n) != 1) return; l = eina_list_nth_list(cfdata->binding.swipe, n); if (l) { _swipe_binding_free(eina_list_data_get(l)); cfdata->binding.swipe = eina_list_remove_list(cfdata->binding.swipe, l); } } _update_swipe_binding_list(cfdata); if (sel >= e_widget_ilist_count(cfdata->gui.o_binding_list)) sel = e_widget_ilist_count(cfdata->gui.o_binding_list) - 1; eina_stringshare_del(cfdata->locals.cur); cfdata->locals.cur = NULL; e_widget_ilist_selected_set(cfdata->gui.o_binding_list, sel); if (sel < 0) { e_widget_ilist_unselect(cfdata->gui.o_action_list); e_widget_entry_clear(cfdata->gui.o_params); e_widget_disabled_set(cfdata->gui.o_params, 1); _update_buttons(cfdata); } } static void _delete_all_swipe_binding_cb(void *data, void *data2 EINA_UNUSED) { E_Config_Binding_Swipe *bi; E_Config_Dialog_Data *cfdata; cfdata = data; EINA_LIST_FREE(cfdata->binding.swipe, bi) _swipe_binding_free(bi); eina_stringshare_del(cfdata->locals.cur); cfdata->locals.cur = NULL; e_widget_ilist_clear(cfdata->gui.o_binding_list); e_widget_ilist_go(cfdata->gui.o_binding_list); e_widget_ilist_unselect(cfdata->gui.o_action_list); e_widget_entry_clear(cfdata->gui.o_params); e_widget_disabled_set(cfdata->gui.o_params, 1); _update_buttons(cfdata); } static void _restore_swipe_binding_defaults_cb(void *data, void *data2 EINA_UNUSED) { E_Config_Bindings *ecb; Eina_Stringshare *prof; E_Config_Dialog_Data *cfdata = data; ecb = e_config_domain_system_load("e_bindings", e_config_descriptor_find("E_Config_Bindings")); if (!ecb) { const char *type; prof = eina_stringshare_ref(e_config_profile_get()); switch (e_config->config_type) { case E_CONFIG_PROFILE_TYPE_DESKTOP: type = "standard"; break; case E_CONFIG_PROFILE_TYPE_MOBILE: type = "mobile"; break; //case E_CONFIG_PROFILE_TYPE_TABLET: FIXME - not used default: type = "default"; break; } e_config_profile_set(type); ecb = e_config_domain_system_load("e_bindings", e_config_descriptor_find("E_Config_Bindings")); e_config_profile_set(prof); eina_stringshare_del(prof); } if (!ecb) return; E_FREE_LIST(cfdata->binding.swipe, e_config_binding_swipe_free); cfdata->binding.swipe = ecb->swipe_bindings, ecb->swipe_bindings = NULL; e_config_bindings_free(ecb); eina_stringshare_del(cfdata->locals.cur); cfdata->locals.cur = NULL; _update_swipe_binding_list(cfdata); _update_buttons(cfdata); e_widget_ilist_unselect(cfdata->gui.o_action_list); e_widget_entry_clear(cfdata->gui.o_params); e_widget_disabled_set(cfdata->gui.o_params, 1); } static void _close_help_dialog(void *data EINA_UNUSED, E_Dialog *dia) { e_object_del(E_OBJECT(dia)); } static void _help_swipe_bindings_cb(void *data EINA_UNUSED, void *data2 EINA_UNUSED) { E_Config_Dialog_Data *cfdata = data; E_Dialog *help = e_dialog_new(cfdata->cfd->dia->win, "E", "_swipe_recognition"); e_dialog_title_set(help, _("Swipe Bindings Help")); e_dialog_text_set(help, _("Enlightenment is using libinput to detect swipe gesture. In case there are problems:
1. Test gestures while executing \"libinput debug-events\" in terminal. The console output will tell the precision of your hardware.
2. Watch for error in console, some libinput devices are returning wrong results.
3. If your session is running inside Xorg, ensure that your user is part of the libinput group.
")); e_dialog_button_add(help, _("Close"), NULL, _close_help_dialog, help); e_dialog_show(help); } static Evas_Object * _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) { Evas_Object *o, *ol, *ot, *of, *ob, *oc; cfdata->evas = evas; o = e_widget_list_add(evas, 0, 0); ol = e_widget_list_add(evas, 0, 1); of = e_widget_frametable_add(evas, _("Swipe Bindings"), 0); ob = e_widget_ilist_add(evas, 32, 32, &(cfdata->locals.binding)); cfdata->gui.o_binding_list = ob; e_widget_size_min_set(ob, 200, 160); e_widget_frametable_object_append(of, ob, 0, 0, 2, 1, 1, 1, 1, 1); ob = e_widget_button_add(evas, _("Add"), "list-add", _add_swipe_binding_by_sample_cb, cfdata, NULL); e_widget_frametable_object_append(of, ob, 0, 1, 1, 1, 1, 0, 1, 0); ob = e_widget_button_add(evas, _("Add by props"), "list-add", _add_swipe_binding_cb, cfdata, NULL); cfdata->gui.o_add = ob; e_widget_frametable_object_append(of, ob, 0, 2, 1, 1, 1, 0, 1, 0); ob = e_widget_button_add(evas, _("Delete"), "list-remove", _delete_swipe_binding_cb, cfdata, NULL); cfdata->gui.o_del = ob; e_widget_disabled_set(ob, 1); e_widget_frametable_object_append(of, ob, 1, 1, 1, 1, 1, 0, 1, 0); ob = e_widget_button_add(evas, _("Delete All"), "edit-clear", _delete_all_swipe_binding_cb, cfdata, NULL); cfdata->gui.o_del_all = ob; e_widget_disabled_set(ob, 1); e_widget_frametable_object_append(of, ob, 1, 2, 1, 1, 1, 0, 1, 0); ob = e_widget_button_add(evas, _("Restore Default Bindings"), "enlightenment", _restore_swipe_binding_defaults_cb, cfdata, NULL); e_widget_frametable_object_append(of, ob, 0, 3, 1, 1, 1, 0, 1, 0); ob = e_widget_button_add(evas, _("Help"), "help", _help_swipe_bindings_cb, cfdata, NULL); e_widget_frametable_object_append(of, ob, 1, 3, 1, 1, 1, 0, 1, 0); e_widget_list_object_append(ol, of, 1, 1, 0.5); ot = e_widget_table_add(e_win_evas_win_get(evas), 0); of = e_widget_framelist_add(evas, _("Action"), 0); ob = e_widget_ilist_add(evas, 24, 24, &(cfdata->locals.action)); cfdata->gui.o_action_list = ob; e_widget_size_min_set(ob, 200, 240); e_widget_framelist_object_append(of, ob); e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1); of = e_widget_framelist_add(evas, _("Action Params"), 0); ob = e_widget_entry_add(cfd->dia->win, &(cfdata->locals.params), NULL, NULL, NULL); cfdata->gui.o_params = ob; e_widget_disabled_set(ob, 1); e_widget_framelist_object_append(of, ob); e_widget_table_object_append(ot, of, 0, 3, 1, 1, 1, 1, 1, 0); e_widget_list_object_append(ol, ot, 1, 1, 0.5); e_widget_list_object_append(o, ol, 1, 1, 0.5); oc = e_widget_check_add(evas, _("Open input devices"), &(cfdata->locals.gesture_open_input_devices)); e_widget_list_object_append(o, oc, 1, 1, 0.5); _update_swipe_binding_list(cfdata); _fill_actions_list(cfdata); e_dialog_resizable_set(cfd->dia, 1); return o; } static Eina_Bool _user_part_of_input(void) { uid_t user = getuid(); struct passwd *user_pw = getpwuid(user); gid_t *gids = NULL; int number_of_groups = 0; struct group *input_group = getgrnam("input"); EINA_SAFETY_ON_NULL_RETURN_VAL(user_pw, EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN_VAL(input_group, EINA_FALSE); if (getgrouplist(user_pw->pw_name, getgid(), NULL, &number_of_groups) != -1) { ERR("Failed to enumerate groups of user"); return EINA_FALSE; } number_of_groups ++; gids = alloca((number_of_groups) * sizeof(gid_t)); if (getgrouplist(user_pw->pw_name, getgid(), gids, &number_of_groups) == -1) { ERR("Failed to get groups of user"); return EINA_FALSE; } for (int i = 0; i < number_of_groups; ++i) { if (gids[i] == input_group->gr_gid) return EINA_TRUE; } return EINA_FALSE; } E_Config_Dialog * e_int_config_swipebindings(Evas_Object *parent EINA_UNUSED, const char *params) { E_Config_Dialog *cfd; E_Config_Dialog_View *v; if (e_config_dialog_find("E", "keyboard_and_mouse/swipe_bindings")) return NULL; v = E_NEW(E_Config_Dialog_View, 1); v->create_cfdata = _create_data; v->free_cfdata = _free_data; v->basic.apply_cfdata = _basic_apply_data; v->basic.create_widgets = _basic_create_widgets; v->override_auto_apply = 1; if (e_comp->comp_type == E_PIXMAP_TYPE_X && !_user_part_of_input()) { e_module_dialog_show(NULL, "Gesture Recognition", "Your user is not part of the input group, libinput cannot be used."); } if (e_bindings_gesture_capable_devices_get() == 0) { e_module_dialog_show(NULL, "Gesture Recognition", "No devices detected that are capable of gesture recognition."); } cfd = e_config_dialog_new(NULL, _("Swipe Bindings Settings"), "E", "keyboard_and_mouse/swipe_bindings", "enlightenment/swipes", 0, v, NULL); if ((params) && (params[0])) { cfd->cfdata->params = eina_stringshare_add(params); } return cfd; }