4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <sys/types.h>
30 #include <linux/limits.h>
34 #include "appcore-internal.h"
37 static char locale_dir[PATH_MAX];
39 static void __free_children_langs(gpointer data)
41 GList *list = (GList *)data;
46 g_list_free_full(list, (GDestroyNotify)free);
49 static gint __compare_langs(gconstpointer a, gconstpointer b)
54 static GHashTable *__get_lang_table(void)
58 struct dirent *dentry;
66 if (locale_dir[0] == 0 || locale_dir[0] == '\0')
69 table = g_hash_table_new_full(g_str_hash, g_str_equal,
70 free, __free_children_langs);
72 _ERR("Out of memory");
76 dp = opendir(locale_dir);
78 g_hash_table_destroy(table);
82 while ((dentry = readdir(dp)) != NULL) {
83 if (!strcmp(dentry->d_name, ".") ||
84 !strcmp(dentry->d_name, ".."))
87 snprintf(buf, sizeof(buf), "%s/%s", locale_dir, dentry->d_name);
88 ret = stat(buf, &stat_buf);
89 if (ret != 0 || !S_ISDIR(stat_buf.st_mode))
92 dup_lang = strdup(dentry->d_name);
93 if (dup_lang == NULL) {
94 _ERR("Out of memory");
98 token = strtok(dup_lang, "_");
104 list = (GList *)g_hash_table_lookup(table, token);
106 list = g_list_append(list, strdup(dentry->d_name));
107 g_hash_table_insert(table, strdup(token), list);
109 list = g_list_append(list, strdup(dentry->d_name));
118 static char *__get_string_before(const char *str, const char *delim)
124 dup_str = strdup(str);
128 token = strtok(dup_str, delim);
134 new_str = strdup(token);
140 static GList *__append_langs(const char *lang, GList *list, GHashTable *table)
153 found = g_list_find_custom(g_list_first(list), lang,
156 tmp = (char *)found->data;
157 list = g_list_remove(list, tmp);
158 list = g_list_append(list, tmp);
162 extract_lang = __get_string_before(lang, ".");
163 if (extract_lang == NULL)
166 parent_lang = __get_string_before(extract_lang, "_");
167 if (parent_lang == NULL) {
172 child_list = g_hash_table_lookup(table, parent_lang);
173 if (child_list == NULL) {
179 found = g_list_find_custom(g_list_first(child_list),
180 extract_lang, __compare_langs);
182 tmp = (char *)found->data;
183 child_list = g_list_remove(child_list, tmp);
184 list = g_list_append(list, tmp);
191 found = g_list_find_custom(g_list_first(child_list),
192 parent_lang, __compare_langs);
194 tmp = (char *)found->data;
195 child_list = g_list_remove(child_list, tmp);
196 list = g_list_append(list, tmp);
202 child_iter = g_list_first(child_list);
204 child_lang = (char *)child_iter->data;
205 child_iter = g_list_next(child_iter);
207 list = g_list_append(list, strdup(child_lang));
208 child_list = g_list_remove(child_list, child_lang);
217 static GList *__split_language(const char *lang)
223 dup_lang = strdup(lang);
224 if (dup_lang == NULL) {
225 _ERR("Out of memory");
229 token = strtok(dup_lang, ":");
230 while (token != NULL) {
231 list = g_list_append(list, strdup(token));
232 token = strtok(NULL, ":");
239 static GList *__append_default_langs(GList *list)
241 const char *langs[] = {"en_US", "en_GB", "en"};
245 for (i = 0; i < (sizeof(langs) / sizeof(langs[0])); i++) {
246 found = g_list_find_custom(g_list_first(list), langs[i],
249 list = g_list_append(list, strdup(langs[i]));
255 static char *__get_language(const char *lang)
259 GList *lang_list = NULL;
262 char buf[LINE_MAX] = {'\0'};
265 list = __split_language(lang);
269 table = __get_lang_table();
271 g_list_free_full(list, free);
275 iter = g_list_first(list);
277 language = (char *)iter->data;
278 lang_list = __append_langs(language, lang_list, table);
279 iter = g_list_next(iter);
281 g_list_free_full(list, free);
282 g_hash_table_destroy(table);
284 lang_list = __append_default_langs(lang_list);
285 iter = g_list_first(lang_list);
287 language = (char *)iter->data;
289 if (buf[0] == '\0') {
290 snprintf(buf, sizeof(buf), "%s", language);
292 n = sizeof(buf) - strlen(buf) - 1;
293 strncat(buf, ":", n);
294 n = sizeof(buf) - strlen(buf) - 1;
295 strncat(buf, language, n);
298 iter = g_list_next(iter);
300 g_list_free_full(lang_list, free);
305 void update_lang(void)
311 lang = vconf_get_str(VCONFKEY_LANGSET);
313 /* TODO: Use VCONFKEY_SETAPPL_LANGUAGES key */
314 language = __get_language(lang);
316 _DBG("*****language(%s)", language);
317 setenv("LANGUAGE", language, 1);
320 setenv("LANGUAGE", lang, 1);
322 setenv("LANG", lang, 1);
323 setenv("LC_MESSAGES", lang, 1);
324 r = setlocale(LC_ALL, "");
326 r = setlocale(LC_ALL, lang);
328 _DBG("*****appcore setlocale=%s\n", r);
334 void update_region(void)
339 region = vconf_get_str(VCONFKEY_REGIONFORMAT);
341 setenv("LC_CTYPE", region, 1);
342 setenv("LC_NUMERIC", region, 1);
343 setenv("LC_TIME", region, 1);
344 setenv("LC_COLLATE", region, 1);
345 setenv("LC_MONETARY", region, 1);
346 setenv("LC_PAPER", region, 1);
347 setenv("LC_NAME", region, 1);
348 setenv("LC_ADDRESS", region, 1);
349 setenv("LC_TELEPHONE", region, 1);
350 setenv("LC_MEASUREMENT", region, 1);
351 setenv("LC_IDENTIFICATION", region, 1);
352 r = setlocale(LC_ALL, "");
354 _DBG("*****appcore setlocale=%s\n", r);
360 static int __set_i18n(const char *domain, const char *dir)
365 if (domain == NULL) {
370 r = setlocale(LC_ALL, "");
371 /* if locale is not set properly, try again to set as language base */
373 lan = vconf_get_str(VCONFKEY_LANGSET);
375 r = setlocale(LC_ALL, lan);
376 _DBG("*****appcore setlocale=%s\n", r);
381 _ERR("appcore: setlocale() error");
383 r = bindtextdomain(domain, dir);
385 _ERR("appcore: bindtextdomain() error");
387 r = textdomain(domain);
389 _ERR("appcore: textdomain() error");
394 static void __set_locale_dir(const char *dirname)
399 snprintf(locale_dir, sizeof(locale_dir), "%s", dirname);
402 EXPORT_API int appcore_set_i18n(const char *domainname, const char *dirname)
406 __set_locale_dir(dirname);
410 r = __set_i18n(domainname, dirname);
417 int set_i18n(const char *domainname, const char *dirname)
421 __set_locale_dir(dirname);
425 return __set_i18n(domainname, dirname);
428 EXPORT_API int appcore_get_timeformat(enum appcore_time_format *timeformat)
432 if (timeformat == NULL) {
437 r = vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, (int *)timeformat);
440 *timeformat = APPCORE_TIME_FORMAT_UNKNOWN;