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"
42 static char locale_dir[PATH_MAX];
44 static void __destroy_lang_info(gpointer data)
46 struct lang_info_s *info = (struct lang_info_s *)data;
52 g_list_free_full(info->list, free);
58 static struct lang_info_s *__create_lang_info(const char *lang)
60 struct lang_info_s *info;
62 info = calloc(1, sizeof(struct lang_info_s));
64 _ERR("Out of memory");
68 info->parent = strdup(lang);
69 if (info->parent == NULL) {
70 _ERR("Out of memory");
78 static gint __compare_langs(gconstpointer a, gconstpointer b)
86 static char *__get_string_before(const char *str, const char *delim)
92 dup_str = strdup(str);
96 token = strtok(dup_str, delim);
102 new_str = strdup(token);
108 static GHashTable *__get_lang_table(void)
112 struct dirent *dentry;
114 struct stat stat_buf;
117 struct lang_info_s *info;
119 if (locale_dir[0] == 0 || locale_dir[0] == '\0')
122 table = g_hash_table_new_full(g_str_hash, g_str_equal,
123 NULL, __destroy_lang_info);
125 _ERR("Out of memory");
129 dp = opendir(locale_dir);
131 g_hash_table_destroy(table);
135 while ((dentry = readdir(dp)) != NULL) {
136 if (!strcmp(dentry->d_name, ".") ||
137 !strcmp(dentry->d_name, ".."))
140 snprintf(buf, sizeof(buf), "%s/%s", locale_dir, dentry->d_name);
141 ret = stat(buf, &stat_buf);
142 if (ret != 0 || !S_ISDIR(stat_buf.st_mode))
145 parent_lang = __get_string_before(dentry->d_name, "_");
146 if (parent_lang == NULL) {
147 _ERR("Out of memory");
151 info = g_hash_table_lookup(table, parent_lang);
153 info = __create_lang_info(parent_lang);
158 g_hash_table_insert(table, info->parent, info);
160 info->list = g_list_append(info->list, strdup(dentry->d_name));
168 static GList *__append_langs(const char *lang, GList *list, GHashTable *table)
170 struct lang_info_s *info;
172 char *parent_lang = NULL;
178 extract_lang = __get_string_before(lang, ".");
179 if (extract_lang == NULL)
182 found = g_list_find_custom(list, extract_lang, __compare_langs);
184 list = g_list_remove_link(list, found);
185 list = g_list_concat(list, found);
189 parent_lang = __get_string_before(extract_lang, "_");
190 if (parent_lang == NULL)
193 info = g_hash_table_lookup(table, parent_lang);
197 found = g_list_find_custom(info->list, extract_lang, __compare_langs);
199 info->list = g_list_remove_link(info->list, found);
200 list = g_list_concat(list, found);
204 found = g_list_find_custom(info->list, parent_lang, __compare_langs);
206 info->list = g_list_remove_link(info->list, found);
207 list = g_list_concat(list, found);
211 found = g_list_first(info->list);
213 info->list = g_list_remove_link(info->list, found);
214 list = g_list_concat(list, found);
226 static GList *__split_language(const char *lang)
232 dup_lang = strdup(lang);
233 if (dup_lang == NULL) {
234 _ERR("Out of memory");
238 token = strtok(dup_lang, ":");
239 while (token != NULL) {
240 list = g_list_append(list, strdup(token));
241 token = strtok(NULL, ":");
248 static GList *__append_default_langs(GList *list)
250 const char *langs[] = {"en_US", "en_GB", "en"};
254 for (i = 0; i < (sizeof(langs) / sizeof(langs[0])); i++) {
255 found = g_list_find_custom(list, langs[i], __compare_langs);
257 list = g_list_append(list, strdup(langs[i]));
263 static char *__get_language(const char *lang)
267 GList *lang_list = NULL;
270 char buf[LINE_MAX] = {'\0'};
273 list = __split_language(lang);
277 table = __get_lang_table();
279 g_list_free_full(list, free);
283 iter = g_list_first(list);
285 language = (char *)iter->data;
286 lang_list = __append_langs(language, lang_list, table);
287 iter = g_list_next(iter);
289 g_list_free_full(list, free);
290 g_hash_table_destroy(table);
292 lang_list = __append_default_langs(lang_list);
293 iter = g_list_first(lang_list);
295 language = (char *)iter->data;
297 if (buf[0] == '\0') {
298 snprintf(buf, sizeof(buf), "%s", language);
300 n = sizeof(buf) - strlen(buf) - 1;
301 strncat(buf, ":", n);
302 n = sizeof(buf) - strlen(buf) - 1;
303 strncat(buf, language, n);
306 iter = g_list_next(iter);
308 g_list_free_full(lang_list, free);
313 void update_lang(void)
319 lang = vconf_get_str(VCONFKEY_LANGSET);
321 /* TODO: Use VCONFKEY_SETAPPL_LANGUAGES key */
322 language = __get_language(lang);
324 _DBG("*****language(%s)", language);
325 setenv("LANGUAGE", language, 1);
328 setenv("LANGUAGE", lang, 1);
330 setenv("LANG", lang, 1);
331 setenv("LC_MESSAGES", lang, 1);
332 r = setlocale(LC_ALL, "");
334 r = setlocale(LC_ALL, lang);
336 _DBG("*****appcore setlocale=%s\n", r);
342 void update_region(void)
347 region = vconf_get_str(VCONFKEY_REGIONFORMAT);
349 setenv("LC_CTYPE", region, 1);
350 setenv("LC_NUMERIC", region, 1);
351 setenv("LC_TIME", region, 1);
352 setenv("LC_COLLATE", region, 1);
353 setenv("LC_MONETARY", region, 1);
354 setenv("LC_PAPER", region, 1);
355 setenv("LC_NAME", region, 1);
356 setenv("LC_ADDRESS", region, 1);
357 setenv("LC_TELEPHONE", region, 1);
358 setenv("LC_MEASUREMENT", region, 1);
359 setenv("LC_IDENTIFICATION", region, 1);
360 r = setlocale(LC_ALL, "");
362 _DBG("*****appcore setlocale=%s\n", r);
368 static int __set_i18n(const char *domain, const char *dir)
373 if (domain == NULL) {
378 r = setlocale(LC_ALL, "");
379 /* if locale is not set properly, try again to set as language base */
381 lan = vconf_get_str(VCONFKEY_LANGSET);
383 r = setlocale(LC_ALL, lan);
384 _DBG("*****appcore setlocale=%s\n", r);
389 _ERR("appcore: setlocale() error");
391 r = bindtextdomain(domain, dir);
393 _ERR("appcore: bindtextdomain() error");
395 r = textdomain(domain);
397 _ERR("appcore: textdomain() error");
402 static void __set_locale_dir(const char *dirname)
407 snprintf(locale_dir, sizeof(locale_dir), "%s", dirname);
410 EXPORT_API int appcore_set_i18n(const char *domainname, const char *dirname)
414 __set_locale_dir(dirname);
418 r = __set_i18n(domainname, dirname);
425 int set_i18n(const char *domainname, const char *dirname)
429 __set_locale_dir(dirname);
433 return __set_i18n(domainname, dirname);
436 EXPORT_API int appcore_get_timeformat(enum appcore_time_format *timeformat)
440 if (timeformat == NULL) {
445 r = vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, (int *)timeformat);
448 *timeformat = APPCORE_TIME_FORMAT_UNKNOWN;