From 60e7ea2cbc3fb203b8ed4485880cc31b5b195ff6 Mon Sep 17 00:00:00 2001 From: Robert Ancell Date: Tue, 20 Sep 2011 11:49:16 +1000 Subject: [PATCH] Add language selector into GTK greeter (disabled by default) --- NEWS | 1 + greeters/gtk/greeter.ui | 63 +++++++------------ greeters/gtk/lightdm-gtk-greeter.c | 88 ++++++++++++++++++++++++++- greeters/gtk/lightdm-gtk-greeter.conf | 1 + liblightdm-gobject/greeter.c | 2 +- liblightdm-gobject/language.c | 20 ++++-- liblightdm-gobject/lightdm/language.h | 2 +- liblightdm-qt/greeter.cpp | 2 +- src/greeter.c | 1 + 9 files changed, 130 insertions(+), 50 deletions(-) diff --git a/NEWS b/NEWS index fc38b47d..22386a95 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ Overview of changes in lightdm 0.9.8 support various display types * Add ability to set the language of a user from the greeter * Set LANG variable based on the user language + * Add language selector into GTK greeter (disabled by default) Overview of changes in lightdm 0.9.7 diff --git a/greeters/gtk/greeter.ui b/greeters/gtk/greeter.ui index 14697f49..0694418e 100644 --- a/greeters/gtk/greeter.ui +++ b/greeters/gtk/greeter.ui @@ -1,6 +1,14 @@ + + + + + + + + False False @@ -132,6 +140,17 @@ 0 + + + False + language_liststore + + + True + True + 1 + + Login @@ -145,7 +164,7 @@ False True end - 1 + 2 @@ -161,7 +180,7 @@ False True end - 2 + 3 @@ -200,26 +219,6 @@ True False False - - - True - False - 3 - - - True - False - 24 - system-shutdown - - - False - True - 0 - - - - True @@ -269,26 +268,6 @@ True False False - - - True - False - 3 - - - True - False - 24 - accessibility - - - False - True - 0 - - - - True diff --git a/greeters/gtk/lightdm-gtk-greeter.c b/greeters/gtk/lightdm-gtk-greeter.c index ed9cb4d5..13c44ee6 100644 --- a/greeters/gtk/lightdm-gtk-greeter.c +++ b/greeters/gtk/lightdm-gtk-greeter.c @@ -25,6 +25,7 @@ static GtkTreeView *user_view; static GtkWidget *login_box, *prompt_box; static GtkEntry *prompt_entry; static GtkComboBox *session_combo; +static GtkComboBox *language_combo; static gchar *default_font_name, *default_theme_name; static gboolean cancelling = FALSE, prompted = FALSE; @@ -72,6 +73,51 @@ set_session (const gchar *session) set_session (lightdm_greeter_get_default_session_hint (greeter)); } +static gchar * +get_language () +{ + GtkTreeIter iter; + gchar *language; + + if (!gtk_combo_box_get_active_iter (language_combo, &iter)) + return NULL; + + gtk_tree_model_get (gtk_combo_box_get_model (language_combo), &iter, 1, &language, -1); + + return language; +} + +static void +set_language (const gchar *language) +{ + GtkTreeModel *model = gtk_combo_box_get_model (language_combo); + GtkTreeIter iter; + const gchar *default_language = NULL; + + if (language && gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + gchar *s; + gboolean matched; + gtk_tree_model_get (model, &iter, 1, &s, -1); + matched = strcmp (s, language) == 0; + g_free (s); + if (matched) + { + gtk_combo_box_set_active_iter (language_combo, &iter); + return; + } + } while (gtk_tree_model_iter_next (model, &iter)); + } + + /* If failed to find this language, then try the default */ + if (lightdm_get_language ()) + default_language = lightdm_language_get_code (lightdm_get_language ()); + if (default_language && g_strcmp0 (default_language, language) != 0) + set_language (default_language); +} + static void set_message_label (const gchar *text) { @@ -99,9 +145,15 @@ start_authentication (const gchar *username) user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username); if (user) + { set_session (lightdm_user_get_session (user)); + set_language (lightdm_user_get_language (user)); + } else + { set_session (NULL); + set_language (NULL); + } lightdm_greeter_authenticate (greeter, username); } @@ -132,8 +184,14 @@ cancel_authentication (void) static void start_session (void) { + gchar *language; gchar *session; + language = get_language (); + if (language) + lightdm_greeter_set_language (greeter, language); + g_free (language); + session = get_session (); if (!lightdm_greeter_start_session_sync (greeter, session, NULL)) { @@ -584,7 +642,7 @@ create_root_surface (GdkScreen *screen) } int -main(int argc, char **argv) +main (int argc, char **argv) { GKeyFile *config; GdkRectangle monitor_geometry; @@ -738,6 +796,7 @@ main(int argc, char **argv) prompt_entry = GTK_ENTRY (gtk_builder_get_object (builder, "prompt_entry")); message_label = GTK_LABEL (gtk_builder_get_object (builder, "message_label")); session_combo = GTK_COMBO_BOX (gtk_builder_get_object (builder, "session_combobox")); + language_combo = GTK_COMBO_BOX (gtk_builder_get_object (builder, "language_combobox")); panel_window = GTK_WINDOW (gtk_builder_get_object (builder, "panel_window")); gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "hostname_label")), lightdm_get_hostname ()); @@ -781,6 +840,33 @@ main(int argc, char **argv) } set_session (NULL); + if (g_key_file_get_boolean (config, "greeter", "show-language-selector", NULL)) + { + gtk_widget_show (GTK_WIDGET (language_combo)); + + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (language_combo), renderer, TRUE); + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (language_combo), renderer, "text", 0); + model = gtk_combo_box_get_model (language_combo); + items = lightdm_get_languages (); + for (item = items; item; item = item->next) + { + LightDMLanguage *language = item->data; + gchar *label; + + label = g_strdup_printf ("%s - %s", lightdm_language_get_name (language), lightdm_language_get_territory (language)); + + gtk_widget_show (GTK_WIDGET (language_combo)); + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + 0, label, + 1, lightdm_language_get_code (language), + -1); + g_free (label); + } + set_language (NULL); + } + gtk_builder_connect_signals(builder, greeter); gtk_widget_show (GTK_WIDGET (login_window)); diff --git a/greeters/gtk/lightdm-gtk-greeter.conf b/greeters/gtk/lightdm-gtk-greeter.conf index 12f32ce0..0e549350 100644 --- a/greeters/gtk/lightdm-gtk-greeter.conf +++ b/greeters/gtk/lightdm-gtk-greeter.conf @@ -9,6 +9,7 @@ # [greeter] #background= +#show-language-selector=false #theme-name= #font-name= #xft-antialias= diff --git a/liblightdm-gobject/greeter.c b/liblightdm-gobject/greeter.c index d0819c8c..a0ee966e 100644 --- a/liblightdm-gobject/greeter.c +++ b/liblightdm-gobject/greeter.c @@ -876,7 +876,7 @@ lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language) g_return_if_fail (priv->connected); - write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, 0, &offset); + write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset); write_string (message, MAX_MESSAGE_LENGTH, language, &offset); write_message (greeter, message, offset); } diff --git a/liblightdm-gobject/language.c b/liblightdm-gobject/language.c index 5c4f7d57..edcf9974 100644 --- a/liblightdm-gobject/language.c +++ b/liblightdm-gobject/language.c @@ -71,7 +71,7 @@ update_languages (void) continue; /* Ignore the non-interesting languages */ - if (strcmp (code, "C") == 0 || strcmp (code, "POSIX") == 0) + if (strcmp (code, "C") == 0 || g_str_has_prefix (code, "C.") || strcmp (code, "POSIX") == 0) continue; language = g_object_new (LIGHTDM_TYPE_LANGUAGE, "code", code, NULL); @@ -94,13 +94,16 @@ update_languages (void) * * Return value: (transfer none): The current language or #NULL if no language. **/ -const LightDMLanguage * +LightDMLanguage * lightdm_get_language (void) { const gchar *lang; GList *link; lang = g_getenv ("LANG"); + if (!lang) + return NULL; + for (link = lightdm_get_languages (); link; link = link->next) { LightDMLanguage *language = link->data; @@ -164,7 +167,9 @@ lightdm_language_get_name (LightDMLanguage *language) #ifdef _NL_IDENTIFICATION_LANGUAGE priv->name = g_strdup (nl_langinfo (_NL_IDENTIFICATION_LANGUAGE)); #else - priv->name = g_strdup ("Unknown"); + priv->name = g_strdup (priv->code); + if (strchr (priv->name, '_')) + *strchr (priv->name, '_') = '\0'; #endif setlocale(LC_ALL, current); } @@ -196,7 +201,14 @@ lightdm_language_get_territory (LightDMLanguage *language) #ifdef _NL_IDENTIFICATION_TERRITORY priv->territory = g_strdup (nl_langinfo (_NL_IDENTIFICATION_TERRITORY)); #else - priv->territory = g_strdup ("Unknown"); + if (strchr (priv->code, '_')) + { + priv->territory = g_strdup (strchr (priv->code, '_') + 1); + if (strchr (priv->territory, '.')) + *strchr (priv->territory, '.') = '\0'; + } + else + priv->territory = g_strdup (""); #endif setlocale(LC_ALL, current); } diff --git a/liblightdm-gobject/lightdm/language.h b/liblightdm-gobject/lightdm/language.h index 154a3382..b7370ab6 100644 --- a/liblightdm-gobject/lightdm/language.h +++ b/liblightdm-gobject/lightdm/language.h @@ -45,7 +45,7 @@ GType lightdm_language_get_type (void); GList *lightdm_get_languages (void); -const LightDMLanguage *lightdm_get_language (void); +LightDMLanguage *lightdm_get_language (void); const gchar *lightdm_language_get_code (LightDMLanguage *language); diff --git a/liblightdm-qt/greeter.cpp b/liblightdm-qt/greeter.cpp index e5925763..bc8ec28a 100644 --- a/liblightdm-qt/greeter.cpp +++ b/liblightdm-qt/greeter.cpp @@ -287,7 +287,7 @@ QString Greeter::authenticationUser() const void Greeter::setLanguage (QString language) { - writeHeader(GREETER_MESSAGE_SET_LANGUAGE, 0); + writeHeader(GREETER_MESSAGE_SET_LANGUAGE, stringLength(language)); writeString (language); flush(); } diff --git a/src/greeter.c b/src/greeter.c index a1e28712..b5e3d787 100644 --- a/src/greeter.c +++ b/src/greeter.c @@ -427,6 +427,7 @@ handle_set_language (Greeter *greeter, const gchar *language) return; } + g_debug ("Greeter sets language %s", language); user = pam_session_get_user (greeter->priv->authentication); user_set_language (user, language); } -- 2.39.2