#include "e.h" /** * TODO: * Maybe use a toolbook widget instead of 2 lists ?? * Maybe add a way to restore default acpi bindings ?? */ /* local config structure */ struct _E_Config_Dialog_Data { Eina_List *bindings; Evas_Object *o_bindings, *o_actions, *o_params; Evas_Object *o_add, *o_del; const char *bindex; E_Config_Dialog *cfd; }; /* local function prototypes */ static void *_create_data(E_Config_Dialog *cfd); static void _fill_data(E_Config_Dialog_Data *cfdata); static void _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata); static int _basic_apply(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata); static Evas_Object *_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); static void _fill_bindings(E_Config_Dialog_Data *cfdata); static void _fill_actions(E_Config_Dialog_Data *cfdata); static E_Config_Binding_Acpi *_selected_binding_get(E_Config_Dialog_Data *cfdata); static E_Action_Description *_selected_action_get(E_Config_Dialog_Data *cfdata); static const char *_binding_label_get(E_Config_Binding_Acpi *bind); static void _cb_bindings_changed(void *data); static void _cb_actions_changed(void *data); static void _cb_entry_changed(void *data, void *data2 __UNUSED__); static void _cb_add_binding(void *data, void *data2 __UNUSED__); static void _cb_del_binding(void *data, void *data2 __UNUSED__); static Eina_Bool _cb_grab_key_down(void *data, int type __UNUSED__, void *event); static Eina_Bool _cb_acpi_event(void *data, int type, void *event); /* local variables */ static E_Dialog *grab_dlg = NULL; static Ecore_X_Window grab_win = 0; static Eina_List *grab_hdls = NULL; E_Config_Dialog * e_int_config_acpibindings(E_Container *con, const char *params __UNUSED__) { E_Config_Dialog *cfd; E_Config_Dialog_View *v; if ((e_config_dialog_find("E", "advanced/acpi_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; v->basic.create_widgets = _basic_create; cfd = e_config_dialog_new(con, _("ACPI Bindings"), "E", "advanced/acpi_bindings", "preferences-system-power-management", 0, v, NULL); return cfd; } /* local functions */ static void * _create_data(E_Config_Dialog *cfd) { E_Config_Dialog_Data *cfdata; cfdata = E_NEW(E_Config_Dialog_Data, 1); _fill_data(cfdata); cfdata->cfd = cfd; return cfdata; } static void _fill_data(E_Config_Dialog_Data *cfdata) { Eina_List *l; E_Config_Binding_Acpi *bind; EINA_LIST_FOREACH(e_config->acpi_bindings, l, bind) { E_Config_Binding_Acpi *b2; b2 = E_NEW(E_Config_Binding_Acpi, 1); b2->context = bind->context; b2->type = bind->type; b2->status = bind->status; b2->action = eina_stringshare_ref(bind->action); b2->params = eina_stringshare_ref(bind->params); cfdata->bindings = eina_list_append(cfdata->bindings, b2); } } static void _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) { E_Config_Binding_Acpi *bind; Ecore_Event_Handler *hdl; EINA_LIST_FREE(cfdata->bindings, bind) { if (bind->action) eina_stringshare_del(bind->action); if (bind->params) eina_stringshare_del(bind->params); E_FREE(bind); } /* free the handlers */ EINA_LIST_FREE(grab_hdls, hdl) ecore_event_handler_del(hdl); if (grab_win) { e_grabinput_release(grab_win, grab_win); ecore_x_window_free(grab_win); } grab_win = 0; if (grab_dlg) { e_object_del(E_OBJECT(grab_dlg)); e_acpi_events_thaw(); } grab_dlg = NULL; E_FREE(cfdata); } static int _basic_apply(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) { E_Config_Binding_Acpi *bind, *b2; Eina_List *l; EINA_LIST_FREE(e_config->acpi_bindings, bind) { e_bindings_acpi_del(bind->context, bind->type, bind->status, bind->action, bind->params); if (bind->action) eina_stringshare_del(bind->action); if (bind->params) eina_stringshare_del(bind->params); E_FREE(bind); } EINA_LIST_FOREACH(cfdata->bindings, l, bind) { b2 = E_NEW(E_Config_Binding_Acpi, 1); b2->context = bind->context; b2->type = bind->type; b2->status = bind->status; b2->action = eina_stringshare_ref(bind->action); b2->params = eina_stringshare_ref(bind->params); e_config->acpi_bindings = eina_list_append(e_config->acpi_bindings, b2); e_bindings_acpi_add(b2->context, b2->type, b2->status, b2->action, b2->params); } e_config_save_queue(); return 1; } static Evas_Object * _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) { Evas_Object *ol, *of, *ow, *ot; ol = e_widget_list_add(evas, 0, 1); of = e_widget_frametable_add(evas, _("ACPI Bindings"), 0); ow = e_widget_ilist_add(evas, (24 * e_scale), (24 * e_scale), &(cfdata->bindex)); cfdata->o_bindings = ow; _fill_bindings(cfdata); e_widget_frametable_object_append(of, ow, 0, 0, 2, 1, 1, 1, 1, 1); ow = e_widget_button_add(evas, _("Add Binding"), "list-add", _cb_add_binding, cfdata, NULL); cfdata->o_add = ow; e_widget_frametable_object_append(of, ow, 0, 1, 1, 1, 1, 0, 1, 0); ow = e_widget_button_add(evas, _("Delete Binding"), "list-remove", _cb_del_binding, cfdata, NULL); cfdata->o_del = ow; e_widget_disabled_set(ow, EINA_TRUE); e_widget_frametable_object_append(of, ow, 1, 1, 1, 1, 1, 0, 1, 0); e_widget_list_object_append(ol, of, 1, 1, 0.5); ot = e_widget_table_add(evas, 0); of = e_widget_framelist_add(evas, _("Action"), 0); ow = e_widget_ilist_add(evas, (24 * e_scale), (24 * e_scale), NULL); cfdata->o_actions = ow; _fill_actions(cfdata); e_widget_framelist_object_append(of, ow); e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1); ow = e_widget_framelist_add(evas, _("Action Params"), 0); cfdata->o_params = e_widget_entry_add(evas, NULL, _cb_entry_changed, cfdata, NULL); e_widget_disabled_set(cfdata->o_params, EINA_TRUE); e_widget_framelist_object_append(ow, cfdata->o_params); e_widget_table_object_append(ot, ow, 0, 1, 1, 1, 1, 0, 1, 0); e_widget_list_object_append(ol, ot, 1, 1, 0.5); e_dialog_resizable_set(cfd->dia, 1); return ol; } static void _fill_bindings(E_Config_Dialog_Data *cfdata) { Evas *evas; Eina_List *l; E_Config_Binding_Acpi *bind; int i = -1, mw; evas = evas_object_evas_get(cfdata->o_bindings); evas_event_freeze(evas); edje_freeze(); e_widget_ilist_freeze(cfdata->o_bindings); e_widget_ilist_clear(cfdata->o_bindings); EINA_LIST_FOREACH(cfdata->bindings, l, bind) { const char *lbl; char buff[32]; i++; if (!(lbl = _binding_label_get(bind))) continue; snprintf(buff, sizeof(buff), "%d", i); e_widget_ilist_append(cfdata->o_bindings, NULL, lbl, _cb_bindings_changed, cfdata, buff); } e_widget_ilist_go(cfdata->o_bindings); e_widget_size_min_get(cfdata->o_bindings, &mw, NULL); if (mw < (160 * e_scale)) mw = (160 * e_scale); e_widget_size_min_set(cfdata->o_bindings, mw, 200); e_widget_ilist_thaw(cfdata->o_bindings); edje_thaw(); evas_event_thaw(evas); } static void _fill_actions(E_Config_Dialog_Data *cfdata) { Evas *evas; Eina_List *l, *ll; E_Action_Group *grp; E_Action_Description *dsc; int mw; evas = evas_object_evas_get(cfdata->o_actions); evas_event_freeze(evas); edje_freeze(); e_widget_ilist_freeze(cfdata->o_actions); e_widget_ilist_clear(cfdata->o_actions); EINA_LIST_FOREACH(e_action_groups_get(), l, grp) { if (!grp->acts) continue; // if ((strcmp(grp->act_grp, "Acpi")) && // (strcmp(grp->act_grp, "System")) && // (strcmp(grp->act_grp, "Launch"))) continue; e_widget_ilist_header_append(cfdata->o_actions, NULL, _(grp->act_grp)); EINA_LIST_FOREACH(grp->acts, ll, dsc) e_widget_ilist_append(cfdata->o_actions, NULL, _(dsc->act_name), _cb_actions_changed, cfdata, dsc->act_cmd); } e_widget_ilist_go(cfdata->o_actions); e_widget_size_min_get(cfdata->o_actions, &mw, NULL); if (mw < (160 * e_scale)) mw = (160 * e_scale); e_widget_size_min_set(cfdata->o_actions, mw, 200); e_widget_ilist_thaw(cfdata->o_actions); edje_thaw(); evas_event_thaw(evas); } static E_Config_Binding_Acpi * _selected_binding_get(E_Config_Dialog_Data *cfdata) { E_Config_Binding_Acpi *bind; if ((!cfdata) || (!cfdata->bindex)) return NULL; if (!(bind = eina_list_nth(cfdata->bindings, atoi(cfdata->bindex)))) return NULL; return bind; } static E_Action_Description * _selected_action_get(E_Config_Dialog_Data *cfdata) { E_Action_Group *grp; E_Action_Description *dsc = NULL; Eina_List *l, *ll; const char *lbl; int sel; if (!cfdata) return NULL; sel = e_widget_ilist_selected_get(cfdata->o_actions); if (sel < 0) return NULL; if (!(lbl = e_widget_ilist_nth_label_get(cfdata->o_actions, sel))) return NULL; EINA_LIST_FOREACH(e_action_groups_get(), l, grp) { if (!grp->acts) continue; // if ((strcmp(grp->act_grp, "Acpi")) && // (strcmp(grp->act_grp, "System")) && // (strcmp(grp->act_grp, "Launch"))) continue; EINA_LIST_FOREACH(grp->acts, ll, dsc) { if ((dsc->act_name) && (!strcmp(dsc->act_name, lbl))) return dsc; } } return NULL; } static const char * _binding_label_get(E_Config_Binding_Acpi *bind) { if (bind->type == E_ACPI_TYPE_UNKNOWN) return NULL; if (bind->type == E_ACPI_TYPE_AC_ADAPTER) { if (bind->status == 0) return _("AC Adapter Unplugged"); if (bind->status == 1) return _("AC Adapter Plugged"); return _("Ac Adapter"); } if (bind->type == E_ACPI_TYPE_BATTERY) return _("Battery"); if (bind->type == E_ACPI_TYPE_BUTTON) return _("Button"); if (bind->type == E_ACPI_TYPE_FAN) return _("Fan"); if (bind->type == E_ACPI_TYPE_LID) { if (bind->status == 0) return _("Lid Closed"); if (bind->status == 1) return _("Lid Opened"); return _("Lid"); } if (bind->type == E_ACPI_TYPE_POWER) return _("Power Button"); if (bind->type == E_ACPI_TYPE_PROCESSOR) return _("Processor"); if (bind->type == E_ACPI_TYPE_SLEEP) return _("Sleep Button"); if (bind->type == E_ACPI_TYPE_THERMAL) return _("Thermal"); if (bind->type == E_ACPI_TYPE_VIDEO) return _("Video"); if (bind->type == E_ACPI_TYPE_WIFI) return _("Wifi"); if (bind->type == E_ACPI_TYPE_HIBERNATE) return _("Hibernate"); if (bind->type == E_ACPI_TYPE_ZOOM_OUT) return _("Zoom Out"); if (bind->type == E_ACPI_TYPE_ZOOM_IN) return _("Zoom In"); if (bind->type == E_ACPI_TYPE_BRIGHTNESS_DOWN) return _("Brightness Down"); if (bind->type == E_ACPI_TYPE_BRIGHTNESS_UP) return _("Brightness Up"); if (bind->type == E_ACPI_TYPE_ASSIST) return _("Assist"); if (bind->type == E_ACPI_TYPE_S1) return _("S1"); if (bind->type == E_ACPI_TYPE_VAIO) return _("Vaio"); return NULL; } static void _cb_bindings_changed(void *data) { E_Config_Dialog_Data *cfdata; E_Config_Binding_Acpi *bind; Eina_List *items; const E_Ilist_Item *item; int i = -1; if (!(cfdata = data)) return; e_widget_entry_clear(cfdata->o_params); if (!(bind = _selected_binding_get(cfdata))) { e_widget_disabled_set(cfdata->o_params, EINA_TRUE); e_widget_disabled_set(cfdata->o_del, EINA_TRUE); return; } e_widget_disabled_set(cfdata->o_del, EINA_FALSE); e_widget_ilist_unselect(cfdata->o_actions); EINA_LIST_FOREACH(e_widget_ilist_items_get(cfdata->o_actions), items, item) { const char *val; i++; if (!(val = e_widget_ilist_item_value_get(item))) continue; if (strcmp(val, bind->action)) continue; e_widget_ilist_selected_set(cfdata->o_actions, i); break; } } static void _cb_actions_changed(void *data) { E_Config_Dialog_Data *cfdata; E_Config_Binding_Acpi *bind; E_Action_Description *dsc; if (!(cfdata = data)) return; e_widget_entry_clear(cfdata->o_params); if (!(bind = _selected_binding_get(cfdata))) { e_widget_disabled_set(cfdata->o_params, EINA_TRUE); e_widget_disabled_set(cfdata->o_del, EINA_TRUE); return; } if (!(dsc = _selected_action_get(cfdata))) { e_widget_disabled_set(cfdata->o_params, EINA_TRUE); return; } eina_stringshare_replace(&bind->action, dsc->act_cmd); e_widget_disabled_set(cfdata->o_params, !(dsc->editable)); if ((!dsc->editable) && (dsc->act_params)) e_widget_entry_text_set(cfdata->o_params, dsc->act_params); else if (bind->params) e_widget_entry_text_set(cfdata->o_params, bind->params); else { if ((!dsc->param_example) || (!dsc->param_example[0])) e_widget_entry_text_set(cfdata->o_params, _("")); else e_widget_entry_text_set(cfdata->o_params, dsc->param_example); } } static void _cb_entry_changed(void *data, void *data2 __UNUSED__) { E_Config_Dialog_Data *cfdata; E_Config_Binding_Acpi *bind; E_Action_Description *dsc; if (!(cfdata = data)) return; if (!(dsc = _selected_action_get(cfdata))) return; if (!dsc->editable) return; if (!(bind = _selected_binding_get(cfdata))) return; eina_stringshare_replace(&bind->params, e_widget_entry_text_get(cfdata->o_params)); } static void _cb_add_binding(void *data, void *data2 __UNUSED__) { E_Config_Dialog_Data *cfdata; E_Manager *man; if (grab_win != 0) return; if (!(cfdata = data)) return; man = e_manager_current_get(); grab_dlg = e_dialog_new(e_container_current_get(man), "E", "_acpibind_getbind_dialog"); if (!grab_dlg) return; e_dialog_title_set(grab_dlg, _("ACPI Binding")); e_dialog_icon_set(grab_dlg, "preferences-system-power-management", 48); e_dialog_text_set(grab_dlg, _("Please trigger the ACPI event you wish to bind to, " "

