]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
add lightdm_user_get_layouts
authorMichael Terry <michael.terry@canonical.com>
Fri, 10 Feb 2012 14:57:32 +0000 (09:57 -0500)
committerMichael Terry <michael.terry@canonical.com>
Fri, 10 Feb 2012 14:57:32 +0000 (09:57 -0500)
liblightdm-gobject/liblightdm-gobject-1.vapi
liblightdm-gobject/lightdm/user.h
liblightdm-gobject/user.c
tests/scripts/keyboard-layout.conf
tests/src/test-gobject-greeter.c
tests/src/test-runner.c

index c35774d422205c39e23f9073e9296039df5d00e8..9c08b6821106daf6ea8d9aa5460e8ef7bc4796aa 100644 (file)
@@ -87,6 +87,8 @@ namespace LightDM {
         public unowned string image { get; }
         public unowned string language { get; }
         public unowned string layout { get; }
+        [CCode (array_length = false, array_null_terminated = true)]
+        public unowned string[] layouts { get; }
         public bool logged_in { get; }
         public unowned string name { get; }
         public unowned string real_name { get; }
index e9a5891b914fff32963b9221073a05836a75db77..eac0df51e9f816e5eb27e28da6debec94e03016c 100644 (file)
@@ -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);
index cc195b0cc0e1686680d243a85904072f3008f050..b974f2adfaf38d860b421eb4f850d64e6e2cc81b 100644 (file)
@@ -38,6 +38,7 @@ enum
     USER_PROP_BACKGROUND,
     USER_PROP_LANGUAGE,
     USER_PROP_LAYOUT,
+    USER_PROP_LAYOUTS,
     USER_PROP_SESSION,
     USER_PROP_LOGGED_IN
 };
@@ -98,7 +99,7 @@ typedef struct
 
     GKeyFile *dmrc_file;
     gchar *language;
-    gchar *layout;
+    gchar **layouts;
     gchar *session;
 } LightDMUserPrivate;
 
@@ -1144,9 +1145,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 +1199,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 +1237,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 +1260,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 +1276,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 +1307,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: (transfer none): 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;
 }
 
 /**
@@ -1363,6 +1426,9 @@ lightdm_user_get_property (GObject    *object,
     case USER_PROP_LAYOUT:
         g_value_set_string (value, lightdm_user_get_layout (self));
         break;
+    case USER_PROP_LAYOUTS:
+        g_value_set_boxed (value, g_strdupv ((gchar **) lightdm_user_get_layouts (self)));
+        break;
     case USER_PROP_SESSION:
         g_value_set_string (value, lightdm_user_get_session (self));
         break;
@@ -1386,6 +1452,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);
 }
@@ -1457,6 +1524,13 @@ lightdm_user_class_init (LightDMUserClass *klass)
                                                           "Keyboard layout used by this user",
                                                           NULL,
                                                           G_PARAM_READABLE));
+    g_object_class_install_property (object_class,
+                                     USER_PROP_LAYOUTS,
+                                     g_param_spec_boxed ("layouts",
+                                                         "layouts",
+                                                         "Keyboard layouts used by this user",
+                                                         G_TYPE_STRV,
+                                                         G_PARAM_READABLE));
     g_object_class_install_property (object_class,
                                      USER_PROP_SESSION,
                                      g_param_spec_string ("session",
index ba67fc03754e55e4e309a7dadd37b5710b991c96..349260f0963268a2faa61ad565965c22e881bdcd 100644 (file)
@@ -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
index 982f15b5f795516edfcfddaf23a225e9550a1b98..cb22e00dd528ea8f305c60321ac577157eb7aa0d 100644 (file)
@@ -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))
     {
index f5f550ebed4a58226a3afd79a86f38b310f462c9..c08e3954e06c772dad91ea4ae75196c174e88fe2 100644 (file)
@@ -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)