From d705653eaded9552a58113bdd212e9456fd27829 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Fri, 13 May 2011 11:39:04 +0000 Subject: [PATCH] e17 gets itself the ability to set environment variables (for itself.. and anything thats a child that it launches) with... a GUI.. for all the people who go "so.. how can i set an environment variable"... ie peopl who dont know how to customis bashrc's or write xinitrc's and use them etc.. which these days is a LOT of people... :( note - it's advanced for people with advanced needs, thus its not the most friendly dialog.. but it works. :) SVN revision: 59369 --- src/bin/Makefile.am | 4 +- src/bin/e_config.c | 21 ++ src/bin/e_config.h | 10 + src/bin/e_env.c | 47 ++++ src/bin/e_env.h | 15 ++ src/bin/e_includes.h | 1 + src/bin/e_main.c | 9 + src/modules/conf_paths/Makefile.am | 4 +- src/modules/conf_paths/e_int_config_env.c | 310 ++++++++++++++++++++++ src/modules/conf_paths/e_int_config_env.h | 9 + src/modules/conf_paths/e_mod_main.c | 7 + src/modules/conf_paths/e_mod_main.h | 2 + 12 files changed, 437 insertions(+), 2 deletions(-) create mode 100644 src/bin/e_env.c create mode 100644 src/bin/e_env.h create mode 100644 src/modules/conf_paths/e_int_config_env.c create mode 100644 src/modules/conf_paths/e_int_config_env.h diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 88ad77e60..872792bfb 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -59,8 +59,9 @@ e_dnd.h \ e_dpms.h \ e_eap_editor.h \ e_editable.h \ -e_entry_dialog.h \ e_entry.h \ +e_entry_dialog.h \ +e_env.h \ e_error.h \ e_exec.h \ e_exehist.h \ @@ -207,6 +208,7 @@ e_eap_editor.c \ e_editable.c \ e_entry.c \ e_entry_dialog.c \ +e_env.c \ e_error.c \ e_exec.c \ e_exehist.c \ diff --git a/src/bin/e_config.c b/src/bin/e_config.c index a624d5641..88594dae9 100644 --- a/src/bin/e_config.c +++ b/src/bin/e_config.c @@ -64,6 +64,7 @@ static E_Config_DD *_e_config_shelf_edd = NULL; static E_Config_DD *_e_config_shelf_desk_edd = NULL; static E_Config_DD *_e_config_mime_icon_edd = NULL; static E_Config_DD *_e_config_syscon_action_edd = NULL; +static E_Config_DD *_e_config_env_var_edd = NULL; static E_Config_DD *_e_config_screen_size_edd = NULL; static E_Config_DD *_e_config_screen_size_mm_edd = NULL; static E_Config_DD *_e_config_eina_rectangle_edd = NULL; @@ -515,6 +516,16 @@ e_config_init(void) E_CONFIG_VAL(D, T, icon, STR); E_CONFIG_VAL(D, T, is_main, INT); + _e_config_env_var_edd = E_CONFIG_DD_NEW("E_Config_Env_Var", + E_Config_Env_Var); +#undef T +#undef D +#define T E_Config_Env_Var +#define D _e_config_env_var_edd + E_CONFIG_VAL(D, T, var, STR); + E_CONFIG_VAL(D, T, val, STR); + E_CONFIG_VAL(D, T, unset, UCHAR); + _e_config_screen_size_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size", Ecore_X_Randr_Screen_Size); #undef T #undef D @@ -893,6 +904,8 @@ e_config_init(void) E_CONFIG_VAL(D, T, null_container_win, UCHAR); + E_CONFIG_LIST(D, T, env_vars, _e_config_env_var_edd); + e_config_load(); e_config_save_queue(); @@ -924,6 +937,7 @@ e_config_shutdown(void) E_CONFIG_DD_FREE(_e_config_shelf_desk_edd); E_CONFIG_DD_FREE(_e_config_mime_icon_edd); E_CONFIG_DD_FREE(_e_config_syscon_action_edd); + E_CONFIG_DD_FREE(_e_config_env_var_edd); E_CONFIG_DD_FREE(_e_config_screen_info_edd); return 1; } @@ -1883,6 +1897,7 @@ _e_config_free(E_Config *ecf) E_Randr_Crtc_Restore_Info *crtc_info; E_Randr_Output_Info *output_info; E_Randr_Screen_Restore_Info_12 *restore_info_12; + E_Config_Env_Var *evr; if (!ecf) return; @@ -2063,6 +2078,12 @@ _e_config_free(E_Config *ecf) free(screen_info); } } + EINA_LIST_FREE(ecf->env_vars, evr) + { + if (evr->var) eina_stringshare_del(evr->var); + if (evr->val) eina_stringshare_del(evr->val); + E_FREE(evr); + } E_FREE(ecf); } diff --git a/src/bin/e_config.h b/src/bin/e_config.h index a44feb4d8..8fe1a4633 100644 --- a/src/bin/e_config.h +++ b/src/bin/e_config.h @@ -19,6 +19,7 @@ typedef struct _E_Config_Shelf E_Config_Shelf; typedef struct _E_Config_Shelf_Desk E_Config_Shelf_Desk; typedef struct _E_Config_Mime_Icon E_Config_Mime_Icon; typedef struct _E_Config_Syscon_Action E_Config_Syscon_Action; +typedef struct _E_Config_Env_Var E_Config_Env_Var; typedef struct _E_Event_Config_Icon_Theme E_Event_Config_Icon_Theme; #else @@ -340,6 +341,15 @@ struct _E_Config } exec; unsigned char null_container_win; + + Eina_List *env_vars; +}; + +struct _E_Config_Env_Var +{ + const char *var; + const char *val; + unsigned char unset; }; struct _E_Config_Syscon_Action diff --git a/src/bin/e_env.c b/src/bin/e_env.c new file mode 100644 index 000000000..fff9c17e0 --- /dev/null +++ b/src/bin/e_env.c @@ -0,0 +1,47 @@ +#include "e.h" + +/* local subsystem functions */ + +/* externally accessible functions */ +EINTERN int +e_env_init(void) +{ + Eina_List *l; + E_Config_Env_Var *evr; + + EINA_LIST_FOREACH(e_config->env_vars, l, evr) + { + if (evr->unset) + e_env_unset(evr->var); + else + e_env_set(evr->var, evr->val); + } + return 1; +} + +EINTERN int +e_env_shutdown(void) +{ + Eina_List *l; + E_Config_Env_Var *evr; + + EINA_LIST_FOREACH(e_config->env_vars, l, evr) + { + e_env_unset(evr->var); + } + return 1; +} + +EAPI void +e_env_set(const char *var, const char *val) +{ + e_util_env_set(var, val); +} + +EAPI void +e_env_unset(const char *var) +{ + e_util_env_set(var, NULL); +} + +/* local subsystem functions */ diff --git a/src/bin/e_env.h b/src/bin/e_env.h new file mode 100644 index 000000000..0e520f50d --- /dev/null +++ b/src/bin/e_env.h @@ -0,0 +1,15 @@ +#ifdef E_TYPEDEFS + +#else +#ifndef E_ENV_H +#define E_ENV_H + +/* init and setup */ +EINTERN int e_env_init(void); +EINTERN int e_env_shutdown(void); + +EAPI void e_env_set(const char *var, const char *val); +EAPI void e_env_unset(const char *var); + +#endif +#endif diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index fab763dbe..82460a18f 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -137,3 +137,4 @@ #include "e_widget_toolbar.h" #include "e_widget_toolbook.h" #include "e_acpi.h" +#include "e_env.h" diff --git a/src/bin/e_main.c b/src/bin/e_main.c index 38977c491..3993e8263 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -557,6 +557,15 @@ main(int argc, char **argv) } _e_main_shutdown_push(e_config_shutdown); + TS("env"); + /* init config system */ + if (!e_env_init()) + { + e_error_message_show(_("Enlightenment cannot set up its environment.")); + _e_main_shutdown(-1); + } + _e_main_shutdown_push(e_env_shutdown); + e_util_env_set("E_ICON_THEME", e_config->icon_theme); locked |= e_config->desklock_start_locked; diff --git a/src/modules/conf_paths/Makefile.am b/src/modules/conf_paths/Makefile.am index 90e6f450a..4df1daeb9 100644 --- a/src/modules/conf_paths/Makefile.am +++ b/src/modules/conf_paths/Makefile.am @@ -21,7 +21,9 @@ pkg_LTLIBRARIES = module.la module_la_SOURCES = e_mod_main.c \ e_mod_main.h \ e_int_config_paths.c \ - e_int_config_paths.h + e_int_config_paths.h \ + e_int_config_env.c \ + e_int_config_env.h module_la_LIBADD = @e_libs@ @dlopen_libs@ module_la_LDFLAGS = -module -avoid-version diff --git a/src/modules/conf_paths/e_int_config_env.c b/src/modules/conf_paths/e_int_config_env.c new file mode 100644 index 000000000..17fd6539f --- /dev/null +++ b/src/modules/conf_paths/e_int_config_env.c @@ -0,0 +1,310 @@ +#include "e.h" + +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); + +struct _E_Config_Dialog_Data +{ + E_Config_Dialog *cfd; + + Eina_List *env_vars; + + char *var_str, *val_str; + int unset; + + struct { + Evas_Object *var_en, *val_en, *unset, *list; + } gui; +}; + +E_Config_Dialog * +e_int_config_env(E_Container *con, const char *params __UNUSED__) +{ + E_Config_Dialog *cfd; + E_Config_Dialog_View *v; + + if (e_config_dialog_find("E", "advanced/environment_variables")) return NULL; + v = E_NEW(E_Config_Dialog_View, 1); + + v->create_cfdata = _create_data; + v->free_cfdata = _free_data; + v->basic.create_widgets = _basic_create_widgets; + v->basic.apply_cfdata = _basic_apply_data; + + cfd = e_config_dialog_new(con, _("Environment-variables"), + "E", "advanced/environment_variables", + "preferences-system", 0, v, NULL); + return cfd; +} + +static void +_fill_data(E_Config_Dialog_Data *cfdata) +{ + Eina_List *l; + E_Config_Env_Var *evr, *evr2; + + EINA_LIST_FOREACH(e_config->env_vars, l, evr) + { + evr2 = E_NEW(E_Config_Env_Var, 1); + evr2->var = eina_stringshare_add(evr->var); + if (evr->val) evr2->val = eina_stringshare_add(evr->val); + evr2->unset = evr->unset; + cfdata->env_vars = eina_list_append(cfdata->env_vars, evr2); + } +} + +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 __UNUSED__, E_Config_Dialog_Data *cfdata) +{ + E_Config_Env_Var *evr; + + EINA_LIST_FREE(cfdata->env_vars, evr) + { + eina_stringshare_del(evr->var); + if (evr->val) eina_stringshare_del(evr->val); + E_FREE(evr); + } + if (cfdata->var_str) free(cfdata->var_str); + if (cfdata->val_str) free(cfdata->val_str); + E_FREE(cfdata); +} + +static int +_basic_apply_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) +{ + Eina_List *l, *l2; + E_Config_Env_Var *evr, *evr2; + int same; + + // old env vars removed from new set - unset + EINA_LIST_FOREACH(e_config->env_vars, l, evr) + { + same = 0; + EINA_LIST_FOREACH(cfdata->env_vars, l2, evr2) + { + if (!strcmp(evr->var, evr2->var)) + { + same = 1; + break; + } + } + if (!same) e_env_unset(evr->var); + } + EINA_LIST_FREE(e_config->env_vars, evr) + { + eina_stringshare_del(evr->var); + if (evr->val) eina_stringshare_del(evr->val); + E_FREE(evr); + } + EINA_LIST_FOREACH(cfdata->env_vars, l, evr) + { + evr2 = E_NEW(E_Config_Env_Var, 1); + + evr2->var = eina_stringshare_add(evr->var); + if (evr->val) evr2->val = eina_stringshare_add(evr->val); + evr2->unset = evr->unset; + e_config->env_vars = eina_list_append(e_config->env_vars, evr2); + } + // set all env vars (or unset as needed) + EINA_LIST_FOREACH(e_config->env_vars, l, evr) + { + if (evr->unset) + e_env_unset(evr->var); + else + e_env_set(evr->var, evr->val); + } + + e_config_save_queue(); + return 1; +} + +static void +_sel_cb(void *data) +{ + E_Config_Dialog_Data *cfdata = data; + int sel_n = e_widget_ilist_selected_get(cfdata->gui.list); + E_Config_Env_Var *evr = eina_list_nth(cfdata->env_vars, sel_n); + if (!evr) return; + e_widget_check_checked_set(cfdata->gui.unset, evr->unset); + e_widget_disabled_set(cfdata->gui.val_en, evr->unset); + e_widget_entry_text_set(cfdata->gui.var_en, evr->var); + if ((evr->val) && (!evr->unset)) + e_widget_entry_text_set(cfdata->gui.val_en, evr->val); + else + e_widget_entry_text_set(cfdata->gui.val_en, ""); +} + +static void +_add_cb(void *data, void *data2 __UNUSED__) +{ + E_Config_Dialog_Data *cfdata = data; + Eina_List *l; + E_Config_Env_Var *evr = NULL; + int i, sel = -1; + + if (!cfdata->var_str) return; + + i = 0; + EINA_LIST_FOREACH(cfdata->env_vars, l, evr) + { + if (!strcmp(cfdata->var_str, evr->var)) + { + sel = i; + break; + } + evr = NULL; + i++; + } + if (!evr) // new + { + evr = E_NEW(E_Config_Env_Var, 1); + if (evr) + { + evr->var = eina_stringshare_add(cfdata->var_str); + if (cfdata->unset) + cfdata->unset = 1; + else + { + if (cfdata->val_str) + evr->val = eina_stringshare_add(cfdata->val_str); + cfdata->unset = 0; + } + cfdata->env_vars = eina_list_append(cfdata->env_vars, evr); + e_widget_ilist_append(cfdata->gui.list, NULL, + evr->var, _sel_cb, cfdata, NULL); + e_widget_ilist_go(cfdata->gui.list); + sel = e_widget_ilist_count(cfdata->gui.list) - 1; + e_widget_ilist_selected_set(cfdata->gui.list, sel); + e_widget_ilist_nth_show(cfdata->gui.list, sel, 0); + } + } + else // modify + { + if (evr->val) eina_stringshare_del(evr->val); + evr->val = NULL; + if (cfdata->unset) + evr->unset = 1; + else + { + if (cfdata->val_str) + evr->val = eina_stringshare_add(cfdata->val_str); + evr->unset = 0; + } + if (sel >= 0) + { + e_widget_ilist_selected_set(cfdata->gui.list, sel); + e_widget_ilist_nth_show(cfdata->gui.list, sel, 0); + } + } +} + +static void +_del_cb(void *data, void *data2 __UNUSED__) +{ + E_Config_Dialog_Data *cfdata = data; + Eina_List *l; + E_Config_Env_Var *evr = NULL; + int i, sel = -1; + + EINA_LIST_FOREACH(cfdata->env_vars, l, evr) + { + if (!strcmp(cfdata->var_str, evr->var)) + { + sel = i; + break; + } + evr = NULL; + i++; + } + if (evr) + { + eina_stringshare_del(evr->var); + if (evr->val) eina_stringshare_del(evr->val); + E_FREE(evr); + cfdata->env_vars = eina_list_remove_list(cfdata->env_vars, l); + e_widget_ilist_clear(cfdata->gui.list); + e_widget_ilist_freeze(cfdata->gui.list); + EINA_LIST_FOREACH(cfdata->env_vars, l, evr) + { + e_widget_ilist_append(cfdata->gui.list, NULL, evr->var, + _sel_cb, cfdata, NULL); + } + e_widget_ilist_go(cfdata->gui.list); + e_widget_ilist_thaw(cfdata->gui.list); + } +} + +static void +_mod_cb(void *data, void *data2 __UNUSED__) +{ + _add_cb(data, data2); +} + +static void +_unset_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + E_Config_Dialog_Data *cfdata = data; + if (cfdata->unset) e_widget_entry_text_set(cfdata->gui.val_en, ""); + e_widget_disabled_set(cfdata->gui.val_en, cfdata->unset); +} + + +static Evas_Object * +_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) +{ + Evas_Object *o, *ol, *oe, *ob, *oc; + Eina_List *l; + E_Config_Env_Var *evr; + + o = e_widget_table_add(evas, 0); + + ol = e_widget_ilist_add(evas, 0, 0, NULL); + cfdata->gui.list = ol; + e_widget_ilist_freeze(ol); + EINA_LIST_FOREACH(cfdata->env_vars, l, evr) + { + e_widget_ilist_append(ol, NULL, evr->var, _sel_cb, cfdata, NULL); + } + e_widget_ilist_go(ol); + e_widget_ilist_thaw(ol); + e_widget_size_min_set(ol, 200, 160); + e_widget_table_object_append(o, ol, 0, 0, 3, 1, 1, 1, 1, 1); + + oe = e_widget_entry_add(evas, &(cfdata->var_str), NULL, NULL, NULL); + cfdata->gui.var_en = oe; + e_widget_table_object_append(o, oe, 0, 1, 1, 1, 1, 1, 1, 0); + + oe = e_widget_entry_add(evas, &(cfdata->val_str), NULL, NULL, NULL); + cfdata->gui.val_en = oe; + e_widget_table_object_append(o, oe, 1, 1, 1, 1, 1, 1, 1, 0); + + oc = e_widget_check_add(evas, _("Unset"), &(cfdata->unset)); + cfdata->gui.unset = oc; + e_widget_table_object_append(o, oc, 2, 1, 1, 1, 1, 1, 1, 0); + evas_object_smart_callback_add(oc, "changed", _unset_cb, cfdata); + + ob = e_widget_button_add(evas, _("Add"), "list-add", _add_cb, cfdata, NULL); + e_widget_table_object_append(o, ob, 0, 2, 1, 1, 1, 1, 0, 0); + + ob = e_widget_button_add(evas, _("Modify"), NULL, _mod_cb, cfdata, NULL); + e_widget_table_object_append(o, ob, 1, 2, 1, 1, 1, 1, 0, 0); + + ob = e_widget_button_add(evas, _("Del"), "list-remove", _del_cb, cfdata, NULL); + e_widget_table_object_append(o, ob, 2, 2, 1, 1, 1, 1, 0, 0); + + e_dialog_resizable_set(cfd->dia, 1); + return o; +} diff --git a/src/modules/conf_paths/e_int_config_env.h b/src/modules/conf_paths/e_int_config_env.h new file mode 100644 index 000000000..8b4f859f6 --- /dev/null +++ b/src/modules/conf_paths/e_int_config_env.h @@ -0,0 +1,9 @@ +#ifdef E_TYPEDEFS +#else +#ifndef E_INT_CONFIG_ENV_H +#define E_INT_CONFIG_ENV_H + +E_Config_Dialog *e_int_config_env(E_Container *con, const char *params __UNUSED__); + +#endif +#endif diff --git a/src/modules/conf_paths/e_mod_main.c b/src/modules/conf_paths/e_mod_main.c index 507fcb637..4498a2124 100644 --- a/src/modules/conf_paths/e_mod_main.c +++ b/src/modules/conf_paths/e_mod_main.c @@ -20,6 +20,10 @@ e_modapi_init(E_Module *m) _("Search Directories"), NULL, "preferences-directories", e_int_config_paths); + e_configure_registry_item_add("advanced/environment_variables", 120, + _("Environment Variables"), NULL, + "preferences-system", + e_int_config_env); conf_module = m; e_module_delayed_set(m, 1); return m; @@ -30,8 +34,11 @@ e_modapi_shutdown(E_Module *m __UNUSED__) { E_Config_Dialog *cfd; + while ((cfd = e_config_dialog_get("E", "advanced/environment_variables"))) + e_object_del(E_OBJECT(cfd)); while ((cfd = e_config_dialog_get("E", "advanced/search_directories"))) e_object_del(E_OBJECT(cfd)); + e_configure_registry_item_del("advanced/environment_variables"); e_configure_registry_item_del("advanced/search_directories"); e_configure_registry_category_del("advanced"); conf_module = NULL; diff --git a/src/modules/conf_paths/e_mod_main.h b/src/modules/conf_paths/e_mod_main.h index bbfd56ef2..8bafe4da8 100644 --- a/src/modules/conf_paths/e_mod_main.h +++ b/src/modules/conf_paths/e_mod_main.h @@ -3,9 +3,11 @@ #define E_TYPEDEFS 1 #include "e_int_config_paths.h" +#include "e_int_config_env.h" #undef E_TYPEDEFS #include "e_int_config_paths.h" +#include "e_int_config_env.h" EAPI extern E_Module_Api e_modapi;