diff -Nura gnome-initial-setup-3.34.1/gnome-initial-setup/gis-driver.c gnome-initial-setup-3.34.1_new/gnome-initial-setup/gis-driver.c --- gnome-initial-setup-3.34.1/gnome-initial-setup/gis-driver.c 2019-10-06 05:03:38.000000000 +0800 +++ gnome-initial-setup-3.34.1_new/gnome-initial-setup/gis-driver.c 2019-11-26 16:05:58.390308663 +0800 @@ -30,6 +30,7 @@ #include "cc-common-language.h" #include "gis-assistant.h" +#include "language-setting.h" #define GIS_TYPE_DRIVER_MODE (gis_driver_mode_get_type ()) @@ -92,6 +93,32 @@ G_DEFINE_TYPE_WITH_PRIVATE(GisDriver, gis_driver, GTK_TYPE_APPLICATION) +gboolean gis_cjk_region; + +static gboolean +current_locale_in_Asia() +{ + gchar * + current_language = cc_common_language_get_current_language (); + + static gchar *expose_locale_list[] = {"zh_CN.UTF-8", + "zh_HK.UTF-8", + "zh_MO.UTF-8", + "zh_TW.UTF-8", + "zh_SG.UTF-8", + "ja_JP.UTF-8", + "ko_KR.UTF-8"}; + guint i = 0; + while (expose_locale_list[i]) + { + if (g_strcmp0 (expose_locale_list[i], current_language) == 0) + return (TRUE); + else + i++; + } + return (FALSE); +} + static void gis_driver_dispose (GObject *object) { @@ -387,7 +414,16 @@ G_APPLICATION_CLASS (gis_driver_parent_class)->activate (app); - gtk_window_present (GTK_WINDOW (priv->main_window)); + if (current_locale_in_Asia()) + { + gis_cjk_region = TRUE; + gtk_window_present (GTK_WINDOW (priv->main_window)); + } + else + { + gis_cjk_region = FALSE; + gtk_widget_hide (GTK_WIDGET (priv->main_window)); + } } static gboolean @@ -555,6 +591,7 @@ "icon-name", "preferences-system", "deletable", FALSE, NULL); + gtk_widget_hide (GTK_WIDGET(priv->main_window)); g_signal_connect (priv->main_window, "realize", diff -Nura gnome-initial-setup-3.34.1/gnome-initial-setup/gnome-initial-setup.c gnome-initial-setup-3.34.1_new/gnome-initial-setup/gnome-initial-setup.c --- gnome-initial-setup-3.34.1/gnome-initial-setup/gnome-initial-setup.c 2019-10-06 05:03:38.000000000 +0800 +++ gnome-initial-setup-3.34.1_new/gnome-initial-setup/gnome-initial-setup.c 2019-11-26 19:19:43.238641813 +0800 @@ -44,6 +44,7 @@ #include "pages/account/gis-account-pages.h" #include "pages/password/gis-password-page.h" #include "pages/summary/gis-summary-page.h" +#include "language-setting.h" #define VENDOR_PAGES_GROUP "pages" #define VENDOR_SKIP_KEY "skip" @@ -84,6 +85,16 @@ #undef PAGE +static gchar + *SUSE_skip_pages [] = + { + "privacy", + "timezone", + "goa", + "account", + "password" + }; + static gboolean should_skip_page (const gchar *page_id, gchar **skip_pages) @@ -101,73 +112,6 @@ return FALSE; } -static gchar ** -strv_append (gchar **a, - gchar **b) -{ - guint n = g_strv_length (a); - guint m = g_strv_length (b); - - a = g_renew (gchar *, a, n + m + 1); - for (guint i = 0; i < m; i++) - a[n + i] = g_strdup (b[i]); - a[n + m] = NULL; - - return a; -} - -static gchar ** -pages_to_skip_from_file (gboolean is_new_user) -{ - GKeyFile *skip_pages_file; - gchar **skip_pages = NULL; - gchar **additional_skip_pages = NULL; - GError *error = NULL; - - /* VENDOR_CONF_FILE points to a keyfile containing vendor customization - * options. This code will look for options under the "pages" group, and - * supports the following keys: - * - skip (optional): list of pages to be skipped always - * - new_user_only (optional): list of pages to be skipped in existing user mode - * - existing_user_only (optional): list of pages to be skipped in new user mode - * - * This is how this file might look on a vendor image: - * - * [pages] - * skip=timezone - * existing_user_only=language;keyboard - */ - skip_pages_file = g_key_file_new (); - if (!g_key_file_load_from_file (skip_pages_file, VENDOR_CONF_FILE, - G_KEY_FILE_NONE, &error)) { - if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) - g_warning ("Could not read file %s: %s", VENDOR_CONF_FILE, error->message); - - g_error_free (error); - goto out; - } - - skip_pages = g_key_file_get_string_list (skip_pages_file, - VENDOR_PAGES_GROUP, - VENDOR_SKIP_KEY, NULL, NULL); - additional_skip_pages = g_key_file_get_string_list (skip_pages_file, - VENDOR_PAGES_GROUP, - is_new_user ? VENDOR_EXISTING_USER_ONLY_KEY : VENDOR_NEW_USER_ONLY_KEY, - NULL, NULL); - - if (!skip_pages && additional_skip_pages) { - skip_pages = additional_skip_pages; - } else if (skip_pages && additional_skip_pages) { - skip_pages = strv_append (skip_pages, additional_skip_pages); - g_strfreev (additional_skip_pages); - } - - out: - g_key_file_free (skip_pages_file); - - return skip_pages; -} - static void destroy_pages_after (GisAssistant *assistant, GisPage *page) @@ -194,7 +138,6 @@ GisPage *page; GisAssistant *assistant; GisPage *current_page; - gchar **skip_pages; gboolean is_new_user, skipped; assistant = gis_driver_get_assistant (driver); @@ -215,13 +158,12 @@ } is_new_user = (gis_driver_get_mode (driver) == GIS_DRIVER_MODE_NEW_USER); - skip_pages = pages_to_skip_from_file (is_new_user); for (; page_data->page_id != NULL; ++page_data) { skipped = FALSE; if ((page_data->new_user_only && !is_new_user) || - (should_skip_page (page_data->page_id, skip_pages))) + (should_skip_page (page_data->page_id, SUSE_skip_pages))) skipped = TRUE; page = page_data->prepare_page_func (driver); @@ -233,8 +175,6 @@ else gis_driver_add_page (driver, page); } - - g_strfreev (skip_pages); } static GisDriverMode diff -Nura gnome-initial-setup-3.34.1/gnome-initial-setup/gnome-initial-setup.h gnome-initial-setup-3.34.1_new/gnome-initial-setup/gnome-initial-setup.h --- gnome-initial-setup-3.34.1/gnome-initial-setup/gnome-initial-setup.h 2019-10-06 05:03:38.000000000 +0800 +++ gnome-initial-setup-3.34.1_new/gnome-initial-setup/gnome-initial-setup.h 2019-11-25 19:53:10.482353002 +0800 @@ -36,6 +36,7 @@ #include "gis-keyring.h" void gis_ensure_stamp_files (void); +extern gboolean gis_cjk_region; #endif /* __GNOME_INITIAL_SETUP_H__ */ diff -Nura gnome-initial-setup-3.34.1/gnome-initial-setup/language-setting.c gnome-initial-setup-3.34.1_new/gnome-initial-setup/language-setting.c --- gnome-initial-setup-3.34.1/gnome-initial-setup/language-setting.c 1970-01-01 08:00:00.000000000 +0800 +++ gnome-initial-setup-3.34.1_new/gnome-initial-setup/language-setting.c 2019-11-25 19:53:10.482353002 +0800 @@ -0,0 +1,289 @@ +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#define GNOME_DESKTOP_USE_UNSTABLE_API +#define GNOME_SYSTEM_LOCALE_DIR "org.gnome.system.locale" +#define REGION_KEY "region" +#define LOCALE_CONFIG_FILE "/etc/locale.conf" +#include +#include "language-setting.h" + +#include +#include +#include "gis-driver.h" + +static char *get_lang_for_user_object_path (const char *path); +typedef struct _GisLanguagePagePrivate GisLanguagePagePrivate; + +gboolean +cc_common_language_has_font (const gchar *locale) +{ + const FcCharSet *charset; + FcPattern *pattern; + FcObjectSet *object_set; + FcFontSet *font_set; + gchar *language_code; + gboolean is_displayable; + + is_displayable = FALSE; + pattern = NULL; + object_set = NULL; + font_set = NULL; + + if (!gnome_parse_locale (locale, &language_code, NULL, NULL, NULL)) + return FALSE; + + charset = FcLangGetCharSet ((FcChar8 *) language_code); + if (!charset) { + /* fontconfig does not know about this language */ + is_displayable = TRUE; + } + else { + /* see if any fonts support rendering it */ + pattern = FcPatternBuild (NULL, FC_LANG, FcTypeString, language_code, NULL); + + if (pattern == NULL) + goto done; + + object_set = FcObjectSetCreate (); + + if (object_set == NULL) + goto done; + + font_set = FcFontList (NULL, pattern, object_set); + + if (font_set == NULL) + goto done; + + is_displayable = (font_set->nfont > 0); + } + + done: + if (font_set != NULL) + FcFontSetDestroy (font_set); + + if (object_set != NULL) + FcObjectSetDestroy (object_set); + + if (pattern != NULL) + FcPatternDestroy (pattern); + + g_free (language_code); + + return is_displayable; +} + +gchar * +cc_common_language_get_current_language (void) +{ + gchar *language; + char *path; + const gchar *locale; + + path = g_strdup_printf ("/org/freedesktop/Accounts/User%d", getuid ()); + language = get_lang_for_user_object_path (path); + g_free (path); + if (language != NULL && *language != '\0') + return gnome_normalize_locale (language); + + locale = (const gchar *) setlocale (LC_MESSAGES, NULL); + if (locale) + language = gnome_normalize_locale (locale); + else + language = NULL; + + return language; +} + +static gboolean +user_language_has_translations (const char *locale) +{ + char *name, *language_code, *territory_code; + gboolean ret; + + gnome_parse_locale (locale, + &language_code, + &territory_code, + NULL, NULL); + name = g_strdup_printf ("%s%s%s", + language_code, + territory_code != NULL? "_" : "", + territory_code != NULL? territory_code : ""); + g_free (language_code); + g_free (territory_code); + ret = gnome_language_has_translations (name); + g_free (name); + + return ret; +} + +static char * +get_lang_for_user_object_path (const char *path) +{ + GError *error = NULL; + GDBusProxy *user; + GVariant *props; + char *lang; + + user = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.Accounts", + path, + "org.freedesktop.Accounts.User", + NULL, + &error); + if (user == NULL) { + g_warning ("Failed to get proxy for user '%s': %s", + path, error->message); + g_error_free (error); + return NULL; + } + props = g_dbus_proxy_get_cached_property (user, "Language"); + lang = g_variant_dup_string (props, NULL); + + g_variant_unref (props); + g_object_unref (user); + return lang; +} + +static void +add_other_users_language (GHashTable *ht) +{ + GVariant *variant; + GVariantIter *vi; + GError *error = NULL; + const char *str; + GDBusProxy *proxy; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.Accounts", + "/org/freedesktop/Accounts", + "org.freedesktop.Accounts", + NULL, + NULL); + + if (proxy == NULL) + return; + + variant = g_dbus_proxy_call_sync (proxy, + "ListCachedUsers", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (variant == NULL) { + g_warning ("Failed to list existing users: %s", error->message); + g_error_free (error); + g_object_unref (proxy); + return; + } + g_variant_get (variant, "(ao)", &vi); + while (g_variant_iter_loop (vi, "o", &str)) { + char *lang; + char *name; + char *language; + + lang = get_lang_for_user_object_path (str); + if (lang != NULL && *lang != '\0' && + cc_common_language_has_font (lang) && + user_language_has_translations (lang)) { + name = gnome_normalize_locale (lang); + if (!g_hash_table_lookup (ht, name)) { + language = gnome_get_language_from_locale (name, NULL); + g_hash_table_insert (ht, name, language); + } + else { + g_free (name); + } + } + g_free (lang); + } + g_variant_iter_free (vi); + g_variant_unref (variant); + + g_object_unref (proxy); +} + +/* + * Note that @lang needs to be formatted like the locale strings + * returned by gnome_get_all_locales(). + */ +static void +insert_language (GHashTable *ht, + const char *lang) +{ + char *label_own_lang; + char *label_current_lang; + char *label_untranslated; + char *key; + + key = g_strdup (lang); + + label_own_lang = gnome_get_language_from_locale (key, key); + label_current_lang = gnome_get_language_from_locale (key, NULL); + label_untranslated = gnome_get_language_from_locale (key, "C"); + + /* We don't have a translation for the label in + * its own language? */ + if (g_strcmp0 (label_own_lang, label_untranslated) == 0) { + if (g_strcmp0 (label_current_lang, label_untranslated) == 0) + g_hash_table_insert (ht, key, g_strdup (label_untranslated)); + else + g_hash_table_insert (ht, key, g_strdup (label_current_lang)); + } else { + g_hash_table_insert (ht, key, g_strdup (label_own_lang)); + } + + g_free (label_own_lang); + g_free (label_current_lang); + g_free (label_untranslated); +} + +static void +insert_user_languages (GHashTable *ht) +{ + char *name; + + /* Add the languages used by other users on the system */ + add_other_users_language (ht); + + /* Add current locale */ + name = cc_common_language_get_current_language (); + if (g_hash_table_lookup (ht, name) == NULL) { + insert_language (ht, name); + } else { + g_free (name); + } +} + +GHashTable * +cc_common_language_get_initial_languages (void) +{ + GHashTable *ht; + + ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + insert_language (ht, "en_US.UTF-8"); + insert_language (ht, "en_GB.UTF-8"); + insert_language (ht, "de_DE.UTF-8"); + insert_language (ht, "fr_FR.UTF-8"); + insert_language (ht, "es_ES.UTF-8"); + insert_language (ht, "zh_CN.UTF-8"); + insert_language (ht, "ja_JP.UTF-8"); + insert_language (ht, "ru_RU.UTF-8"); + insert_language (ht, "ar_EG.UTF-8"); + + insert_user_languages (ht); + + return ht; +} diff -Nura gnome-initial-setup-3.34.1/gnome-initial-setup/language-setting.h gnome-initial-setup-3.34.1_new/gnome-initial-setup/language-setting.h --- gnome-initial-setup-3.34.1/gnome-initial-setup/language-setting.h 1970-01-01 08:00:00.000000000 +0800 +++ gnome-initial-setup-3.34.1_new/gnome-initial-setup/language-setting.h 2019-11-25 19:53:10.482353002 +0800 @@ -0,0 +1,13 @@ +#ifndef __CC_COMMON_LANGUAGE_H__ +#define __CC_COMMON_LANGUAGE_H__ + +#include + +G_BEGIN_DECLS + +gchar *cc_common_language_get_current_language (void); +GHashTable *cc_common_language_get_initial_languages (void); + +G_END_DECLS + +#endif diff -Nura gnome-initial-setup-3.34.1/gnome-initial-setup/pages/keyboard/cc-input-chooser.c gnome-initial-setup-3.34.1_new/gnome-initial-setup/pages/keyboard/cc-input-chooser.c --- gnome-initial-setup-3.34.1/gnome-initial-setup/pages/keyboard/cc-input-chooser.c 2019-10-06 05:03:38.000000000 +0800 +++ gnome-initial-setup-3.34.1_new/gnome-initial-setup/pages/keyboard/cc-input-chooser.c 2019-11-25 19:53:10.483353011 +0800 @@ -58,6 +58,7 @@ gboolean showing_extra; gchar *locale; + gboolean is_Japanese; gchar *id; gchar *type; GnomeXkbInfo *xkb_info; @@ -271,8 +272,14 @@ if (priv->id == NULL || priv->type == NULL) should_be_visible = FALSE; + else if (priv->is_Japanese) + { + if ( g_strcmp0 (widget->id, "mozc-jp") == 0) + should_be_visible = TRUE; + } else should_be_visible = g_strcmp0 (widget->id, priv->id) == 0 && g_strcmp0 (widget->type, priv->type) == 0; + gtk_widget_set_opacity (widget->checkmark, should_be_visible ? 1.0 : 0.0); if (widget->is_extra && should_be_visible) @@ -451,6 +458,14 @@ widget = get_input_widget (child); + if (priv->is_Japanese) + { + if((g_strcmp0 (widget->id, "mozc-jp") == 0) || (g_strcmp0 (widget->id, "anthy") == 0)) + return TRUE; + if(g_strcmp0 (widget->id, "Japanese (Mozc)") == 0) + return FALSE; + } + if (!priv->showing_extra && widget->is_extra) return FALSE; @@ -467,6 +482,9 @@ GtkListBoxRow *b, gpointer data) { + CcInputChooser *chooser = data; + CcInputChooserPrivate *priv = cc_input_chooser_get_instance_private (chooser); + InputWidget *la, *lb; la = get_input_widget (gtk_bin_get_child (GTK_BIN (a))); @@ -478,6 +496,18 @@ if (lb == NULL) return -1; + if (priv->is_Japanese) + { + if (g_strcmp0 (la->id, "mozc-jp") == 0 && g_strcmp0 (lb->id, "anthy") == 0) + return -1; + if (g_strcmp0 (lb->id, "mozc-jp") == 0 && g_strcmp0 (la->id, "anthy") == 0) + return 1; + if (g_strcmp0 (la->id, "mozc-jp") == 0 || g_strcmp0 (la->id, "anthy") == 0) + return -1; + if (g_strcmp0 (lb->id, "mozc-jp") == 0 || g_strcmp0 (lb->id, "anthy") == 0) + return 1; + } + if (la->is_extra && !lb->is_extra) return 1; @@ -752,9 +782,13 @@ gtk_list_box_set_selection_mode (GTK_LIST_BOX (priv->input_list), GTK_SELECTION_NONE); - if (priv->locale == NULL) { + if (priv->locale == NULL) priv->locale = cc_common_language_get_current_language (); - } + + if(g_strcmp0(priv->locale, "ja_JP.UTF-8") == 0) + priv->is_Japanese = TRUE; + else + priv->is_Japanese = FALSE; get_locale_infos (chooser); #ifdef HAVE_IBUS diff -Nura gnome-initial-setup-3.34.1/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c gnome-initial-setup-3.34.1_new/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c --- gnome-initial-setup-3.34.1/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c 2019-10-06 05:03:38.000000000 +0800 +++ gnome-initial-setup-3.34.1_new/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c 2019-11-25 19:53:10.483353011 +0800 @@ -36,6 +36,7 @@ #include "gis-keyboard-page.h" #include "keyboard-resources.h" #include "cc-input-chooser.h" +#include "cc-common-language.h" #include "cc-common-language.h" @@ -52,6 +53,7 @@ GCancellable *cancellable; GPermission *permission; GSettings *input_settings; + gchar *current_language; GSList *system_sources; }; @@ -437,6 +439,29 @@ update_page_complete (self); } +gboolean +current_locale_need_input_selection(GisKeyboardPage *self) +{ + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + + static gchar *expose_locale_list[] = {"zh_CN.UTF-8", + "zh_HK.UTF-8", + "zh_MO.UTF-8", + "zh_TW.UTF-8", + "zh_SG.UTF-8", + "ja_JP.UTF-8", + "ko_KR.UTF-8"}; + guint i = 0; + while (expose_locale_list[i]) + { + if (g_strcmp0 (expose_locale_list[i], priv->current_language) == 0) + return (TRUE); + else + i++; + } + return (FALSE); +} + static void gis_keyboard_page_constructed (GObject *object) { @@ -456,6 +481,7 @@ g_settings_delay (priv->input_settings); priv->cancellable = g_cancellable_new (); + priv->current_language = cc_common_language_get_current_language (); g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, @@ -473,7 +499,10 @@ update_page_complete (self); - gtk_widget_show (GTK_WIDGET (self)); + if (current_locale_need_input_selection(self)) + gtk_widget_show (GTK_WIDGET (self)); + else + gtk_widget_hide (GTK_WIDGET (self)); } static void diff -Nura gnome-initial-setup-3.34.1/gnome-initial-setup/pages/language/gis-language-page.c gnome-initial-setup-3.34.1_new/gnome-initial-setup/pages/language/gis-language-page.c --- gnome-initial-setup-3.34.1/gnome-initial-setup/pages/language/gis-language-page.c 2019-10-06 05:03:38.000000000 +0800 +++ gnome-initial-setup-3.34.1_new/gnome-initial-setup/pages/language/gis-language-page.c 2019-11-27 11:11:18.491358283 +0800 @@ -28,17 +28,33 @@ #define GNOME_SYSTEM_LOCALE_DIR "org.gnome.system.locale" #define REGION_KEY "region" +#define LOCALE_CONFIG_FILE "/etc/locale.conf" #include "config.h" #include "language-resources.h" #include "gis-welcome-widget.h" #include "cc-language-chooser.h" #include "gis-language-page.h" +#include "gnome-initial-setup.h" #include #include #include #include +#include +#include +#include + +typedef struct _Region_Info +{ + GPermission *permission; + GDBusProxy *localed; + GCancellable *cancellable; + gchar *language; + gchar *region; + gchar *system_language; + gchar *system_region; +} Region_Info; struct _GisLanguagePagePrivate { @@ -49,6 +65,7 @@ GDBusProxy *localed; GPermission *permission; const gchar *new_locale_id; + gchar *system_language; GCancellable *cancellable; }; @@ -103,11 +120,17 @@ GParamSpec *pspec, gpointer user_data) { - gchar *new_locale_id = user_data; + GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (user_data); + gchar *new_locale_id = g_strdup (priv->new_locale_id); act_user_set_language (ACT_USER (object), new_locale_id); - g_free (new_locale_id); + + if (!gis_cjk_region) + { + gis_ensure_stamp_files (); + g_application_quit (G_APPLICATION (GIS_PAGE (user_data)->driver)); + } } static void @@ -179,85 +202,161 @@ priv->localed = proxy; } -static char * -get_item (const char *buffer, const char *name) +static void +language_confirmed (CcLanguageChooser *chooser, + GisLanguagePage *page) { - char *label, *start, *end, *result; - char end_char; + gis_assistant_next_page (gis_driver_get_assistant (GIS_PAGE (page)->driver)); +} - result = NULL; - start = NULL; - end = NULL; - label = g_strconcat (name, "=", NULL); - if ((start = strstr (buffer, label)) != NULL) +void +get_language_from_dbus_proxy (Region_Info *self) +{ + g_autoptr (GVariant) v = NULL; + v = + g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self->localed), "Locale"); + if (v) + { + g_autofree const gchar **strv = NULL; + gsize len; + gint i; + strv = g_variant_get_strv (v, &len); + for (i = 0; strv[i]; i++) { - start += strlen (label); - end_char = '\n'; - if (*start == '"') - { - start++; - end_char = '"'; - } - - end = strchr (start, end_char); + if (g_str_has_prefix (strv[i], "LANG=")) + self->language = g_strdup (strv[i] + strlen ("LANG=")); } + } +} - if (start != NULL && end != NULL) +void +get_language_from_config_file (Region_Info *self) +{ + g_autoptr (GFile) file = g_file_new_for_path (LOCALE_CONFIG_FILE); + g_autoptr (GFileInputStream) in = g_file_read (file, NULL, NULL); + g_assert (in != NULL); + gssize read; + char temp[1000]; + char *head; + + if ((read = g_input_stream_read (G_INPUT_STREAM (in), temp, + G_N_ELEMENTS (temp) - 1, NULL, NULL))) + { + if ((head = strstr (temp, "LANG"))) { - result = g_strndup (start, end - start); + head = index (head, '='); + do {head++;} + while (isblank (head[0])); + *index (head, '\n') = '\0'; + self->language = g_strdup (head); } - - g_free (label); - - return result; + } } -static void -update_distro_logo (GisLanguagePage *page) +static gboolean +connect_dbus_proxy (Region_Info * self) { - GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page); - char *buffer; - char *id; - gsize i; - - static const struct { - const char *id; - const char *logo; - } id_to_logo[] = { - { "debian", "emblem-debian" }, - { "fedora", "fedora-logo-icon" }, - { "ubuntu", "ubuntu-logo-icon" }, - { "openSUSE Tumbleweed", "opensuse-logo-icon" }, - { "openSUSE Leap", "opensuse-logo-icon" }, - { "SLED", "suse-logo-icon" }, - { "SLES", "suse-logo-icon" }, - }; + g_autoptr (GDBusConnection) bus = NULL; + g_autoptr (GError) error = NULL; + GDBusProxy *proxy; - id = NULL; + self->permission = + polkit_permission_new_sync ("org.freedesktop.locale1.set-locale", NULL, + NULL, &error); + if (self->permission == NULL) + { + g_warning + ("Could not get 'org.freedesktop.locale1.set-locale' permission: %s", + error->message); + return FALSE; + } - if (g_file_get_contents ("/etc/os-release", &buffer, NULL, NULL)) + bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); + proxy = g_dbus_proxy_new_sync (bus, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + NULL, + "org.freedesktop.locale1", + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + self->cancellable, &error); + if (!proxy) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to contact localed: %s\n", error->message); + return FALSE; + } + else { - id = get_item (buffer, "ID"); - g_free (buffer); + self->localed = proxy; + return TRUE; } +} - for (i = 0; i < G_N_ELEMENTS (id_to_logo); i++) +static gboolean +get_system_language (GisPage *page) +{ + gboolean language_acquire = FALSE; + GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (GIS_LANGUAGE_PAGE (page)); + Region_Info *self = g_malloc0 (sizeof (Region_Info)); + self->language = NULL; + + /*Try to get system language from DBUS, if DBUS don't have this value, language will keep NULL.*/ + if (connect_dbus_proxy (self)) + get_language_from_dbus_proxy (self); + if (self->language != NULL) + { + language_acquire = TRUE; + priv-> system_language = g_strdup(self->language); + priv->new_locale_id = g_strdup(self->language); + } + /*When get languge from DBUS failed, try to get from config file.*/ + if (!language_acquire) + { + get_language_from_config_file (self); + if (self->language != NULL) { - if (g_strcmp0 (id, id_to_logo[i].id) == 0) - { - g_object_set (priv->logo, "icon-name", id_to_logo[i].logo, NULL); - break; - } + language_acquire = TRUE; + priv-> system_language = g_strdup(self->language); + priv->new_locale_id = g_strdup(self->language); } + } - g_free (id); + g_clear_object (&self->permission); + g_clear_object (&self->localed); + g_clear_object (&self->cancellable); + g_free (self->language); + g_free (self->region); + g_free (self->system_language); + g_free (self->system_region); + g_free (self); + return language_acquire; } static void -language_confirmed (CcLanguageChooser *chooser, - GisLanguagePage *page) +silent_set_system_locale_to_user (GisLanguagePage *page) { - gis_assistant_next_page (gis_driver_get_assistant (GIS_PAGE (page)->driver)); + GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page); + GisDriver *driver; + GSettings *region_settings; + ActUser *user; + + driver = GIS_PAGE (page)->driver; + setlocale (LC_MESSAGES, priv->new_locale_id); + + region_settings = g_settings_new (GNOME_SYSTEM_LOCALE_DIR); + g_settings_reset (region_settings, REGION_KEY); + g_object_unref (region_settings); + + user = act_user_manager_get_user (act_user_manager_get_default (), g_get_user_name ()); + + if (act_user_is_loaded (user)) + act_user_set_language (user, priv->new_locale_id); + else + g_signal_connect (user, + "notify::is-loaded", + G_CALLBACK (user_loaded), + page); + gis_driver_set_user_language (driver, priv->new_locale_id, FALSE); } static void @@ -271,8 +370,6 @@ G_OBJECT_CLASS (gis_language_page_parent_class)->constructed (object); - update_distro_logo (page); - g_signal_connect (priv->language_chooser, "notify::language", G_CALLBACK (language_changed), page); g_signal_connect (priv->language_chooser, "confirm", @@ -297,6 +394,12 @@ } gis_page_set_complete (GIS_PAGE (page), TRUE); + + gtk_widget_hide (priv->language_chooser); + + if (get_system_language(GIS_PAGE (page))) + silent_set_system_locale_to_user (page); + gtk_widget_show (GTK_WIDGET (page)); }