From 88bc1e83e57ed8097233a4f3ec362782978f02ae Mon Sep 17 00:00:00 2001 From: Kim Woelders Date: Fri, 21 Apr 2006 23:47:30 +0000 Subject: [PATCH] Enable configuring internal and exported language. SVN revision: 22285 --- src/actions.c | 4 ++ src/econfig.c | 2 + src/lang.c | 116 +++++++++++++++++++++++++++++++++++++++++++++---- src/lang.h | 3 ++ src/main.c | 17 ++++---- src/mod-misc.c | 2 + src/session.c | 2 + 7 files changed, 130 insertions(+), 16 deletions(-) diff --git a/src/actions.c b/src/actions.c index 76c18e2a..5e6af7db 100644 --- a/src/actions.c +++ b/src/actions.c @@ -40,6 +40,8 @@ runApp(const char *exe, const char *params) for (fd = 3; fd < 1024; fd++) close(fd); + LangExport(); + sh = usershell(getuid()); if (exe) { @@ -175,6 +177,8 @@ Espawn(int argc __UNUSED__, char **argv) for (fd = 3; fd < 1024; fd++) close(fd); + LangExport(); + execvp(argv[0], argv); DialogAlertOK(_("There was an error running the program:\n%s\n"), argv[0]); diff --git a/src/econfig.c b/src/econfig.c index 9f9111fa..d6683f65 100644 --- a/src/econfig.c +++ b/src/econfig.c @@ -407,6 +407,8 @@ CfgItemSetFromString(const CfgItem * ci, const char *str) case ITEM_TYPE_STRING: if (*(char **)ci->ptr) Efree(*(char **)ci->ptr); + if (*str == '\0') + str = NULL; *((char **)ci->ptr) = Estrdup(str); break; } diff --git a/src/lang.c b/src/lang.c index 1c2f351c..91e42a13 100644 --- a/src/lang.c +++ b/src/lang.c @@ -22,6 +22,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "E.h" +#include "emodule.h" #include "lang.h" #ifdef HAVE_LOCALE_H @@ -121,6 +122,7 @@ EstrInt2Enc(const char *str, int want_utf8) return Eiconv(iconv_cd_int2loc, str, strlen(str)); #else + want_utf8 = 0; return str; #endif } @@ -135,16 +137,83 @@ EstrInt2EncFree(const char *str, int want_utf8) if (str) Efree((char *)str); +#else + str = NULL; + want_utf8 = 0; #endif } +static struct +{ + char *internal; + char *exported; +} Conf_locale = +{ +NULL, NULL}; + +static struct +{ + char init; + char *env_language; + char *env_lc_all; + char *env_lc_messages; + char *env_lang; +} locale_data; + +static void +LangEnvironmentSetup(const char *locale) +{ + /* Precedence: LANGUAGE, LC_ALL, LC_MESSAGES, LANG */ + if (locale) + { + /* Set requested */ + Esetenv("LANGUAGE", locale); + Esetenv("LC_ALL", locale); + Esetenv("LANG", locale); + } + else + { + /* Restore saved */ + Esetenv("LANGUAGE", locale_data.env_language); + Esetenv("LC_ALL", locale_data.env_lc_all); + Esetenv("LC_MESSAGES", locale_data.env_lc_messages); + Esetenv("LANG", locale_data.env_lang); + } +} + +static void +LangEnvironmentSave(void) +{ + if (locale_data.init) + return; + locale_data.init = 1; + + locale_data.env_language = Estrdup(getenv("LANGUAGE")); + locale_data.env_lc_all = Estrdup(getenv("LC_ALL")); + locale_data.env_lc_messages = Estrdup(getenv("LC_MESSAGES")); + locale_data.env_lang = Estrdup(getenv("LANG")); +} + +void +LangExport(void) +{ + if (Conf_locale.exported) + LangEnvironmentSetup(Conf_locale.exported); + else if (Conf_locale.internal) + LangEnvironmentSetup(NULL); +} + void LangInit(void) { const char *enc_loc, *enc_int; - /* Set up things according to env vars */ - setlocale(LC_ALL, ""); + if (!locale_data.init) + LangEnvironmentSave(); + + LangEnvironmentSetup(Conf_locale.internal); + + setlocale(LC_ALL, ""); /* Set up things according to env vars */ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -199,13 +268,44 @@ LangInit(void) #endif } -#if 0 /* Not used yet */ - -static void +void LangExit(void) { - if (iconv_cd) - iconv_close(iconv_cd); +#if HAVE_ICONV + if (iconv_cd_int2utf8) + iconv_close(iconv_cd_int2utf8); + if (iconv_cd_utf82int) + iconv_close(iconv_cd_utf82int); + if (iconv_cd_int2loc) + iconv_close(iconv_cd_int2loc); + if (iconv_cd_loc2int) + iconv_close(iconv_cd_loc2int); + iconv_cd_int2utf8 = iconv_cd_utf82int = NULL; + iconv_cd_int2loc = iconv_cd_loc2int = NULL; +#endif + + LangEnvironmentSetup(NULL); } -#endif +static void +LangCfgChange(void *item __UNUSED__, const char *locale) +{ + if (*locale == '\0') + locale = NULL; + LangExit(); + _EFDUP(Conf_locale.internal, locale); + LangInit(); +} + +static const CfgItem LocaleCfgItems[] = { + CFG_FUNC_STR(Conf_locale, internal, LangCfgChange), + CFG_ITEM_STR(Conf_locale, exported), +}; +#define N_CFG_ITEMS (sizeof(LocaleCfgItems)/sizeof(CfgItem)) + +const EModule ModLocale = { + "locale", NULL, + NULL, + {0, NULL}, + {N_CFG_ITEMS, LocaleCfgItems} +}; diff --git a/src/lang.h b/src/lang.h index c2da7731..965c22f8 100644 --- a/src/lang.h +++ b/src/lang.h @@ -41,6 +41,9 @@ /* lang.c */ void LangInit(void); +void LangExit(void); +void LangExport(void); + char *EstrLoc2Int(const char *str, int len); char *EstrUtf82Int(const char *str, int len); const char *EstrInt2Enc(const char *str, int want_utf8); diff --git a/src/main.c b/src/main.c index 564cd90c..4a844fdf 100644 --- a/src/main.c +++ b/src/main.c @@ -212,21 +212,21 @@ main(int argc, char **argv) } } - /* Initialise internationalisation */ - LangInit(); + SignalsSetup(); /* Install signal handlers */ - /* run most of the setup */ - SignalsSetup(); SetupX(dstr); /* This is where the we fork per screen */ /* X is now running, and we have forked per screen */ + /* So far nothing should rely on a selected settings or theme. */ + ConfigurationLoad(); /* Load settings */ + + /* Initialise internationalisation */ + LangInit(); + ECheckEprog("epp"); ECheckEprog("eesh"); EDirsSetup(); - /* So far nothing should rely on a selected settings or theme. */ - ConfigurationLoad(); /* Load settings */ - /* The theme path must now be available for config file loading. */ ThemePathFind(); @@ -466,12 +466,13 @@ RunDocBrowser(void) static void RunMenuGen(void) { - char file[FILEPATH_LEN_MAX]; if (fork()) return; + LangExport(); + Esnprintf(file, sizeof(file), "exec %s/scripts/e_gen_menu", EDirRoot()); execl(usershell(getuid()), usershell(getuid()), "-c", (char *)file, NULL); exit(0); diff --git a/src/mod-misc.c b/src/mod-misc.c index 94592327..12484017 100644 --- a/src/mod-misc.c +++ b/src/mod-misc.c @@ -45,6 +45,7 @@ extern const EModule ModFocus; extern const EModule ModGroups; extern const EModule ModImageclass; extern const EModule ModIconboxes; +extern const EModule ModLocale; extern const EModule ModMenus; extern const EModule ModMisc; extern const EModule ModPagers; @@ -75,6 +76,7 @@ const EModule *p_modules[] = { &ModGroups, &ModIconboxes, &ModImageclass, + &ModLocale, &ModMenus, &ModMisc, &ModPagers, diff --git a/src/session.c b/src/session.c index 03491bec..f6168525 100644 --- a/src/session.c +++ b/src/session.c @@ -513,6 +513,8 @@ doSMExit(int mode, const char *params) if (mode != EEXIT_THEME && mode != EEXIT_RESTART) SessionHelper(ESESSION_STOP); + LangExit(); + if (disp) { /* We may get here from HandleXIOError */