Elementary profiles managing revamped. Most importantly:

Changes in Elementary Config application's UI now *persist*.
Not doing right now, but should be simple:
- profile deletion
- profile addition



SVN revision: 53977
This commit is contained in:
Gustavo Lima Chaves 2010-10-28 20:57:44 +00:00
parent ab3b494248
commit 5113b69035
5 changed files with 467 additions and 70 deletions

View File

@ -27,6 +27,7 @@ static const char *scale_set = NULL;
static void
my_win_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
elm_config_save();
/* called when my_win_main is requested to be deleted */
elm_exit(); /* exit the program's main loop that runs in elm_run() */
}
@ -249,6 +250,66 @@ _cf_caches(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
_flip_to(data, "caches");
}
const char *
_elm_theme_current_get(const char *theme_search_order)
{
const char *ret;
const char *p;
if (!theme_search_order)
return NULL;
for (p = theme_search_order; ; p++)
{
if ((*p == ':') || (!*p))
{
if (p > theme_search_order)
{
char *n = malloc(p - theme_search_order + 1);
if (!n)
return NULL;
strncpy(n, theme_search_order, p - theme_search_order);
n[p - theme_search_order] = 0;
ret = eina_stringshare_add(n);
free(n);
break;
}
}
}
return ret;
}
static void
_profile_change_do(Evas_Object *win, const char *profile)
{
const char *curr_theme;
Elm_Theme *th;
double scale;
int fs;
elm_profile_all_set(profile);
scale = elm_scale_get();
fs = elm_finger_size_get();
/* gotta update root windows' atoms */
elm_scale_all_set(scale);
elm_slider_value_set(evas_object_data_get(win, "scale_slider"), scale);
elm_finger_size_all_set(fs);
elm_slider_value_set(evas_object_data_get(win, "fs_slider"), fs);
curr_theme = _elm_theme_current_get(elm_theme_get(NULL));
elm_theme_all_set(curr_theme);
th = elm_theme_new();
elm_theme_set(th, curr_theme);
elm_object_theme_set(evas_object_data_get(win, "theme_preview"), th);
elm_theme_free(th);
eina_stringshare_del(curr_theme);
}
static void
_profile_use(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
@ -258,10 +319,46 @@ _profile_use(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED_
li = data;
selection = elm_list_item_data_get(elm_list_selected_item_get(li));
if (!strcmp(elm_profile_get(), selection))
if (!strcmp(elm_profile_current_get(), selection))
return;
elm_profile_all_set(selection);
elm_config_save(); /* dump config into old profile's data dir */
elm_profile_set(selection); /* just here to update info for getters below */
_profile_change_do(elm_object_top_widget_get(li), selection);
elm_config_save(); /* make sure new profile has its data dir */
}
static void
_btn_todo(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
printf("To be done!\n");
}
static void
_profile_reset(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
const char *selection, *curr;
const char *pdir;
Evas_Object *li;
li = data;
selection = elm_list_item_data_get(elm_list_selected_item_get(li));
curr = elm_profile_current_get();
pdir = elm_profile_dir_get(selection, EINA_TRUE);
if (!pdir)
return;
elm_config_save(); /* dump config into old profile's data dir */
ecore_file_recursive_rm(pdir);
free((void *)pdir);
elm_config_reload();
_profile_change_do(elm_object_top_widget_get(li), curr);
elm_config_save(); /* make sure new profile has its data dir */
}
static void
@ -297,7 +394,7 @@ _theme_sel(void *data, Evas_Object *obj, void *event_info __UNUSED__)
{
Theme *t = data;
Evas_Object *win = elm_object_top_widget_get(obj);
Evas_Object *sample = evas_object_data_get(win, "sample");
Evas_Object *sample = evas_object_data_get(win, "theme_preview");
Elm_Theme *th;
const char *defth;
char *newth;
@ -356,6 +453,7 @@ _status_config_sizing(Evas_Object *win, Evas_Object *holder)
evas_object_show(lb);
sl = elm_slider_add(win);
evas_object_data_set(win, "scale_slider", sl);
evas_object_size_hint_weight_set(sl, 1.0, 0.0);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
elm_slider_span_size_set(sl, 120);
@ -391,6 +489,7 @@ _status_config_sizing(Evas_Object *win, Evas_Object *holder)
evas_object_show(lb);
sl = elm_slider_add(win);
evas_object_data_set(win, "fs_slider", sl);
evas_object_size_hint_weight_set(sl, 1.0, 0.0);
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
elm_slider_span_size_set(sl, 120);
@ -610,7 +709,7 @@ _status_config_themes(Evas_Object *win, Evas_Object *holder)
sample = _sample_theme_new(win);
elm_scroller_content_set(sc, sample);
evas_object_show(sample);
evas_object_data_set(win, "sample", sample);
evas_object_data_set(win, "theme_preview", sample);
/////////////////////////////////////////////
sp = elm_separator_add(win);
@ -684,10 +783,10 @@ static void
_profiles_list_selected_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
{
const char *cur_profile = NULL;
char *pdir, buf[PATH_MAX];
const char *sel_profile;
const char *sel_profile, *pdir;
Eina_Bool cur_selected;
const char *prof_name;
char buf[PATH_MAX];
Evas_Object *en;
#ifdef ELM_EFREET
Efreet_Desktop *desk = NULL;
@ -695,21 +794,12 @@ _profiles_list_selected_cb(void *data, Evas_Object *obj, void *event_info __UNUS
sel_profile = data;
if (!sel_profile)
return;
return;
cur_profile = elm_profile_get();
cur_profile = elm_profile_current_get();
cur_selected = !strcmp(cur_profile, sel_profile);
elm_object_disabled_set(evas_object_data_get(obj, "prof_del_btn"),
cur_selected);
/* TODO */
/* e_config_dialog_changed_set(cfdata->cfd, !v); /\* just a flag to say */
/* user selected */
/* other profile */
/* other than curr *\/ */
pdir = elm_profile_dir_get(sel_profile);
pdir = elm_profile_dir_get(sel_profile, EINA_FALSE);
#ifdef ELM_EFREET
snprintf(buf, sizeof(buf), "%s/profile.desktop", pdir);
desk = efreet_desktop_new(buf);
@ -718,6 +808,16 @@ _profiles_list_selected_cb(void *data, Evas_Object *obj, void *event_info __UNUS
#endif
prof_name = cur_profile;
if (!pdir)
elm_object_disabled_set(evas_object_data_get(obj, "prof_reset_btn"),
cur_selected);
else
{
elm_object_disabled_set(evas_object_data_get(obj, "prof_del_btn"),
EINA_TRUE);
elm_profile_dir_free(pdir);
}
snprintf(buf, sizeof(buf), "<hilight>Selected profile: %s</><br>",
prof_name);
elm_label_label_set(evas_object_data_get(obj, "prof_name_lbl"), buf);
@ -747,19 +847,19 @@ _profiles_list_fill(Evas_Object *l_widget, Eina_List *p_names)
elm_list_clear(l_widget);
cur_profile = elm_profile_get();
cur_profile = elm_profile_current_get();
EINA_LIST_FOREACH(p_names, l, profile)
{
char buf[PATH_MAX], *pdir;
const char *label, *ext;
Evas_Object *ic;
Elm_List_Item *it;
#ifdef ELM_EFREET
Efreet_Desktop *desk = NULL;
#endif
pdir = elm_profile_dir_get(profile);
const char *label, *ext, *pdir;
char buf[PATH_MAX];
Elm_List_Item *it;
Evas_Object *ic;
pdir = elm_profile_dir_get(profile, EINA_FALSE);
label = profile;
#ifdef ELM_EFREET
@ -792,8 +892,7 @@ _profiles_list_fill(Evas_Object *l_widget, Eina_List *p_names)
if (cur_profile && !strcmp(profile, cur_profile))
sel_it = it;
if (pdir)
free(pdir);
elm_profile_dir_free(pdir);
#ifdef ELM_EFREET
if (desk) efreet_desktop_free(desk);
@ -879,15 +978,15 @@ _status_config_profiles(Evas_Object *win, Evas_Object *holder)
bt = elm_button_add(win);
evas_object_smart_callback_add(bt, "clicked", _profile_use, li);
elm_button_label_set(bt, "Use profile");
elm_button_label_set(bt, "Use");
evas_object_size_hint_weight_set(bt, 0.0, 0.0);
evas_object_size_hint_align_set(bt, 0.5, 0.5);
elm_box_pack_end(btn_bx, bt);
evas_object_show(bt);
bt = elm_button_add(win);
evas_object_smart_callback_add(bt, "clicked", NULL, NULL); /* TODO */
elm_button_label_set(bt, "Delete profile");
evas_object_smart_callback_add(bt, "clicked", _btn_todo, NULL); /* TODO */
elm_button_label_set(bt, "Delete");
evas_object_size_hint_weight_set(bt, 0.0, 0.0);
evas_object_size_hint_align_set(bt, 0.5, 0.5);
elm_box_pack_end(btn_bx, bt);
@ -896,7 +995,17 @@ _status_config_profiles(Evas_Object *win, Evas_Object *holder)
evas_object_data_set(li, "prof_del_btn", bt);
bt = elm_button_add(win);
evas_object_smart_callback_add(bt, "clicked", NULL, NULL); /* TODO */
evas_object_smart_callback_add(bt, "clicked", _profile_reset, li);
elm_button_label_set(bt, "Reset");
evas_object_size_hint_weight_set(bt, 0.0, 0.0);
evas_object_size_hint_align_set(bt, 0.5, 0.5);
elm_box_pack_end(btn_bx, bt);
evas_object_show(bt);
evas_object_data_set(li, "prof_reset_btn", bt);
bt = elm_button_add(win);
evas_object_smart_callback_add(bt, "clicked", _btn_todo, NULL); /* TODO */
elm_button_label_set(bt, "Add new");
evas_object_size_hint_weight_set(bt, 0.0, 0.0);
evas_object_size_hint_align_set(bt, 0.5, 0.5);

View File

@ -333,8 +333,11 @@ extern "C" {
EAPI void elm_scale_set(double scale);
EAPI void elm_scale_all_set(double scale);
EAPI const char *elm_profile_get(void);
EAPI char *elm_profile_dir_get(const char *profile);
EAPI Eina_Bool elm_config_save(void);
EAPI void elm_config_reload(void);
EAPI const char *elm_profile_current_get(void);
EAPI const char *elm_profile_dir_get(const char *profile, Eina_Bool is_user);
EAPI void elm_profile_dir_free(const char *p_dir);
EAPI Eina_List *elm_profile_list_get(void);
EAPI void elm_profile_list_free(Eina_List *l);

View File

@ -295,21 +295,74 @@ _elm_config_current_profile_get(void)
return _elm_profile;
}
char *
_elm_config_profile_dir_get(const char *prof)
static size_t
_elm_data_dir_snprintf(char *dst, size_t size, const char *fmt, ...)
{
char buf[PATH_MAX];
const char *home = NULL;
size_t data_dir_len, off;
va_list ap;
data_dir_len = eina_str_join_len(dst, size, '/', _elm_data_dir,
strlen(_elm_data_dir), "config",
sizeof("config") - 1);
off = data_dir_len + 1;
if (off >= size)
goto end;
va_start(ap, fmt);
dst[data_dir_len] = '/';
off = off + vsnprintf(dst + off, size - off, fmt, ap);
va_end(ap);
end:
return off;
}
static size_t
_elm_user_dir_snprintf(char *dst, size_t size, const char *fmt, ...)
{
const char *home;
size_t user_dir_len, off;
va_list ap;
home = getenv("HOME");
if (!home)
home = "/";
snprintf(buf, sizeof(buf), "%s/.elementary/config/%s", home, prof);
user_dir_len = eina_str_join_len(dst, size, '/', home, strlen(home),
".elementary", sizeof(".elementary") - 1);
off = user_dir_len + 1;
if (off >= size)
goto end;
va_start(ap, fmt);
dst[user_dir_len] = '/';
off = off + vsnprintf(dst + off, size - off, fmt, ap);
va_end(ap);
end:
return off;
}
const char *
_elm_config_profile_dir_get(const char *prof, Eina_Bool is_user)
{
char buf[PATH_MAX];
if (!is_user)
goto not_user;
_elm_user_dir_snprintf(buf, sizeof(buf), "config/%s", prof);
if (ecore_file_is_dir(buf))
return strdup(buf);
return NULL;
not_user:
snprintf(buf, sizeof(buf), "%s/config/%s", _elm_data_dir, prof);
if (ecore_file_is_dir(buf))
@ -322,7 +375,6 @@ Eina_List *
_elm_config_profiles_list(void)
{
const Eina_File_Direct_Info *info;
const char *home = NULL;
Eina_List *flist = NULL;
Eina_Iterator *file_it;
struct stat buffer;
@ -330,13 +382,7 @@ _elm_config_profiles_list(void)
const char *dir;
size_t len;
home = getenv("HOME");
if (!home)
home = "/";
len = eina_str_join_len(buf, sizeof(buf), '/', home, strlen(home),
".elementary/config",
sizeof(".elementary/config") - 1);
len = _elm_user_dir_snprintf(buf, sizeof(buf), "config");
file_it = eina_file_direct_ls(buf);
if (!file_it)
@ -466,8 +512,8 @@ _profile_fetch_from_conf(void)
home = getenv("HOME");
if (!home) home = "/";
// usser profile
snprintf(buf, sizeof(buf), "%s/.elementary/config/profile.cfg", home);
// user profile
_elm_user_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
ef = eet_open(buf, EET_FILE_MODE_READ);
if (ef)
{
@ -486,7 +532,7 @@ _profile_fetch_from_conf(void)
if (ef) return;
// system profile
snprintf(buf, sizeof(buf), "%s/config/profile.cfg", _elm_data_dir);
_elm_data_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
ef = eet_open(buf, EET_FILE_MODE_READ);
if (ef)
{
@ -540,13 +586,10 @@ _config_user_load(void)
Elm_Config *cfg = NULL;
Eet_File *ef;
char buf[PATH_MAX];
const char *home;
home = getenv("HOME");
if (!home) home = "";
_elm_user_dir_snprintf(buf, sizeof(buf), "config/%s/base.cfg",
_elm_profile);
snprintf(buf, sizeof(buf), "%s/.elementary/config/%s/base.cfg", home,
_elm_profile);
ef = eet_open(buf, EET_FILE_MODE_READ);
if (ef)
{
@ -563,8 +606,9 @@ _config_system_load(void)
Eet_File *ef;
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), "%s/config/%s/base.cfg", _elm_data_dir,
_elm_profile);
_elm_data_dir_snprintf(buf, sizeof(buf), "config/%s/base.cfg",
_elm_profile);
ef = eet_open(buf, EET_FILE_MODE_READ);
if (ef)
{
@ -629,6 +673,182 @@ _config_load(void)
_elm_config->icon_size = 32;
}
static const char *
_elm_config_eet_close_error_get(Eet_File *ef, char *file)
{
Eet_Error err;
char *erstr = NULL;
err = eet_close(ef);
switch (err)
{
case EET_ERROR_WRITE_ERROR:
erstr = "An error occurred while saving Elementary's "
"settings to disk. The error could not be "
"deterimined. The file where the error occurred was: "
"%s. This file has been deleted to avoid corrupt data.";
break;
case EET_ERROR_WRITE_ERROR_FILE_TOO_BIG:
erstr = "Elementary's settings files are too big "
"for the file system they are being saved to. "
"This error is very strange as the files should "
"be extremely small. Please check the settings "
"for your home directory. "
"The file where the error occurred was: %s ."
"This file has been deleted to avoid corrupt data.";
break;
case EET_ERROR_WRITE_ERROR_IO_ERROR:
erstr = "An output error occurred when writing the settings "
"files for Elementary. Your disk is having troubles "
"and possibly needs replacement. "
"The file where the error occurred was: %s ."
"This file has been deleted to avoid corrupt data.";
break;
case EET_ERROR_WRITE_ERROR_OUT_OF_SPACE:
erstr = "Elementary cannot write its settings file "
"because it ran out of space to write the file. "
"You have either run out of disk space or have "
"gone over your quota limit. "
"The file where the error occurred was: %s ."
"This file has been deleted to avoid corrupt data.";
break;
case EET_ERROR_WRITE_ERROR_FILE_CLOSED:
erstr = "Elementary unexpectedly had the settings file "
"it was writing closed on it. This is very unusual. "
"The file where the error occurred was: %s "
"This file has been deleted to avoid corrupt data.";
break;
default:
break;
}
if (erstr)
{
/* delete any partially-written file */
ecore_file_unlink(file);
return strdup(erstr);
}
return NULL;
}
static Eina_Bool
_elm_config_profile_save(void)
{
char buf[4096], buf2[4096];
int ok = 0, ret;
const char *err;
Eet_File *ef;
size_t len;
len = _elm_user_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
if (len + 1 >= sizeof(buf))
return EINA_FALSE;
len = _elm_user_dir_snprintf(buf2, sizeof(buf2), "config/profile.cfg.tmp");
if (len + 1 >= sizeof(buf2))
return EINA_FALSE;
ef = eet_open(buf2, EET_FILE_MODE_WRITE);
if (!ef)
return EINA_FALSE;
ok = eet_write(ef, "config", _elm_profile, strlen(_elm_profile), 0);
if (!ok)
goto err;
err = _elm_config_eet_close_error_get(ef, buf2);
if (err)
{
ERR("%s", err);
free((void *)err);
goto err;
}
ret = ecore_file_mv(buf2, buf);
if (!ret)
{
ERR("Error saving Elementary's configuration file");
goto err;
}
ecore_file_unlink(buf2);
return EINA_TRUE;
err:
ecore_file_unlink(buf2);
return EINA_FALSE;
}
Eina_Bool
_elm_config_save(void)
{
char buf[4096], buf2[4096];
int ok = 0, ret;
const char *err;
Eet_File *ef;
size_t len;
if (!_elm_config_profile_save())
return EINA_FALSE;
len = _elm_user_dir_snprintf(buf, sizeof(buf), "config/%s", _elm_profile);
if (len + 1 >= sizeof(buf))
return EINA_FALSE;
ok = ecore_file_mkpath(buf);
if (!ok)
{
ERR("Problem acessing Elementary's user configuration directory: %s",
buf);
return EINA_FALSE;
}
buf[len] = '/';
len++;
if (len + sizeof("base.cfg") >= sizeof(buf) - len)
return EINA_FALSE;
memcpy(buf + len, "base.cfg", sizeof("base.cfg"));
len += sizeof("base.cfg") - 1;
if (len + sizeof(".tmp") >= sizeof(buf))
return EINA_FALSE;
memcpy(buf2, buf, len);
memcpy(buf2 + len, ".tmp", sizeof(".tmp"));
ef = eet_open(buf2, EET_FILE_MODE_WRITE);
if (!ef)
return EINA_FALSE;
ok = eet_data_write(ef, _config_edd, "config", _elm_config, 1);
if (!ok)
goto err;
err = _elm_config_eet_close_error_get(ef, buf2);
if (err)
{
ERR("%s", err);
free((void *)err);
goto err;
}
ret = ecore_file_mv(buf2, buf);
if (!ret)
{
ERR("Error saving Elementary's configuration file");
goto err;
}
ecore_file_unlink(buf2);
return EINA_TRUE;
err:
ecore_file_unlink(buf2);
return EINA_FALSE;
}
static void
_config_update(void)
{
@ -949,8 +1169,15 @@ _elm_config_sub_init(void)
_config_sub_apply();
}
/* TODO: dump old profile's entries to disk? keep default values, for
reset action? */
void
_elm_config_reload(void)
{
_config_free();
_config_load();
_config_apply();
_elm_rescale();
}
void
_elm_config_profile_set(const char *profile)
{
@ -962,6 +1189,7 @@ _elm_config_profile_set(const char *profile)
changed = 1;
free(_elm_profile);
}
_elm_profile = strdup(profile);
if (changed)

View File

@ -1210,6 +1210,53 @@ elm_scale_all_set(double scale)
#endif
}
/**
* @defgroup Config Elementary Config
*
* Elementary configuration is formed by a set options bounded to a
* given @ref Profile profile, like @ref Theme theme, @ref Fingers
* "finger size", etc. These are functions with which one syncronizes
* changes made to those values to the configuration storing files, de
* facto. You most probably don't want to use the functions in this
* group unlees you're writing an elementary configuration manager.
*/
/**
* Save back Elementary's configuration, so that it will persist on
* future sessions.
*
* @return @c EINA_TRUE, when sucessful. @c EINA_FALSE, otherwise.
* @ingroup Config
*
* This function will take effect -- thus, do I/O -- immediately. Use
* it when you want to apply all configuration changes at once. The
* current configuration set will get saved onto the current profile
* configuration file.
*
*/
EAPI Eina_Bool
elm_config_save(void)
{
return _elm_config_save();
}
/**
* Reload Elementary's configuration, bounded to current selected
* profile.
*
* @return @c EINA_TRUE, when sucessful. @c EINA_FALSE, otherwise.
* @ingroup Config
*
* Useful when you want to force reloading of configuration values for
* a profile. If one removes user custom configuration directories,
* for example, it will force a reload with system values insted.
*
*/
EAPI void
elm_config_reload(void)
{
_elm_config_reload();
}
/**
* @defgroup Profile Elementary Profile
@ -1217,7 +1264,7 @@ elm_scale_all_set(double scale)
* Profiles are pre-set options that affect the whole look-and-feel of
* Elementary-based applications. There are, for example, profiles
* aimed at desktop computer applications and others aimed at mobile,
* touchscreen-based ones. You probably don't want to use the
* touchscreen-based ones. You most probably don't want to use the
* functions in this group unlees you're writing an elementary
* configuration manager.
*/
@ -1232,24 +1279,28 @@ elm_scale_all_set(double scale)
* @ingroup Profile
*/
EAPI const char *
elm_profile_get(void)
elm_profile_current_get(void)
{
return _elm_config_current_profile_get();
}
/**
* Get an Elementary's profile directory path in the filesystem.
* Get an Elementary's profile directory path in the filesystem. One
* may want to fetch a system profile's dir or an user one (fetched
* inside $HOME).
*
* @param profile The profile's name
* @param is_user Whether to lookup for an user profile (@c EINA_TRUE)
* or a system one (@c EINA_FALSE)
* @return The profile's directory path.
* @ingroup Profile
*
* @note You must free it with elm_profile_dir_free().
*/
EAPI char *
elm_profile_dir_get(const char *profile)
EAPI const char *
elm_profile_dir_get(const char *profile, Eina_Bool is_user)
{
return _elm_config_profile_dir_get(profile);
return _elm_config_profile_dir_get(profile, is_user);
}
/**
@ -1291,17 +1342,17 @@ elm_profile_list_get(void)
EAPI void
elm_profile_list_free(Eina_List *l)
{
const char *dir;
const char *dir;
EINA_LIST_FREE(l, dir)
eina_stringshare_del(dir);
EINA_LIST_FREE(l, dir)
eina_stringshare_del(dir);
}
/**
* Set Elementary's profile.
*
* This sets the global profile that is applied to Elementary
* applications. Just the instance the call comes from will be
* applications. Just the process the call comes from will be
* affected.
*
* @param profile The profile's name
@ -1311,6 +1362,8 @@ elm_profile_list_free(Eina_List *l)
EAPI void
elm_profile_set(const char *profile)
{
if (!profile)
return;
_elm_config_profile_set(profile);
}
@ -1330,7 +1383,8 @@ elm_profile_all_set(const char *profile)
#ifdef HAVE_ELEMENTARY_X
static Ecore_X_Atom atom = 0;
if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_PROFILE");
if (!atom)
atom = ecore_x_atom_get("ENLIGHTENMENT_PROFILE");
ecore_x_window_prop_string_set(ecore_x_window_root_first_get(),
atom, profile);
#endif

View File

@ -145,8 +145,11 @@ void _elm_rescale(void);
void _elm_config_init(void);
void _elm_config_sub_init(void);
void _elm_config_shutdown(void);
Eina_Bool _elm_config_save(void);
void _elm_config_reload(void);
const char *_elm_config_current_profile_get(void);
char *_elm_config_profile_dir_get(const char *prof);
const char *_elm_config_profile_dir_get(const char *prof, Eina_Bool is_user);
Eina_List *_elm_config_profiles_list(void);
void _elm_config_profile_set(const char *profile);