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 GList *__append_langs(const char *lang, GList *list, GHashTable *table)
130 found = g_list_find_custom(g_list_first(list), lang,
133 list = g_list_remove_link(list, found);
136 list = g_list_append(list, strdup(lang));
140 dup_lang = strdup(lang);
141 if (dup_lang == NULL)
144 token = strtok(dup_lang, "_");
150 child_list = g_hash_table_lookup(table, token);
151 if (child_list == NULL) {
156 found = g_list_find_custom(g_list_first(child_list),
157 lang, __compare_langs);
159 list = g_list_append(list, strdup(lang));
160 child_list = g_list_remove_link(child_list, found);
167 found = g_list_find_custom(g_list_first(child_list),
168 token, __compare_langs);
170 list = g_list_append(list, strdup(token));
171 child_list = g_list_remove_link(child_list, found);
179 child_iter = g_list_first(child_list);
181 child_lang = (char *)child_iter->data;
182 child_iter = g_list_next(child_iter);
184 list = g_list_append(list, strdup(child_lang));
185 child_list = g_list_remove(child_list, child_lang);
194 static GList *__split_language(const char *lang)
200 dup_lang = strdup(lang);
201 if (dup_lang == NULL) {
202 _ERR("Out of memory");
206 token = strtok(dup_lang, ":");
207 while (token != NULL) {
208 list = g_list_append(list, strdup(token));
209 token = strtok(NULL, ":");
216 static char *__get_language(const char *lang)
220 GList *lang_list = NULL;
223 char buf[LINE_MAX] = {'\0'};
226 list = __split_language(lang);
230 table = __get_lang_table();
232 g_list_free_full(list, free);
236 iter = g_list_first(list);
238 language = (char *)iter->data;
239 lang_list = __append_langs(language, lang_list, table);
240 iter = g_list_next(iter);
242 g_list_free_full(list, free);
243 g_hash_table_destroy(table);
245 iter = g_list_first(lang_list);
247 language = (char *)iter->data;
249 if (buf[0] == '\0') {
250 snprintf(buf, sizeof(buf), "%s", language);
252 n = sizeof(buf) - strlen(buf) - 1;
253 strncat(buf, ":", n);
254 n = sizeof(buf) - strlen(buf) - 1;
255 strncat(buf, language, n);
258 iter = g_list_next(iter);
260 g_list_free_full(lang_list, free);
262 n = sizeof(buf) - strlen(buf) - 1;
263 strncat(buf, ":", n);
264 n = sizeof(buf) - strlen(buf) - 1;
265 strncat(buf, "en_US:en_GB:en", n);
270 void update_lang(void)
276 lang = vconf_get_str(VCONFKEY_LANGSET);
278 /* TODO: Use VCONFKEY_SETAPPL_LANGUAGES key */
279 language = __get_language(lang);
281 _DBG("*****language(%s)", language);
282 setenv("LANGUAGE", language, 1);
285 setenv("LANGUAGE", lang, 1);
287 setenv("LANG", lang, 1);
288 setenv("LC_MESSAGES", lang, 1);
289 r = setlocale(LC_ALL, "");
291 r = setlocale(LC_ALL, lang);
293 _DBG("*****appcore setlocale=%s\n", r);
299 void update_region(void)
304 region = vconf_get_str(VCONFKEY_REGIONFORMAT);
306 setenv("LC_CTYPE", region, 1);
307 setenv("LC_NUMERIC", region, 1);
308 setenv("LC_TIME", region, 1);
309 setenv("LC_COLLATE", region, 1);
310 setenv("LC_MONETARY", region, 1);
311 setenv("LC_PAPER", region, 1);
312 setenv("LC_NAME", region, 1);
313 setenv("LC_ADDRESS", region, 1);
314 setenv("LC_TELEPHONE", region, 1);
315 setenv("LC_MEASUREMENT", region, 1);
316 setenv("LC_IDENTIFICATION", region, 1);
317 r = setlocale(LC_ALL, "");
319 _DBG("*****appcore setlocale=%s\n", r);
325 static int __set_i18n(const char *domain, const char *dir)
330 if (domain == NULL) {
335 r = setlocale(LC_ALL, "");
336 /* if locale is not set properly, try again to set as language base */
338 lan = vconf_get_str(VCONFKEY_LANGSET);
340 r = setlocale(LC_ALL, lan);
341 _DBG("*****appcore setlocale=%s\n", r);
346 _ERR("appcore: setlocale() error");
348 r = bindtextdomain(domain, dir);
350 _ERR("appcore: bindtextdomain() error");
352 r = textdomain(domain);
354 _ERR("appcore: textdomain() error");
359 static void __set_locale_dir(const char *dirname)
364 snprintf(locale_dir, sizeof(locale_dir), "%s", dirname);
367 EXPORT_API int appcore_set_i18n(const char *domainname, const char *dirname)
371 __set_locale_dir(dirname);
375 r = __set_i18n(domainname, dirname);
382 int set_i18n(const char *domainname, const char *dirname)
386 __set_locale_dir(dirname);
390 return __set_i18n(domainname, dirname);
393 EXPORT_API int appcore_get_timeformat(enum appcore_time_format *timeformat)
397 if (timeformat == NULL) {
402 r = vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, (int *)timeformat);
405 *timeformat = APPCORE_TIME_FORMAT_UNKNOWN;