You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1193 lines
36 KiB

#include "e.h"
#define TEXT_NONE_ACTION_KEY _("<None>")
#define TEXT_NO_PARAMS _("<None>")
#define TEXT_NO_MODIFIER_HEADER _("Single key")
static void *_create_data(E_Config_Dialog *cfd);
static void _free_data(E_Config_Dialog *cfd,
E_Config_Dialog_Data *cfdata);
static int _basic_apply_data(E_Config_Dialog *cfd,
E_Config_Dialog_Data *cfdata);
static Evas_Object *_basic_create_widgets(E_Config_Dialog *cfd,
Evas *evas,
E_Config_Dialog_Data *cfdata);
/********* private functions ***************/
static void _fill_actions_list(E_Config_Dialog_Data *cfdata);
/**************** Updates ***********/
static int _update_key_binding_list(E_Config_Dialog_Data *cfdata,
E_Config_Binding_Key *bi);
static void _update_action_list(E_Config_Dialog_Data *cfdata);
static void _update_action_params(E_Config_Dialog_Data *cfdata);
static void _update_buttons(E_Config_Dialog_Data *cfdata);
/**************** Callbacks *********/
static void _binding_change_cb(void *data);
static void _action_change_cb(void *data);
static void _delete_all_key_binding_cb(void *data,
void *data2);
static void _delete_key_binding_cb(void *data,
void *data2);
static void _restore_key_binding_defaults_cb(void *data,
void *data2);
static void _add_key_binding_cb(void *data,
void *data2);
static void _modify_key_binding_cb(void *data,
void *data2);
/********* Helper *************************/
static char *_key_binding_header_get(int modifiers);
static char *_key_binding_text_get(E_Config_Binding_Key *bi);
static void _auto_apply_changes(E_Config_Dialog_Data *cfdata);
static void _find_key_binding_action(const char *action,
const char *params,
int *g,
int *a,
int *n);
/********* Sorting ************************/
static int _key_binding_sort_cb(const void *d1,
const void *d2);
/**************** grab window *******/
static void _grab_wnd_show(E_Config_Dialog_Data *cfdata);
static Eina_Bool _grab_key_down_cb(void *data,
int type,
void *event);
struct _E_Config_Dialog_Data
{
Evas *evas;
struct
{
Eina_List *key;
} binding;
struct
{
const char *binding, *action, *cur;
char *params;
int cur_act, add;
Eina_Bool changed E_BITFIELD;
E_Grab_Dialog *eg;
} locals;
struct
{
Evas_Object *o_add, *o_mod, *o_del, *o_del_all;
Evas_Object *o_binding_list, *o_action_list;
Evas_Object *o_params;
} gui;
char *params;
E_Config_Dialog *cfd;
};
E_Config_Dialog *
e_int_config_keybindings(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/key_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;
cfd = e_config_dialog_new(NULL, _("Key Bindings Settings"), "E",
"keyboard_and_mouse/key_bindings",
"preferences-desktop-keyboard-shortcuts", 0, v, NULL);
if ((params) && (params[0]))
{
cfd->cfdata->params = strdup(params);
_add_key_binding_cb(cfd->cfdata, NULL);
}
return cfd;
}
static void
_fill_data(E_Config_Dialog_Data *cfdata)
{
Eina_List *l = NULL;
E_Config_Binding_Key *bi, *bi2;
cfdata->locals.binding = eina_stringshare_add("");
cfdata->locals.action = eina_stringshare_add("");
cfdata->locals.params = strdup("");
cfdata->locals.cur = NULL;
cfdata->binding.key = NULL;
cfdata->locals.eg = NULL;
EINA_LIST_FOREACH(e_bindings->key_bindings, l, bi)
{
if (!bi) continue;
bi2 = E_NEW(E_Config_Binding_Key, 1);
bi2->context = bi->context;
bi2->key = eina_stringshare_add(bi->key);
bi2->modifiers = bi->modifiers;
bi2->any_mod = bi->any_mod;
bi2->action = eina_stringshare_ref(bi->action);
bi2->params = eina_stringshare_ref(bi->params);
cfdata->binding.key = eina_list_append(cfdata->binding.key, 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;
cfdata->locals.cur_act = -1;
_fill_data(cfdata);
return cfdata;
}
static void
_free_data(E_Config_Dialog *cfd EINA_UNUSED,
E_Config_Dialog_Data *cfdata)
{
E_Config_Binding_Key *bi;
EINA_LIST_FREE(cfdata->binding.key, bi)
{
eina_stringshare_del(bi->key);
eina_stringshare_del(bi->action);
eina_stringshare_del(bi->params);
E_FREE(bi);
}
eina_stringshare_del(cfdata->locals.cur);
eina_stringshare_del(cfdata->locals.binding);
eina_stringshare_del(cfdata->locals.action);
free(cfdata->locals.params);
free(cfdata->params);
E_FREE(cfdata);
}
static int
_basic_apply_data(E_Config_Dialog *cfd EINA_UNUSED,
E_Config_Dialog_Data *cfdata)
{
Eina_List *l = NULL;
E_Config_Binding_Key *bi, *bi2;
_auto_apply_changes(cfdata);
e_comp_canvas_keys_ungrab();
EINA_LIST_FREE(e_bindings->key_bindings, bi)
{
e_bindings_key_del(bi->context, bi->key, bi->modifiers, bi->any_mod,
bi->action, bi->params);
if (bi->key) eina_stringshare_del(bi->key);
if (bi->action) eina_stringshare_del(bi->action);
if (bi->params) eina_stringshare_del(bi->params);
E_FREE(bi);
}
EINA_LIST_FOREACH(cfdata->binding.key, l, bi2)
{
if (!bi2->key || !bi2->key[0]) continue;
bi = E_NEW(E_Config_Binding_Key, 1);
bi->context = bi2->context;
bi->key = eina_stringshare_add(bi2->key);
bi->modifiers = bi2->modifiers;
bi->any_mod = bi2->any_mod;
bi->action =
((!bi2->action) || (!bi2->action[0])) ? NULL : eina_stringshare_ref(bi2->action);
bi->params =
((!bi2->params) || (!bi2->params[0])) ? NULL : eina_stringshare_ref(bi2->params);
e_bindings->key_bindings = eina_list_append(e_bindings->key_bindings, bi);
e_bindings_key_add(bi->context, bi->key, bi->modifiers, bi->any_mod,
bi->action, bi->params);
}
e_comp_canvas_keys_grab();
e_config_save_queue();
return 1;
}
static Evas_Object *
_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
{
Evas_Object *o, *ot, *of, *ob;
cfdata->evas = evas;
o = e_widget_list_add(evas, 0, 1);
of = e_widget_frametable_add(evas, _("Key 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, 200);
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_key_binding_cb, cfdata, NULL);
cfdata->gui.o_add = ob;
e_widget_frametable_object_append(of, ob, 0, 1, 1, 1, 1, 0, 1, 0);
ob = e_widget_button_add(evas, _("Delete"), "list-remove", _delete_key_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, _("Modify"), NULL, _modify_key_binding_cb, cfdata, NULL);
cfdata->gui.o_mod = ob;
e_widget_disabled_set(ob, 1);
e_widget_frametable_object_append(of, ob, 0, 2, 1, 1, 1, 0, 1, 0);
ob = e_widget_button_add(evas, _("Delete All"), "edit-clear", _delete_all_key_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_key_binding_defaults_cb, cfdata, NULL);
e_widget_frametable_object_append(of, ob, 0, 3, 2, 1, 1, 0, 1, 0);
e_widget_list_object_append(o, 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, 280);
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, 1, 1, 1, 1, 1, 1, 0);
e_widget_list_object_append(o, ot, 1, 1, 0.5);
_update_key_binding_list(cfdata, NULL);
_fill_actions_list(cfdata);
e_dialog_resizable_set(cfd->dia, 1);
return o;
}
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));
}
/**************** Callbacks *********/
static void
_add_key_binding_cb(void *data,
void *data2 EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata;
cfdata = data;
_auto_apply_changes(cfdata);
cfdata->locals.add = 1;
_grab_wnd_show(cfdata);
}
static void
_modify_key_binding_cb(void *data,
void *data2 EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata;
cfdata = data;
_auto_apply_changes(cfdata);
cfdata->locals.add = 0;
_grab_wnd_show(cfdata);
}
static void
_binding_change_cb(void *data)
{
E_Config_Dialog_Data *cfdata;
cfdata = data;
if (cfdata->locals.changed) _auto_apply_changes(cfdata);
eina_stringshare_del(cfdata->locals.cur);
cfdata->locals.cur = NULL;
cfdata->locals.cur_act = -1;
cfdata->locals.changed = 0;
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 void
_action_change_cb(void *data)
{
E_Config_Dialog_Data *cfdata;
cfdata = data;
_update_action_params(cfdata);
cfdata->locals.cur_act = e_widget_ilist_selected_get(cfdata->gui.o_action_list);
cfdata->locals.changed = 1;
}
static void
_delete_all_key_binding_cb(void *data,
void *data2 EINA_UNUSED)
{
E_Config_Binding_Key *bi;
E_Config_Dialog_Data *cfdata;
cfdata = data;
/* FIXME: need confirmation dialog */
EINA_LIST_FREE(cfdata->binding.key, bi)
{
eina_stringshare_del(bi->key);
eina_stringshare_del(bi->action);
eina_stringshare_del(bi->params);
E_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
_delete_key_binding_cb(void *data,
void *data2 EINA_UNUSED)
{
Eina_List *l = NULL;
const char *n;
int sel;
E_Config_Dialog_Data *cfdata;
E_Config_Binding_Key *bi;
cfdata = data;
sel = e_widget_ilist_selected_get(cfdata->gui.o_binding_list);
if (cfdata->locals.binding[0] == 'k')
{
n = cfdata->locals.binding;
l = eina_list_nth_list(cfdata->binding.key, atoi(++n));
/* FIXME: need confirmation dialog */
if (l)
{
bi = eina_list_data_get(l);
eina_stringshare_del(bi->key);
eina_stringshare_del(bi->action);
eina_stringshare_del(bi->params);
E_FREE(bi);
cfdata->binding.key = eina_list_remove_list(cfdata->binding.key, l);
}
}
_update_key_binding_list(cfdata, NULL);
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;
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);
}
else
{
e_widget_ilist_selected_set(cfdata->gui.o_binding_list, sel);
e_widget_ilist_nth_show(cfdata->gui.o_binding_list, sel, 0);
}
}
static void
_restore_key_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.key, e_config_binding_key_free);
cfdata->binding.key = ecb->key_bindings, ecb->key_bindings = NULL;
e_config_bindings_free(ecb);
eina_stringshare_del(cfdata->locals.cur);
cfdata->locals.cur = NULL;
_update_key_binding_list(cfdata, NULL);
_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);
}
/**************** Updates ***********/
static void
_update_action_list(E_Config_Dialog_Data *cfdata)
{
E_Config_Binding_Key *bi;
int j = -1, i, n, cnt;
const char *action, *params;
if (!cfdata->locals.cur) return;
if (cfdata->locals.cur[0] == 'k')
{
sscanf(cfdata->locals.cur, "k%d", &n);
bi = eina_list_nth(cfdata->binding.key, 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_key_binding_action(action, params, NULL, NULL, &j);
if (j >= 0)
{
cnt = e_widget_ilist_count(cfdata->gui.o_action_list);
for (i = 0; i < cnt; 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);
}
/*if (cfdata->locals.cur[0] == 'k')
{
sscanf(cfdata->locals.cur, "k%d", &n);
bi = eina_list_nth(cfdata->binding.key, 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;
}
_find_key_binding_action(bi, 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);
free(cfdata->locals.action);
cfdata->locals.action = strdup("");
e_widget_entry_clear(cfdata->gui.o_params);
}
}*/
}
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_Key *bi;
const char *action, *params;
#define KB_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;
}
sscanf(cfdata->locals.action, "%d %d", &g, &a);
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);
KB_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] == 'k')
{
sscanf(cfdata->locals.cur, "k%d", &b);
bi = eina_list_nth(cfdata->binding.key, b);
if (!bi)
{
e_widget_disabled_set(cfdata->gui.o_params, 1);
KB_EXAMPLE_PARAMS;
return;
}
action = bi->action;
params = bi->params;
}
else
{
e_widget_disabled_set(cfdata->gui.o_params, 1);
KB_EXAMPLE_PARAMS;
return;
}
if (action)
{
if (!e_util_strcmp(action, actd->act_cmd))
{
if ((cfdata->locals.cur_act >= 0) && (cfdata->locals.cur_act != e_widget_ilist_selected_get(cfdata->gui.o_action_list)))
KB_EXAMPLE_PARAMS;
else
e_widget_entry_text_set(cfdata->gui.o_params, params);
}
else
KB_EXAMPLE_PARAMS;
}
else
KB_EXAMPLE_PARAMS;
}
static int
_update_key_binding_list(E_Config_Dialog_Data *cfdata,
E_Config_Binding_Key *bi_new)
{
int i;
char *b, b2[64];
Eina_List *l;
E_Config_Binding_Key *bi;
int modifiers = -1;
int bi_pos = 0;
int ret = -1;
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.key)
{
cfdata->binding.key = eina_list_sort(cfdata->binding.key,
eina_list_count(cfdata->binding.key), _key_binding_sort_cb);
}
for (l = cfdata->binding.key, i = 0; l; l = l->next, i++)
{
bi = l->data;
if (bi == bi_new) ret = bi_pos;
if (ret < 0) bi_pos++;
if (modifiers != (int)bi->modifiers)
{
modifiers = bi->modifiers;
b = _key_binding_header_get(modifiers);
if (b)
{
if (ret < 0) bi_pos++;
e_widget_ilist_header_append(cfdata->gui.o_binding_list, NULL, b);
free(b);
}
}
b = _key_binding_text_get(bi);
if (!b) continue;
snprintf(b2, sizeof(b2), "k%d", i);
e_widget_ilist_append(cfdata->gui.o_binding_list, NULL, b,
_binding_change_cb, cfdata, b2);
free(b);
}
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.key))
e_widget_disabled_set(cfdata->gui.o_del_all, 0);
else
e_widget_disabled_set(cfdata->gui.o_del_all, 1);
return ret;
}
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_mod, 1);
e_widget_disabled_set(cfdata->gui.o_del, 1);
return;
}
e_widget_disabled_set(cfdata->gui.o_mod, 0);
e_widget_disabled_set(cfdata->gui.o_del, 0);
}
/*************** Sorting *****************************/
static int
_key_binding_sort_cb(const void *d1,
const void *d2)
{
int i, j;
const E_Config_Binding_Key *bi, *bi2;
bi = d1;
bi2 = d2;
i = 0; j = 0;
if (bi->modifiers & E_BINDING_MODIFIER_CTRL) i++;
if (bi->modifiers & E_BINDING_MODIFIER_ALT) i++;
if (bi->modifiers & E_BINDING_MODIFIER_SHIFT) i++;
if (bi->modifiers & E_BINDING_MODIFIER_WIN) i++;
if (bi2->modifiers & E_BINDING_MODIFIER_CTRL) j++;
if (bi2->modifiers & E_BINDING_MODIFIER_ALT) j++;