X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fbase%2Fappcore_base.c;h=2f7298b05408a4a7511d724ee88b8f589041410b;hb=refs%2Fchanges%2F28%2F113328%2F10;hp=7c1b82662be66615bc373beb2fde03c0dd54db8b;hpb=5ce24250be4c50783b93221e76fe58411e5f3dcd;p=platform%2Fcore%2Fappfw%2Fapp-core.git diff --git a/src/base/appcore_base.c b/src/base/appcore_base.c index 7c1b826..2f7298b 100644 --- a/src/base/appcore_base.c +++ b/src/base/appcore_base.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,7 @@ static appcore_base_context __context; static GList *__events; static GDBusConnection *__bus; static guint __suspend_dbus_handler_initialized; +static char *__locale_dir; static void __invoke_callback(void *event, int type) { @@ -114,16 +116,255 @@ static void __on_low_battery(keynode_t *key, void *data) __invoke_callback(key, APPCORE_BASE_EVENT_LOW_BATTERY); } +static void __free_children_langs(gpointer data) +{ + GList *list = (GList *)data; + + if (list == NULL) + return; + + g_list_free_full(list, (GDestroyNotify)free); +} + +static gint __compare_langs(gconstpointer a, gconstpointer b) +{ + return strcmp(a, b); +} + +static GHashTable *__get_lang_table(void) +{ + GHashTable *table; + DIR *dp; + struct dirent *dentry; + char buf[PATH_MAX]; + struct stat stat_buf; + int ret; + char *dup_lang; + char *token; + GList *list; + + if (__locale_dir == NULL || __locale_dir[0] == '\0') + return NULL; + + table = g_hash_table_new_full(g_str_hash, g_str_equal, + free, __free_children_langs); + if (table == NULL) { + _ERR("Out of memory"); + return NULL; + } + + dp = opendir(__locale_dir); + if (dp == NULL) { + g_hash_table_destroy(table); + return NULL; + } + + while ((dentry = readdir(dp)) != NULL) { + if (!strcmp(dentry->d_name, ".") || + !strcmp(dentry->d_name, "..")) + continue; + + snprintf(buf, sizeof(buf), "%s/%s", + __locale_dir, dentry->d_name); + ret = stat(buf, &stat_buf); + if (ret != 0 || !S_ISDIR(stat_buf.st_mode)) + continue; + + dup_lang = strdup(dentry->d_name); + if (dup_lang == NULL) { + _ERR("Out of memory"); + break; + } + + token = strtok(dup_lang, "_"); + if (token == NULL) { + free(dup_lang); + continue; + } + + list = (GList *)g_hash_table_lookup(table, token); + if (list == NULL) { + list = g_list_append(list, strdup(dentry->d_name)); + g_hash_table_insert(table, strdup(token), list); + } else { + list = g_list_append(list, strdup(dentry->d_name)); + } + free(dup_lang); + } + closedir(dp); + + return table; +} + +static GList *__append_langs(const char *lang, GList *list, GHashTable *table) +{ + GList *child_list; + GList *child_iter; + GList *found; + char *child_lang; + char *dup_lang; + char *token; + + if (lang == NULL) + return list; + + found = g_list_find_custom(g_list_first(list), lang, + __compare_langs); + if (found) { + list = g_list_remove_link(list, found); + free(found->data); + g_list_free(found); + list = g_list_append(list, strdup(lang)); + return list; + } + + dup_lang = strdup(lang); + if (dup_lang == NULL) + return list; + + token = strtok(dup_lang, "_"); + if (token == NULL) { + free(dup_lang); + return list; + } + + child_list = g_hash_table_lookup(table, token); + if (child_list == NULL) { + free(dup_lang); + return list; + } + + found = g_list_find_custom(g_list_first(child_list), + lang, __compare_langs); + if (found) { + list = g_list_append(list, strdup(lang)); + child_list = g_list_remove_link(child_list, found); + free(found->data); + g_list_free(found); + free(dup_lang); + return list; + } + + found = g_list_find_custom(g_list_first(child_list), + token, __compare_langs); + if (found) { + list = g_list_append(list, strdup(token)); + child_list = g_list_remove_link(child_list, found); + free(found->data); + g_list_free(found); + free(dup_lang); + return list; + } + free(dup_lang); + + child_iter = g_list_first(child_list); + while (child_iter) { + child_lang = (char *)child_iter->data; + child_iter = g_list_next(child_iter); + if (child_lang) { + list = g_list_append(list, strdup(child_lang)); + child_list = g_list_remove(child_list, child_lang); + free(child_lang); + break; + } + } + + return list; +} + +static GList *__split_language(const char *lang) +{ + GList *list = NULL; + char *dup_lang; + char *token; + + dup_lang = strdup(lang); + if (dup_lang == NULL) { + _ERR("Out of memory"); + return NULL; + } + + token = strtok(dup_lang, ":"); + while (token != NULL) { + list = g_list_append(list, strdup(token)); + token = strtok(NULL, ":"); + } + free(dup_lang); + + return list; +} + +static char *__get_language(const char *lang) +{ + GHashTable *table; + GList *list; + GList *lang_list = NULL; + GList *iter; + char *language; + char buf[LINE_MAX] = {'\0'}; + size_t n; + + list = __split_language(lang); + if (list == NULL) + return NULL; + + table = __get_lang_table(); + if (table == NULL) { + g_list_free_full(list, free); + return NULL; + } + + iter = g_list_first(list); + while (iter) { + language = (char *)iter->data; + lang_list = __append_langs(language, lang_list, table); + iter = g_list_next(iter); + } + g_list_free_full(list, free); + g_hash_table_destroy(table); + + iter = g_list_first(lang_list); + while (iter) { + language = (char *)iter->data; + if (language) { + if (buf[0] == '\0') { + snprintf(buf, sizeof(buf), "%s", language); + } else { + n = sizeof(buf) - strlen(buf) - 1; + strncat(buf, ":", n); + n = sizeof(buf) - strlen(buf) - 1; + strncat(buf, language, n); + } + } + iter = g_list_next(iter); + } + g_list_free_full(lang_list, free); + + n = sizeof(buf) - strlen(buf) - 1; + strncat(buf, ":", n); + n = sizeof(buf) - strlen(buf) - 1; + strncat(buf, "en_US:en_GB:en", n); + + return strdup(buf); +} + static void __update_lang(void) { - char language[32]; + char *language; char *lang; char *r; lang = vconf_get_str(VCONFKEY_LANGSET); if (lang) { - snprintf(language, sizeof(language), "%s:en_US:en_GB:en", lang); - setenv("LANGUAGE", language, 1); + /* TODO: Use VCONFKEY_SETAPPL_LANGUAGES key */ + language = __get_language(lang); + if (language) { + _DBG("*****language(%s)", language); + setenv("LANGUAGE", language, 1); + free(language); + } else { + setenv("LANGUAGE", language, 1); + } setenv("LANG", lang, 1); setenv("LC_MESSAGES", lang, 1); r = setlocale(LC_ALL, ""); @@ -356,6 +597,12 @@ static int __set_i18n(const char *domain, const char *dir) if (r == NULL) _ERR("appcore: setlocale() error"); + if (dir) { + if (__locale_dir) + free(__locale_dir); + __locale_dir = strdup(dir); + } + r = bindtextdomain(domain, dir); if (r == NULL) _ERR("appcore: bindtextdomain() error"); @@ -444,6 +691,10 @@ EXPORT_API void appcore_base_fini(void) if (__context.ops.terminate) __context.ops.terminate(__context.data); + if (__locale_dir) { + free(__locale_dir); + __locale_dir = NULL; + } } EXPORT_API int appcore_base_flush_memory(void)