summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--liblightdm-gobject/lightdm/user.h2
-rw-r--r--liblightdm-gobject/user.c83
-rw-r--r--tests/scripts/keyboard-layout.conf3
-rw-r--r--tests/src/test-gobject-greeter.c17
-rw-r--r--tests/src/test-runner.c31
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)