diff options
-rw-r--r-- | liblightdm-gobject/lightdm/user.h | 2 | ||||
-rw-r--r-- | liblightdm-gobject/user.c | 83 | ||||
-rw-r--r-- | tests/scripts/keyboard-layout.conf | 3 | ||||
-rw-r--r-- | tests/src/test-gobject-greeter.c | 17 | ||||
-rw-r--r-- | tests/src/test-runner.c | 31 |
5 files changed, 111 insertions, 25 deletions
diff --git a/liblightdm-gobject/lightdm/user.h b/liblightdm-gobject/lightdm/user.h index e9a5891b..eac0df51 100644 --- a/liblightdm-gobject/lightdm/user.h +++ b/liblightdm-gobject/lightdm/user.h @@ -99,6 +99,8 @@ const gchar *lightdm_user_get_language (LightDMUser *user); const gchar *lightdm_user_get_layout (LightDMUser *user); +const gchar * const *lightdm_user_get_layouts (LightDMUser *user); + const gchar *lightdm_user_get_session (LightDMUser *user); gboolean lightdm_user_get_logged_in (LightDMUser *user); diff --git a/liblightdm-gobject/user.c b/liblightdm-gobject/user.c index cc195b0c..d47c05f6 100644 --- a/liblightdm-gobject/user.c +++ b/liblightdm-gobject/user.c @@ -98,7 +98,7 @@ typedef struct GKeyFile *dmrc_file; gchar *language; - gchar *layout; + gchar **layouts; gchar *session; } LightDMUserPrivate; @@ -1144,9 +1144,17 @@ load_dmrc (LightDMUser *user) *codeset = '\0'; } - if (priv->layout) - g_free (priv->layout); - priv->layout = g_key_file_get_string (priv->dmrc_file, "Desktop", "Layout", NULL); + if (priv->layouts) + { + g_strfreev (priv->layouts); + priv->layouts = NULL; + } + if (g_key_file_has_key (priv->dmrc_file, "Desktop", "Layout", NULL)) + { + priv->layouts = g_malloc (sizeof (gchar *) * 2); + priv->layouts[0] = g_key_file_get_string (priv->dmrc_file, "Desktop", "Layout", NULL); + priv->layouts[1] = NULL; + } if (priv->session) g_free (priv->session); @@ -1190,6 +1198,37 @@ get_string_property (GDBusProxy *proxy, const gchar *property) return rv; } +static gchar ** +get_string_array_property (GDBusProxy *proxy, const gchar *property) +{ + GVariant *answer; + gchar **rv; + + if (!proxy) + return NULL; + + answer = g_dbus_proxy_get_cached_property (proxy, property); + + if (!answer) + { + g_warning ("Could not get accounts property %s", property); + return NULL; + } + + if (!g_variant_is_of_type (answer, G_VARIANT_TYPE ("as"))) + { + g_warning ("Unexpected accounts property type for %s: %s", + property, g_variant_get_type_string (answer)); + g_variant_unref (answer); + return NULL; + } + + rv = g_variant_dup_strv (answer, NULL); + + g_variant_unref (answer); + return rv; +} + static gboolean load_accounts_service (LightDMUser *user) { @@ -1197,7 +1236,7 @@ load_accounts_service (LightDMUser *user) LightDMUserListPrivate *list_priv = GET_LIST_PRIVATE (priv->user_list); UserAccountObject *account = NULL; GList *iter; - gchar *value; + gchar **value; /* First, find AccountObject proxy */ for (iter = list_priv->user_account_objects; iter; iter = iter->next) @@ -1220,11 +1259,11 @@ load_accounts_service (LightDMUser *user) g_free (priv->session); priv->session = get_string_property (account->proxy, "XSession"); - value = get_string_property (account->proxy, "XKeyboardLayout"); + value = get_string_array_property (account->proxy, "XKeyboardLayouts"); if (value) { - g_free (priv->layout); - priv->layout = value; + g_strfreev (priv->layouts); + priv->layouts = value; } return TRUE; @@ -1236,6 +1275,13 @@ load_user_values (LightDMUser *user) { load_dmrc (user); load_accounts_service (user); // overrides dmrc values + + /* Ensure a few guarantees */ + if (GET_USER_PRIVATE (user)->layouts == NULL) + { + GET_USER_PRIVATE (user)->layouts = g_malloc (sizeof (gchar)); + GET_USER_PRIVATE (user)->layouts[0] = NULL; + } } /** @@ -1260,14 +1306,30 @@ lightdm_user_get_language (LightDMUser *user) * * Get the keyboard layout for a user. * - * Return value: The keyboard layoyt for the given user or #NULL if using system defaults. + * Return value: The keyboard layout for the given user or #NULL if using system defaults. Copy the value if you want to use it long term. **/ const gchar * lightdm_user_get_layout (LightDMUser *user) { g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); load_user_values (user); - return GET_USER_PRIVATE (user)->layout; + return GET_USER_PRIVATE (user)->layouts[0]; +} + +/** + * lightdm_user_get_layouts + * @user: A #LightDMUser + * + * Get the configured keyboard layouts for a user. + * + * Return value: A NULL-terminated array of keyboard layouts for the given user. Copy the values if you want to use them long term. + **/ +const gchar * const * +lightdm_user_get_layouts (LightDMUser *user) +{ + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); + load_user_values (user); + return (const gchar * const *) GET_USER_PRIVATE (user)->layouts; } /** @@ -1386,6 +1448,7 @@ lightdm_user_finalize (GObject *object) g_free (priv->home_directory); g_free (priv->image); g_free (priv->background); + g_strfreev (priv->layouts); if (priv->dmrc_file) g_key_file_free (priv->dmrc_file); } diff --git a/tests/scripts/keyboard-layout.conf b/tests/scripts/keyboard-layout.conf index ba67fc03..349260f0 100644 --- a/tests/scripts/keyboard-layout.conf +++ b/tests/scripts/keyboard-layout.conf @@ -26,6 +26,9 @@ minimum-display-number=50 #?GREETER :50 LOG-LAYOUT USERNAME=bob LAYOUT='us' #?*GREETER :50 LOG-LAYOUT USERNAME=carol #?GREETER :50 LOG-LAYOUT USERNAME=carol LAYOUT='fr oss' +#?*GREETER :50 LOG-LAYOUTS USERNAME=carol +#?GREETER :50 LOG-LAYOUTS USERNAME=carol LAYOUT='fr oss' +#?GREETER :50 LOG-LAYOUTS USERNAME=carol LAYOUT='ru' # Cleanup #?*STOP-DAEMON diff --git a/tests/src/test-gobject-greeter.c b/tests/src/test-gobject-greeter.c index 982f15b5..cb22e00d 100644 --- a/tests/src/test-gobject-greeter.c +++ b/tests/src/test-gobject-greeter.c @@ -113,6 +113,23 @@ request_cb (const gchar *request) } g_free (r); + r = g_strdup_printf ("GREETER %s LOG-LAYOUTS USERNAME=", getenv ("DISPLAY")); + if (g_str_has_prefix (request, r)) + { + LightDMUser *user; + const gchar *username; + const gchar * const *layouts; + int i; + + username = request + strlen (r); + user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username); + layouts = lightdm_user_get_layouts (user); + + for (i = 0; layouts[i]; i++) + status_notify ("GREETER %s LOG-LAYOUTS USERNAME=%s LAYOUT='%s'", getenv ("DISPLAY"), username, layouts[i]); + } + g_free (r); + r = g_strdup_printf ("GREETER %s LOG-VARIANTS LAYOUT=", getenv ("DISPLAY")); if (g_str_has_prefix (request, r)) { diff --git a/tests/src/test-runner.c b/tests/src/test-runner.c index f5f550eb..c08e3954 100644 --- a/tests/src/test-runner.c +++ b/tests/src/test-runner.c @@ -49,7 +49,7 @@ typedef struct guint id; gchar *language; gchar *xsession; - gchar *layout; + gchar **layouts; } AccountsUser; static GList *accounts_users = NULL; static void handle_user_call (GDBusConnection *connection, @@ -788,7 +788,7 @@ load_passwd_file () *c = '\0'; } user->xsession = g_key_file_get_string (dmrc_file, "Desktop", "Session", NULL); - user->layout = g_key_file_get_string (dmrc_file, "X-Accounts", "Layout", NULL); + user->layouts = g_key_file_get_string_list (dmrc_file, "X-Accounts", "Layouts", NULL, NULL); user->path = g_strdup_printf ("/org/freedesktop/Accounts/User%d", uid); user->id = g_dbus_connection_register_object (accounts_connection, user->path, @@ -913,8 +913,9 @@ handle_user_get_property (GDBusConnection *connection, return g_variant_new_string (user->language ? user->language : ""); else if (strcmp (property_name, "XSession") == 0) return g_variant_new_string (user->xsession ? user->xsession : ""); - else if (strcmp (property_name, "XKeyboardLayout") == 0) - return g_variant_new_string (user->layout ? user->layout : ""); + else if (strcmp (property_name, "XKeyboardLayouts") == 0 && + user->layouts != NULL && user->layouts[0] != NULL) + return g_variant_new_strv ((const gchar * const *) user->layouts, -1); return NULL; } @@ -952,7 +953,7 @@ accounts_name_acquired_cb (GDBusConnection *connection, " <property name='BackgroundFile' type='s' access='read'/>" " <property name='Language' type='s' access='read'/>" " <property name='XSession' type='s' access='read'/>" - " <property name='XKeyboardLayout' type='s' access='read'/>" + " <property name='XKeyboardLayouts' type='as' access='read'/>" " </interface>" "</node>"; GError *error = NULL; @@ -1205,18 +1206,18 @@ main (int argc, char **argv) gchar *real_name; gchar *xsession; gchar *dmrc_layout; - gchar *dbus_layout; + gchar *dbus_layouts; gchar *language; gint uid; } users[] = { - {"root", "", TRUE, "root", NULL, NULL, NULL, NULL, 0}, - {"lightdm", "", TRUE, "", NULL, NULL, NULL, NULL, 100}, - {"alice", "password", TRUE, "Alice User", NULL, NULL, NULL, NULL, 1000}, - {"bob", "", TRUE, "Bob User", NULL, "us", NULL, "en_AU.utf8", 1001}, - {"carol", "", TRUE, "Carol User", "alternative", "ru", "fr\toss", "fr_FR.UTF-8", 1002}, - {"dave", "", FALSE, "Dave User", NULL, NULL, NULL, NULL, 1003}, - {NULL, NULL, FALSE, NULL, NULL, NULL, NULL, NULL, 0} + {"root", "", TRUE, "root", NULL, NULL, NULL, NULL, 0}, + {"lightdm", "", TRUE, "", NULL, NULL, NULL, NULL, 100}, + {"alice", "password", TRUE, "Alice User", NULL, NULL, NULL, NULL, 1000}, + {"bob", "", TRUE, "Bob User", NULL, "us", NULL, "en_AU.utf8", 1001}, + {"carol", "", TRUE, "Carol User", "alternative", "ru", "fr\toss;ru;", "fr_FR.UTF-8", 1002}, + {"dave", "", FALSE, "Dave User", NULL, NULL, NULL, NULL, 1003}, + {NULL, NULL, FALSE, NULL, NULL, NULL, NULL, NULL, 0} }; passwd_data = g_string_new (""); int i; @@ -1245,9 +1246,9 @@ main (int argc, char **argv) g_key_file_set_string (dmrc_file, "Desktop", "Layout", users[i].dmrc_layout); save_dmrc = TRUE; } - if (users[i].dbus_layout) + if (users[i].dbus_layouts) { - g_key_file_set_string (dmrc_file, "X-Accounts", "Layout", users[i].dbus_layout); + g_key_file_set_string (dmrc_file, "X-Accounts", "Layouts", users[i].dbus_layouts); save_dmrc = TRUE; } if (users[i].language) |