or Escape to abort.")); e_win_centered_set(grab_dlg->win, EINA_TRUE); e_win_borderless_set(grab_dlg->win, EINA_TRUE); grab_win = ecore_x_window_input_new(man->root, 0, 0, 1, 1); ecore_x_window_show(grab_win); e_grabinput_get(grab_win, 0, grab_win); grab_hdls = eina_list_append(grab_hdls, ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _cb_grab_key_down, cfdata)); grab_hdls = eina_list_append(grab_hdls, ecore_event_handler_add(E_EVENT_ACPI, _cb_acpi_event, cfdata)); /* freeze all incoming acpi events */ e_acpi_events_freeze(); e_dialog_show(grab_dlg); ecore_x_icccm_transient_for_set(grab_dlg->win->evas_win, cfdata->cfd->dia->win->evas_win); } static void _cb_del_binding(void *data, void *data2 __UNUSED__) { E_Config_Dialog_Data *cfdata; E_Config_Binding_Acpi *bind, *bind2; Eina_List *l; if (!(cfdata = data)) return; if (!(bind = _selected_binding_get(cfdata))) return; /* delete from e_config */ EINA_LIST_FOREACH(e_config->acpi_bindings, l, bind2) { if ((bind->context == bind2->context) && (bind->type == bind2->type) && (((bind->action) && (bind2->action) && (!strcmp(bind->action, bind2->action))) || ((!bind->action) && (!bind2->action))) && (((bind->params) && (bind2->params) && (!strcmp(bind->params, bind2->params))) || ((!bind->params) && (!bind2->params)))) { if (bind2->action) eina_stringshare_del(bind2->action); if (bind2->params) eina_stringshare_del(bind2->params); E_FREE(bind2); e_config->acpi_bindings = eina_list_remove_list(e_config->acpi_bindings, l); e_config_save_queue(); break; } } /* delete from e_bindings */ e_bindings_acpi_del(bind->context, bind->type, bind->status, bind->action, bind->params); /* delete from dialog list */ EINA_LIST_FOREACH(cfdata->bindings, l, bind2) { if ((bind->context == bind2->context) && (bind->type == bind2->type) && (((bind->action) && (bind2->action) && (!strcmp(bind->action, bind2->action))) || ((!bind->action) && (!bind2->action))) && (((bind->params) && (bind2->params) && (!strcmp(bind->params, bind2->params))) || ((!bind->params) && (!bind2->params)))) { if (bind2->action) eina_stringshare_del(bind2->action); if (bind2->params) eina_stringshare_del(bind2->params); E_FREE(bind2); cfdata->bindings = eina_list_remove_list(cfdata->bindings, l); break; } } /* reset gui */ e_widget_entry_clear(cfdata->o_params); e_widget_disabled_set(cfdata->o_params, EINA_TRUE); e_widget_ilist_unselect(cfdata->o_actions); e_widget_disabled_set(cfdata->o_del, EINA_TRUE); _fill_bindings(cfdata); } static Eina_Bool _cb_grab_key_down(void *data, int type __UNUSED__, void *event) { E_Config_Dialog_Data *cfdata; Ecore_Event_Key *ev; ev = event; if (ev->window != grab_win) return ECORE_CALLBACK_PASS_ON; if (!(cfdata = data)) return ECORE_CALLBACK_PASS_ON; if (!strcmp(ev->keyname, "Escape")) { Ecore_Event_Handler *hdl; /* free the handlers */ EINA_LIST_FREE(grab_hdls, hdl) ecore_event_handler_del(hdl); /* kill the dialog window */ e_grabinput_release(grab_win, grab_win); ecore_x_window_free(grab_win); grab_win = 0; e_object_del(E_OBJECT(grab_dlg)); grab_dlg = NULL; /* unfreeze acpi events */ e_acpi_events_thaw(); } return ECORE_CALLBACK_PASS_ON; } static Eina_Bool _cb_acpi_event(void *data, __UNUSED__ int type, void *event) { E_Event_Acpi *ev; E_Config_Dialog_Data *cfdata; E_Config_Binding_Acpi *bind; Ecore_Event_Handler *hdl; ev = event; if (!(cfdata = data)) return ECORE_CALLBACK_PASS_ON; /* free the handlers */ EINA_LIST_FREE(grab_hdls, hdl) ecore_event_handler_del(hdl); /* kill the dialog window */ e_grabinput_release(grab_win, grab_win); ecore_x_window_free(grab_win); grab_win = 0; e_object_del(E_OBJECT(grab_dlg)); grab_dlg = NULL; /* unfreeze acpi events */ e_acpi_events_thaw(); /* NB: This may need more testing/parsing for event status */ bind = E_NEW(E_Config_Binding_Acpi, 1); bind->context = E_BINDING_CONTEXT_NONE; bind->type = ev->type; bind->status = ev->status; bind->action = eina_stringshare_add("dim_screen"); bind->params = NULL; e_config->acpi_bindings = eina_list_append(e_config->acpi_bindings, bind); e_config_save_queue(); cfdata->bindings = eina_list_append(cfdata->bindings, bind); _fill_bindings(cfdata); return ECORE_CALLBACK_DONE; }