summaryrefslogtreecommitdiff
path: root/gui/simple-greeter/gdm-languages.c
diff options
context:
space:
mode:
Diffstat (limited to 'gui/simple-greeter/gdm-languages.c')
-rw-r--r--gui/simple-greeter/gdm-languages.c1159
1 files changed, 0 insertions, 1159 deletions
diff --git a/gui/simple-greeter/gdm-languages.c b/gui/simple-greeter/gdm-languages.c
deleted file mode 100644
index fa2f0407..00000000
--- a/gui/simple-greeter/gdm-languages.c
+++ /dev/null
@@ -1,1159 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright 2008 Red Hat, Inc,
- * 2007 William Jon McCann <mccann@jhu.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Written by : William Jon McCann <mccann@jhu.edu>
- * Ray Strode <rstrode@redhat.com>
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <dirent.h>
-#include <locale.h>
-#include <langinfo.h>
-#include <sys/stat.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <glib/gstdio.h>
-
-#include "gdm-languages.h"
-
-#include <langinfo.h>
-#ifndef __LC_LAST
-#define __LC_LAST 13
-#endif
-#include "locarchive.h"
-
-#define ALIASES_FILE DATADIR "/gdm/locale.alias"
-#define ARCHIVE_FILE LIBLOCALEDIR "/locale-archive"
-#define SYSTEM_ARCHIVE_FILE "/usr/lib/locale/locale-archive"
-#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
-#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
-
-typedef struct _GdmLocale {
- char *id;
- char *name;
- char *language_code;
- char *territory_code;
- char *codeset;
- char *modifier;
-} GdmLocale;
-
-static GHashTable *gdm_languages_map;
-static GHashTable *gdm_territories_map;
-static GHashTable *gdm_available_locales_map;
-
-static char * construct_language_name (const char *language,
- const char *territory,
- const char *codeset,
- const char *modifier);
-
-static gboolean language_name_is_valid (const char *language_name);
-
-static void
-gdm_locale_free (GdmLocale *locale)
-{
- if (locale == NULL) {
- return;
- }
-
- g_free (locale->id);
- g_free (locale->name);
- g_free (locale->codeset);
- g_free (locale->modifier);
- g_free (locale);
-}
-
-static char *
-normalize_codeset (const char *codeset)
-{
- char *normalized_codeset;
- const char *p;
- char *q;
-
- normalized_codeset = g_strdup (codeset);
-
- if (codeset != NULL) {
- for (p = codeset, q = normalized_codeset;
- *p != '\0'; p++) {
-
- if (*p == '-' || *p == '_') {
- continue;
- }
-
- *q = g_ascii_tolower (*p);
- q++;
- }
- *q = '\0';
- }
-
- return normalized_codeset;
-}
-
-/*
- * According to http://en.wikipedia.org/wiki/Locale
- * locale names are of the form:
- * [language[_territory][.codeset][@modifier]]
- */
-gboolean
-gdm_parse_language_name (const char *name,
- char **language_codep,
- char **territory_codep,
- char **codesetp,
- char **modifierp)
-{
- GRegex *re;
- GMatchInfo *match_info;
- gboolean res;
- GError *error;
- gchar *normalized_codeset = NULL;
- gchar *normalized_name = NULL;
- gboolean retval;
-
- match_info = NULL;
- retval = FALSE;
-
- error = NULL;
- re = g_regex_new ("^(?P<language>[^_.@[:space:]]+)"
- "(_(?P<territory>[[:upper:]]+))?"
- "(\\.(?P<codeset>[-_0-9a-zA-Z]+))?"
- "(@(?P<modifier>[[:ascii:]]+))?$",
- 0, 0, &error);
- if (re == NULL) {
- g_warning ("%s", error->message);
- goto out;
- }
-
- if (!g_regex_match (re, name, 0, &match_info) ||
- g_match_info_is_partial_match (match_info)) {
- g_warning ("locale %s isn't valid\n", name);
- goto out;
- }
-
- res = g_match_info_matches (match_info);
- if (! res) {
- g_warning ("Unable to parse locale: %s", name);
- goto out;
- }
-
- retval = TRUE;
-
- if (language_codep != NULL) {
- *language_codep = g_match_info_fetch_named (match_info, "language");
- }
-
- if (territory_codep != NULL) {
- *territory_codep = g_match_info_fetch_named (match_info, "territory");
-
- if (*territory_codep != NULL &&
- *territory_codep[0] == '\0') {
- g_free (*territory_codep);
- *territory_codep = NULL;
- }
- }
-
- if (codesetp != NULL) {
- *codesetp = g_match_info_fetch_named (match_info, "codeset");
-
- if (*codesetp != NULL &&
- *codesetp[0] == '\0') {
- g_free (*codesetp);
- *codesetp = NULL;
- }
- }
-
- if (modifierp != NULL) {
- *modifierp = g_match_info_fetch_named (match_info, "modifier");
-
- if (*modifierp != NULL &&
- *modifierp[0] == '\0') {
- g_free (*modifierp);
- *modifierp = NULL;
- }
- }
-
- if (codesetp != NULL && *codesetp != NULL) {
- normalized_codeset = normalize_codeset (*codesetp);
- normalized_name = construct_language_name (language_codep ? *language_codep : NULL,
- territory_codep ? *territory_codep : NULL,
- normalized_codeset,
- modifierp ? *modifierp : NULL);
-
- if (language_name_is_valid (normalized_name)) {
- g_free (*codesetp);
- *codesetp = normalized_codeset;
- } else {
- g_free (normalized_codeset);
- }
- g_free (normalized_name);
- }
-
- out:
- g_match_info_free (match_info);
- g_regex_unref (re);
-
- return retval;
-}
-
-static char *
-construct_language_name (const char *language,
- const char *territory,
- const char *codeset,
- const char *modifier)
-{
- char *name;
-
- g_assert (language[0] != 0);
- g_assert (territory == NULL || territory[0] != 0);
- g_assert (codeset == NULL || codeset[0] != 0);
- g_assert (modifier == NULL || modifier[0] != 0);
-
- name = g_strdup_printf ("%s%s%s%s%s%s%s",
- language,
- territory != NULL? "_" : "",
- territory != NULL? territory : "",
- codeset != NULL? "." : "",
- codeset != NULL? codeset : "",
- modifier != NULL? "@" : "",
- modifier != NULL? modifier : "");
-
- return name;
-}
-
-char *
-gdm_normalize_language_name (const char *name)
-{
- char *normalized_name;
- char *language_code;
- char *territory_code;
- char *codeset;
- char *modifier;
-
- if (name[0] == '\0') {
- return NULL;
- }
-
- gdm_parse_language_name (name,
- &language_code,
- &territory_code,
- &codeset, &modifier);
-
- normalized_name = construct_language_name (language_code,
- territory_code,
- codeset, modifier);
- g_free (language_code);
- g_free (territory_code);
- g_free (codeset);
- g_free (modifier);
-
- return normalized_name;
-}
-
-static gboolean
-language_name_is_valid (const char *language_name)
-{
- char *old_locale;
- gboolean is_valid;
-#ifdef WITH_INCOMPLETE_LOCALES
- int lc_type_id = LC_CTYPE;
-#else
- int lc_type_id = LC_MESSAGES;
-#endif
-
- old_locale = g_strdup (setlocale (lc_type_id, NULL));
- is_valid = setlocale (lc_type_id, language_name) != NULL;
- setlocale (lc_type_id, old_locale);
- g_free (old_locale);
-
- return is_valid;
-}
-
-static void
-language_name_get_codeset_details (const char *language_name,
- char **pcodeset,
- gboolean *is_utf8)
-{
- char *old_locale;
- char *codeset;
-
- old_locale = g_strdup (setlocale (LC_CTYPE, NULL));
-
- if (setlocale (LC_CTYPE, language_name) == NULL) {
- g_free (old_locale);
- return;
- }
-
- codeset = nl_langinfo (CODESET);
-
- if (pcodeset != NULL) {
- *pcodeset = g_strdup (codeset);
- }
-
- if (is_utf8 != NULL) {
- codeset = normalize_codeset (codeset);
-
- *is_utf8 = strcmp (codeset, "utf8") == 0;
- g_free (codeset);
- }
-
- setlocale (LC_CTYPE, old_locale);
- g_free (old_locale);
-}
-
-static gboolean
-language_name_has_translations (const char *language_name)
-{
- GDir *dir;
- char *path;
- const char *name;
- gboolean has_translations;
-
- path = g_build_filename (GNOMELOCALEDIR, language_name, "LC_MESSAGES", NULL);
-
- has_translations = FALSE;
- dir = g_dir_open (path, 0, NULL);
- g_free (path);
-
- if (dir == NULL) {
- goto out;
- }
-
- do {
- name = g_dir_read_name (dir);
-
- if (name == NULL) {
- break;
- }
-
- if (g_str_has_suffix (name, ".mo")) {
- has_translations = TRUE;
- break;
- }
- } while (name != NULL);
- g_dir_close (dir);
-
-out:
- return has_translations;
-}
-
-static gboolean
-add_locale (const char *language_name,
- gboolean utf8_only)
-{
- GdmLocale *locale;
- GdmLocale *old_locale;
- char *name;
- gboolean is_utf8;
-
- g_return_val_if_fail (language_name != NULL, FALSE);
-
- language_name_get_codeset_details (language_name, NULL, &is_utf8);
-
- if (is_utf8) {
- name = g_strdup (language_name);
- } else if (utf8_only) {
- name = g_strdup_printf ("%s.utf8", language_name);
-
- language_name_get_codeset_details (name, NULL, &is_utf8);
- if (!is_utf8) {
- g_free (name);
- return FALSE;
- }
- } else {
- name = g_strdup (language_name);
- }
-
- if (!language_name_is_valid (name)) {
- g_debug ("Ignoring '%s' as a locale, since it's invalid", name);
- g_free (name);
- return FALSE;
- }
-
- locale = g_new0 (GdmLocale, 1);
- gdm_parse_language_name (name,
- &locale->language_code,
- &locale->territory_code,
- &locale->codeset,
- &locale->modifier);
- g_free (name);
- name = NULL;
-
-#ifdef WITH_INCOMPLETE_LOCALES
- if (utf8_only) {
- if (locale->territory_code == NULL || locale->modifier) {
- gdm_locale_free (locale);
- return FALSE;
- }
- }
-#endif
-
- locale->id = construct_language_name (locale->language_code, locale->territory_code,
- NULL, locale->modifier);
- locale->name = construct_language_name (locale->language_code, locale->territory_code,
- locale->codeset, locale->modifier);
-
-#ifndef WITH_INCOMPLETE_LOCALES
- if (!language_name_has_translations (locale->name) &&
- !language_name_has_translations (locale->id) &&
- !language_name_has_translations (locale->language_code) &&
- utf8_only) {
- g_debug ("Ignoring '%s' as a locale, since it lacks translations", locale->name);
- gdm_locale_free (locale);
- return FALSE;
- }
-#endif
-
- if (!utf8_only) {
- g_free (locale->id);
- locale->id = g_strdup (locale->name);
- }
-
- old_locale = g_hash_table_lookup (gdm_available_locales_map, locale->id);
- if (old_locale != NULL) {
- if (strlen (old_locale->name) > strlen (locale->name)) {
- gdm_locale_free (locale);
- return FALSE;
- }
- }
-
- g_hash_table_insert (gdm_available_locales_map, g_strdup (locale->id), locale);
-
- return TRUE;
-}
-
-struct nameent
-{
- char *name;
- uint32_t locrec_offset;
-};
-
-static gboolean
-collect_locales_from_archive (void)
-{
- GMappedFile *mapped;
- GError *error;
- char *addr;
- struct locarhead *head;
- struct namehashent *namehashtab;
- struct nameent *names;
- uint32_t used;
- uint32_t cnt;
- gsize len;
- gboolean locales_collected;
-
- error = NULL;
- mapped = g_mapped_file_new (ARCHIVE_FILE, FALSE, &error);
- if (mapped == NULL) {
- mapped = g_mapped_file_new (SYSTEM_ARCHIVE_FILE, FALSE, NULL);
- if (mapped == NULL) {
- g_warning ("Mapping failed for %s: %s", ARCHIVE_FILE, error->message);
- g_error_free (error);
- return FALSE;
- }
- g_error_free (error);
- }
-
- locales_collected = FALSE;
-
- addr = g_mapped_file_get_contents (mapped);
- len = g_mapped_file_get_length (mapped);
-
- head = (struct locarhead *) addr;
- if (head->namehash_offset + head->namehash_size > len
- || head->string_offset + head->string_size > len
- || head->locrectab_offset + head->locrectab_size > len
- || head->sumhash_offset + head->sumhash_size > len) {
- goto out;
- }
-
- namehashtab = (struct namehashent *) (addr + head->namehash_offset);
-
- names = (struct nameent *) g_new0 (struct nameent, head->namehash_used);
- for (cnt = used = 0; cnt < head->namehash_size; ++cnt) {
- if (namehashtab[cnt].locrec_offset != 0) {
- names[used].name = addr + namehashtab[cnt].name_offset;
- names[used++].locrec_offset = namehashtab[cnt].locrec_offset;
- }
- }
-
- for (cnt = 0; cnt < used; ++cnt) {
- add_locale (names[cnt].name, TRUE);
- }
-
- g_free (names);
-
- locales_collected = TRUE;
- out:
-
- g_mapped_file_unref (mapped);
- return locales_collected;
-}
-
-static int
-select_dirs (const struct dirent *dirent)
-{
- int result = 0;
-
- if (strcmp (dirent->d_name, ".") != 0 && strcmp (dirent->d_name, "..") != 0) {
- mode_t mode = 0;
-
-#ifdef _DIRENT_HAVE_D_TYPE
- if (dirent->d_type != DT_UNKNOWN && dirent->d_type != DT_LNK) {
- mode = DTTOIF (dirent->d_type);
- } else
-#endif
- {
- struct stat st;
- char *path;
-
- path = g_build_filename (LIBLOCALEDIR, dirent->d_name, NULL);
- if (g_stat (path, &st) == 0) {
- mode = st.st_mode;
- }
- g_free (path);
- }
-
- result = S_ISDIR (mode);
- }
-
- return result;
-}
-
-static void
-collect_locales_from_directory (void)
-{
- struct dirent **dirents;
- int ndirents;
- int cnt;
-
- ndirents = scandir (LIBLOCALEDIR, &dirents, select_dirs, alphasort);
-
- for (cnt = 0; cnt < ndirents; ++cnt) {
- add_locale (dirents[cnt]->d_name, TRUE);
- }
-
- if (ndirents > 0) {
- free (dirents);
- }
-}
-
-static void
-collect_locales_from_locale_file (const char *locale_file)
-{
- FILE *langlist;
- char curline[256];
- char *getsret;
-
- if (locale_file == NULL)
- return;
-
- langlist = fopen (locale_file, "r");
-
- if (langlist == NULL)
- return;
-
- for (;;) {
- char *name;
- char *lang;
- char **lang_list;
- int i;
-
- getsret = fgets (curline, sizeof (curline), langlist);
- if (getsret == NULL)
- break;
-
- if (curline[0] <= ' ' ||
- curline[0] == '#')
- continue;
-
- name = strtok (curline, " \t\r\n");
- if (name == NULL)
- continue;
-
- lang = strtok (NULL, " \t\r\n");
- if (lang == NULL)
- continue;
-
- lang_list = g_strsplit (lang, ",", -1);
- if (lang_list == NULL)
- continue;
-
- lang = NULL;
- for (i = 0; lang_list[i] != NULL; i++) {
- if (add_locale (lang_list[i], FALSE)) {
- break;
- }
- }
- g_strfreev (lang_list);
- }
-
- fclose (langlist);
-}
-
-static void
-collect_locales (void)
-{
-
- if (gdm_available_locales_map == NULL) {
- gdm_available_locales_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gdm_locale_free);
- }
-
- if (!collect_locales_from_archive ()) {
-#ifndef WITH_INCOMPLETE_LOCALES
- g_warning ("Could not read list of available locales from libc, "
- "guessing possible locales from available translations, "
- "but list may be incomplete!");
-#endif
-
- collect_locales_from_directory ();
- }
- collect_locales_from_locale_file (ALIASES_FILE);
-}
-
-static gboolean
-is_fallback_language (const char *code)
-{
- const char *fallback_language_names[] = { "C", "POSIX", NULL };
- int i;
-
- for (i = 0; fallback_language_names[i] != NULL; i++) {
- if (strcmp (code, fallback_language_names[i]) == 0) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static const char *
-get_language (const char *code)
-{
- const char *name;
- int len;
-
- g_assert (code != NULL);
-
- if (is_fallback_language (code)) {
- return "Unspecified";
- }
-
- len = strlen (code);
- if (len != 2 && len != 3) {
- return NULL;
- }
-
- name = (const char *) g_hash_table_lookup (gdm_languages_map, code);
-
- return name;
-}
-
-static char *
-get_first_item_in_semicolon_list (const char *list)
-{
- char **items;
- char *item;
-
- /* Some entries in iso codes have multiple values, separated
- * by semicolons. Not really sure which one to pick, so
- * we just arbitrarily pick the first one.
- */
- items = g_strsplit (list, "; ", 2);
-
- item = g_strdup (items[0]);
- g_strfreev (items);
-
- return item;
-}
-
-static char *
-get_translated_language (const char *code,
- const char *locale)
-{
- const char *language;
- char *name;
-
- language = get_language (code);
-
- name = NULL;
- if (language != NULL) {
- const char *translated_name;
- char *old_locale;
-
- if (locale != NULL) {
- old_locale = g_strdup (setlocale (LC_MESSAGES, NULL));
- setlocale (LC_MESSAGES, locale);
- }
-
- if (is_fallback_language (code)) {
- name = g_strdup (_("Unspecified"));
- } else {
- translated_name = dgettext ("iso_639", language);
- name = get_first_item_in_semicolon_list (translated_name);
- }
-
- if (locale != NULL) {
- setlocale (LC_MESSAGES, old_locale);
- g_free (old_locale);
- }
- }
-
- return name;
-}
-
-static const char *
-get_territory (const char *code)
-{
- const char *name;
- int len;
-
- g_assert (code != NULL);
-
- len = strlen (code);
- if (len != 2 && len != 3) {
- return NULL;
- }
-
- name = (const char *) g_hash_table_lookup (gdm_territories_map, code);
-
- return name;
-}
-
-static char *
-get_translated_territory (const char *code,
- const char *locale)
-{
- const char *territory;
- char *name;
-
- territory = get_territory (code);
-
- name = NULL;
- if (territory != NULL) {
- const char *translated_territory;
- char *old_locale;
-
- if (locale != NULL) {
- old_locale = g_strdup (setlocale (LC_MESSAGES, NULL));
- setlocale (LC_MESSAGES, locale);
- }
-
- translated_territory = dgettext ("iso_3166", territory);
- name = get_first_item_in_semicolon_list (translated_territory);
-
- if (locale != NULL) {
- setlocale (LC_MESSAGES, old_locale);
- g_free (old_locale);
- }
- }
-
- return name;
-}
-
-static void
-languages_parse_start_tag (GMarkupParseContext *ctx,
- const char *element_name,
- const char **attr_names,
- const char **attr_values,
- gpointer user_data,
- GError **error)
-{
- const char *ccode_longB;
- const char *ccode_longT;
- const char *ccode;
- const char *ccode_id;
- const char *lang_name;
-
- if (! (g_str_equal (element_name, "iso_639_entry") || g_str_equal (element_name, "iso_639_3_entry"))
- || attr_names == NULL || attr_values == NULL) {
- return;
- }
-
- ccode = NULL;
- ccode_longB = NULL;
- ccode_longT = NULL;
- ccode_id = NULL;
- lang_name = NULL;
-
- while (*attr_names && *attr_values) {
- if (g_str_equal (*attr_names, "iso_639_1_code")) {
- /* skip if empty */
- if (**attr_values) {
- if (strlen (*attr_values) != 2) {
- return;
- }
- ccode = *attr_values;
- }
- } else if (g_str_equal (*attr_names, "iso_639_2B_code")) {
- /* skip if empty */
- if (**attr_values) {
- if (strlen (*attr_values) != 3) {
- return;
- }
- ccode_longB = *attr_values;
- }
- } else if (g_str_equal (*attr_names, "iso_639_2T_code")) {
- /* skip if empty */
- if (**attr_values) {
- if (strlen (*attr_values) != 3) {
- return;
- }
- ccode_longT = *attr_values;
- }
- } else if (g_str_equal (*attr_names, "id")) {
- /* skip if empty */
- if (**attr_values) {
- if (strlen (*attr_values) != 2 &&
- strlen (*attr_values) != 3) {
- return;
- }
- ccode_id = *attr_values;
- }
- } else if (g_str_equal (*attr_names, "name")) {
- lang_name = *attr_values;
- }
-
- ++attr_names;
- ++attr_values;
- }
-
- if (lang_name == NULL) {
- return;
- }
-
- if (ccode != NULL) {
- g_hash_table_insert (gdm_languages_map,
- g_strdup (ccode),
- g_strdup (lang_name));
- }
- if (ccode_longB != NULL) {
- g_hash_table_insert (gdm_languages_map,
- g_strdup (ccode_longB),
- g_strdup (lang_name));
- }
- if (ccode_longT != NULL) {
- g_hash_table_insert (gdm_languages_map,
- g_strdup (ccode_longT),
- g_strdup (lang_name));
- }
- if (ccode_id != NULL) {
- g_hash_table_insert (gdm_languages_map,
- g_strdup (ccode_id),
- g_strdup (lang_name));
- }
-}
-
-static void
-territories_parse_start_tag (GMarkupParseContext *ctx,
- const char *element_name,
- const char **attr_names,
- const char **attr_values,
- gpointer user_data,
- GError **error)
-{
- const char *acode_2;
- const char *acode_3;
- const char *ncode;
- const char *territory_common_name;
- const char *territory_name;
-
- if (! g_str_equal (element_name, "iso_3166_entry") || attr_names == NULL || attr_values == NULL) {
- return;
- }
-
- acode_2 = NULL;
- acode_3 = NULL;
- ncode = NULL;
- territory_common_name = NULL;
- territory_name = NULL;
-
- while (*attr_names && *attr_values) {
- if (g_str_equal (*attr_names, "alpha_2_code")) {
- /* skip if empty */
- if (**attr_values) {
- if (strlen (*attr_values) != 2) {
- return;
- }
- acode_2 = *attr_values;
- }
- } else if (g_str_equal (*attr_names, "alpha_3_code")) {
- /* skip if empty */
- if (**attr_values) {
- if (strlen (*attr_values) != 3) {
- return;
- }
- acode_3 = *attr_values;
- }
- } else if (g_str_equal (*attr_names, "numeric_code")) {
- /* skip if empty */
- if (**attr_values) {
- if (strlen (*attr_values) != 3) {
- return;
- }
- ncode = *attr_values;
- }
- } else if (g_str_equal (*attr_names, "common_name")) {
- /* skip if empty */
- if (**attr_values) {
- territory_common_name = *attr_values;
- }
- } else if (g_str_equal (*attr_names, "name")) {
- territory_name = *attr_values;
- }
-
- ++attr_names;
- ++attr_values;
- }
-
- if (territory_common_name != NULL) {
- territory_name = territory_common_name;
- }
-
- if (territory_name == NULL) {
- return;
- }
-
- if (acode_2 != NULL) {
- g_hash_table_insert (gdm_territories_map,
- g_strdup (acode_2),
- g_strdup (territory_name));
- }
- if (acode_3 != NULL) {
- g_hash_table_insert (gdm_territories_map,
- g_strdup (acode_3),
- g_strdup (territory_name));
- }
- if (ncode != NULL) {
- g_hash_table_insert (gdm_territories_map,
- g_strdup (ncode),
- g_strdup (territory_name));
- }
-}
-
-static void
-languages_variant_init (const char *variant)
-{
- GError *error;
- gboolean res;
- char *buf;
- gsize buf_len;
- char *filename;
-
- bindtextdomain (variant, ISO_CODES_LOCALESDIR);
- bind_textdomain_codeset (variant, "UTF-8");
-
- error = NULL;
- filename = g_strdup_printf (ISO_CODES_DATADIR "/%s.xml", variant);
- res = g_file_get_contents (filename,
- &buf,
- &buf_len,
- &error);
- if (res) {
- GMarkupParseContext *ctx;
- GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL };
-
- ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
-
- error = NULL;
- res = g_markup_parse_context_parse (ctx, buf, buf_len, &error);
-
- if (! res) {
- g_warning ("Failed to parse '%s': %s\n",
- filename,
- error->message);
- g_error_free (error);
- g_free (filename);
- }
-
- g_markup_parse_context_free (ctx);
- g_free (buf);
- } else {
- g_warning ("Failed to load '%s': %s\n",
- filename,
- error->message);
- g_error_free (error);
- }
-}
-
-static void
-languages_init (void)
-{
- gdm_languages_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
- languages_variant_init ("iso_639");
- languages_variant_init ("iso_639_3");
-}
-
-static void
-territories_init (void)
-{
- GError *error;
- gboolean res;
- char *buf;
- gsize buf_len;
-
- bindtextdomain ("iso_3166", ISO_CODES_LOCALESDIR);
- bind_textdomain_codeset ("iso_3166", "UTF-8");
-
- gdm_territories_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
- error = NULL;
- res = g_file_get_contents (ISO_CODES_DATADIR "/iso_3166.xml",
- &buf,
- &buf_len,
- &error);
- if (res) {
- GMarkupParseContext *ctx;
- GMarkupParser parser = { territories_parse_start_tag, NULL, NULL, NULL, NULL };
-
- ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
-
- error = NULL;
- res = g_markup_parse_context_parse (ctx, buf, buf_len, &error);
-
- if (! res) {
- g_warning ("Failed to parse '%s': %s\n",
- ISO_CODES_DATADIR "/iso_3166.xml",
- error->message);
- g_error_free (error);
- }
-
- g_markup_parse_context_free (ctx);
- g_free (buf);
- } else {
- g_warning ("Failed to load '%s': %s\n",
- ISO_CODES_DATADIR "/iso_3166.xml",
- error->message);
- g_error_free (error);
- }
-}
-
-char *
-gdm_get_language_from_name (const char *name,
- const char *locale)
-{
- GString *full_language;
- char *language_code;
- char *territory_code;
- char *codeset_code;
- char *langinfo_codeset;
- char *translated_language;
- char *translated_territory;
- gboolean is_utf8 = TRUE;
-
- translated_territory = NULL;
- translated_language = NULL;
- langinfo_codeset = NULL;
-
- full_language = g_string_new (NULL);
-
- if (gdm_languages_map == NULL) {
- languages_init ();
- }
-
- if (gdm_territories_map == NULL) {
- territories_init ();
- }
-
- language_code = NULL;
- territory_code = NULL;
- codeset_code = NULL;
-
- gdm_parse_language_name (name,
- &language_code,
- &territory_code,
- &codeset_code,
- NULL);
-
- if (language_code == NULL) {
- goto out;
- }
-
- translated_language = get_translated_language (language_code, locale);
- if (translated_language == NULL) {
- goto out;
- }
-
- full_language = g_string_append (full_language, translated_language);
-
- if (territory_code != NULL) {
- translated_territory = get_translated_territory (territory_code, locale);
- }
- if (translated_territory != NULL) {
- g_string_append_printf (full_language,
- " (%s)",
- translated_territory);
- }
-
- language_name_get_codeset_details (name, &langinfo_codeset, &is_utf8);
-
- if (codeset_code == NULL && langinfo_codeset != NULL) {
- codeset_code = g_strdup (langinfo_codeset);
- }
-
- if (!is_utf8 && codeset_code) {
- g_string_append_printf (full_language,
- " [%s]",
- codeset_code);
- }
-
-out:
- g_free (language_code);
- g_free (territory_code);
- g_free (codeset_code);
- g_free (langinfo_codeset);
- g_free (translated_language);
- g_free (translated_territory);
-
- if (full_language->len == 0) {
- g_string_free (full_language, TRUE);
- return NULL;
- }
-
- return g_string_free (full_language, FALSE);
-}
-
-char **
-gdm_get_all_language_names (void)
-{
- GHashTableIter iter;
- gpointer key, value;
- GPtrArray *array;
-
- if (gdm_available_locales_map == NULL) {
- collect_locales ();
- }
-
- array = g_ptr_array_new ();
- g_hash_table_iter_init (&iter, gdm_available_locales_map);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- GdmLocale *locale;
-
- locale = (GdmLocale *) value;
-
- g_ptr_array_add (array, g_strdup (locale->name));
- }
- g_ptr_array_add (array, NULL);
-
- return (char **) g_ptr_array_free (array, FALSE);
-}