2 * Copyright (C) 2010 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 3 of the License, or (at your option) any
8 * later version. See http://www.gnu.org/copyleft/lgpl.html the full text of the
16 #include "lightdm/language.h"
30 } LightDMLanguagePrivate;
32 G_DEFINE_TYPE (LightDMLanguage, lightdm_language, G_TYPE_OBJECT);
34 #define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_LANGUAGE, LightDMLanguagePrivate)
36 static gboolean have_languages = FALSE;
37 static GList *languages = NULL;
40 update_languages (void)
42 gchar *stdout_text = NULL, *stderr_text = NULL;
50 result = g_spawn_command_line_sync ("locale -a", &stdout_text, &stderr_text, &exit_status, &error);
53 g_warning ("Failed to run 'locale -a': %s", error->message);
54 g_clear_error (&error);
56 else if (exit_status != 0)
57 g_warning ("Failed to get languages, locale -a returned %d", exit_status);
63 tokens = g_strsplit_set (stdout_text, "\n\r", -1);
64 for (i = 0; tokens[i]; i++)
66 LightDMLanguage *language;
69 code = g_strchug (tokens[i]);
73 /* Ignore the non-interesting languages */
74 if (strcmp (code, "C") == 0 || strcmp (code, "POSIX") == 0)
77 language = g_object_new (LIGHTDM_TYPE_LANGUAGE, "code", code, NULL);
78 languages = g_list_append (languages, language);
87 have_languages = TRUE;
91 * lightdm_get_language:
93 * Get the current language.
95 * Return value: (transfer none): The current language or #NULL if no language.
97 const LightDMLanguage *
98 lightdm_get_language (void)
103 lang = g_getenv ("LANG");
104 for (link = lightdm_get_languages (); link; link = link->next)
106 LightDMLanguage *language = link->data;
107 if (lightdm_language_matches (language, lang))
115 * lightdm_get_languages:
117 * Get a list of languages to present to the user.
119 * Return value: (element-type LightDMLanguage) (transfer none): A list of #LightDMLanguage that should be presented to the user.
122 lightdm_get_languages (void)
129 * lightdm_language_get_code:
130 * @language: A #LightDMLanguage
132 * Get the code of a language.
134 * Return value: The code of the language
137 lightdm_language_get_code (LightDMLanguage *language)
139 g_return_val_if_fail (LIGHTDM_IS_LANGUAGE (language), NULL);
140 return GET_PRIVATE (language)->code;
144 * lightdm_language_get_name:
145 * @language: A #LightDMLanguage
147 * Get the name of a language.
149 * Return value: The name of the language
152 lightdm_language_get_name (LightDMLanguage *language)
154 LightDMLanguagePrivate *priv;
156 g_return_val_if_fail (LIGHTDM_IS_LANGUAGE (language), NULL);
158 priv = GET_PRIVATE (language);
162 char *current = setlocale(LC_ALL, NULL);
163 setlocale(LC_ALL, priv->code);
164 #ifdef _NL_IDENTIFICATION_LANGUAGE
165 priv->name = g_strdup (nl_langinfo (_NL_IDENTIFICATION_LANGUAGE));
167 priv->name = g_strdup ("Unknown");
169 setlocale(LC_ALL, current);
176 * lightdm_language_get_territory:
177 * @language: A #LightDMLanguage
179 * Get the territory the language is used in.
181 * Return value: The territory the language is used in.
184 lightdm_language_get_territory (LightDMLanguage *language)
186 LightDMLanguagePrivate *priv;
188 g_return_val_if_fail (LIGHTDM_IS_LANGUAGE (language), NULL);
190 priv = GET_PRIVATE (language);
192 if (!priv->territory)
194 char *current = setlocale(LC_ALL, NULL);
195 setlocale(LC_ALL, priv->code);
196 #ifdef _NL_IDENTIFICATION_TERRITORY
197 priv->territory = g_strdup (nl_langinfo (_NL_IDENTIFICATION_TERRITORY));
199 priv->territory = g_strdup ("Unknown");
201 setlocale(LC_ALL, current);
204 return priv->territory;
208 is_utf8 (const gchar *code)
210 return g_str_has_suffix (code, ".utf8") || g_str_has_suffix (code, ".UTF-8");
214 * lightdm_language_matches:
215 * @language: A #LightDMLanguage
216 * @code: A language code
218 * Check if a language code matches this language.
220 * Return value: #TRUE if the code matches this language.
223 lightdm_language_matches (LightDMLanguage *language, const gchar *code)
225 LightDMLanguagePrivate *priv;
227 g_return_val_if_fail (LIGHTDM_IS_LANGUAGE (language), FALSE);
228 g_return_val_if_fail (code != NULL, FALSE);
230 priv = GET_PRIVATE (language);
232 /* Handle the fact the UTF-8 is specified both as '.utf8' and '.UTF-8' */
233 if (is_utf8 (priv->code) && is_utf8 (code))
235 /* Match the characters before the '.' */
237 for (i = 0; priv->code[i] && code[i] && priv->code[i] == code[i] && code[i] != '.' ; i++);
238 return priv->code[i] == '.' && code[i] == '.';
241 return g_str_equal (priv->code, code);
245 lightdm_language_init (LightDMLanguage *language)
250 lightdm_language_set_property (GObject *object,
255 LightDMLanguage *self = LIGHTDM_LANGUAGE (object);
256 LightDMLanguagePrivate *priv = GET_PRIVATE (self);
261 priv->code = g_strdup (g_value_get_string (value));
264 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
270 lightdm_language_get_property (GObject *object,
275 LightDMLanguage *self;
277 self = LIGHTDM_LANGUAGE (object);
281 g_value_set_string (value, lightdm_language_get_code (self));
284 g_value_set_string (value, lightdm_language_get_name (self));
287 g_value_set_string (value, lightdm_language_get_territory (self));
290 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
296 lightdm_language_class_init (LightDMLanguageClass *klass)
298 GObjectClass *object_class = G_OBJECT_CLASS (klass);
300 g_type_class_add_private (klass, sizeof (LightDMLanguagePrivate));
302 object_class->set_property = lightdm_language_set_property;
303 object_class->get_property = lightdm_language_get_property;
305 g_object_class_install_property (object_class,
307 g_param_spec_string ("code",
311 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
312 g_object_class_install_property (object_class,
314 g_param_spec_string ("name",
316 "Name of the language",
319 g_object_class_install_property (object_class,
321 g_param_spec_string ("territory",
323 "Territory the language is from",