]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - liblightdm-gobject/session.c
Add support for greeters that stay alive after logging a user in, rather than being...
[sojka/lightdm.git] / liblightdm-gobject / session.c
index 3ebb8ce49dff49e65403546ca620a56671ad1788..2a0be54496908c9b1ea5edb6184752c05a56f009 100644 (file)
@@ -4,14 +4,14 @@
  * 
  * This library is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option) any
- * later version. See http://www.gnu.org/copyleft/lgpl.html the full text of the
- * license.
+ * Software Foundation; either version 2 or version 3 of the License.
+ * See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
  */
 
 #include <string.h>
 #include <gio/gdesktopappinfo.h>
 
+#include "configuration.h"
 #include "lightdm/session.h"
 
 enum {
@@ -24,6 +24,7 @@ enum {
 typedef struct
 {
     gchar *key;
+    gchar *type;
     gchar *name;
     gchar *comment;
 } LightDMSessionPrivate;
@@ -33,7 +34,8 @@ G_DEFINE_TYPE (LightDMSession, lightdm_session, G_TYPE_OBJECT);
 #define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_SESSION, LightDMSessionPrivate)
 
 static gboolean have_sessions = FALSE;
-static GList *sessions = NULL;
+static GList *local_sessions = NULL;
+static GList *remote_sessions = NULL;
 
 static gint 
 compare_session (gconstpointer a, gconstpointer b)
@@ -46,7 +48,7 @@ compare_session (gconstpointer a, gconstpointer b)
 static LightDMSession *
 load_session (GKeyFile *key_file, const gchar *key)
 {
-    gchar *domain, *name;
+    gchar *type, *domain, *name;
     LightDMSession *session;
     LightDMSessionPrivate *priv;
     gchar *try_exec;
@@ -55,6 +57,10 @@ load_session (GKeyFile *key_file, const gchar *key)
         g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, NULL))
         return NULL;
 
+    type = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-LightDM-Session-Type", NULL);
+    if (!type)
+        type = "x";
+
 #ifdef G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN
     domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, NULL);
 #else
@@ -78,6 +84,7 @@ load_session (GKeyFile *key_file, const gchar *key)
 
         if (!full_path)
         {
+            g_free (name);
             g_free (domain);
             return NULL;
         }
@@ -90,6 +97,9 @@ load_session (GKeyFile *key_file, const gchar *key)
     g_free (priv->key);
     priv->key = g_strdup (key);
 
+    g_free (priv->type);
+    priv->type = g_strdup (type);
+
     g_free (priv->name);
     priv->name = name;
 
@@ -98,28 +108,23 @@ load_session (GKeyFile *key_file, const gchar *key)
     if (!priv->comment)
         priv->comment = g_strdup ("");
 
-    sessions = g_list_insert_sorted (sessions, session, compare_session);
-
     g_free (domain);
 
     return session;
 }
 
-static void
-update_sessions (void)
+static GList *
+load_sessions_dir (GList *sessions, const gchar *sessions_dir)
 {
     GDir *directory;
     GError *error = NULL;
 
-    if (have_sessions)
-        return;
-
-    directory = g_dir_open (XSESSIONS_DIR, 0, &error);
-    if (error)
+    directory = g_dir_open (sessions_dir, 0, &error);
+    if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
         g_warning ("Failed to open sessions directory: %s", error->message);
     g_clear_error (&error);
     if (!directory)
-        return;
+        return sessions;
 
     while (TRUE)
     {
@@ -135,7 +140,7 @@ update_sessions (void)
         if (!g_str_has_suffix (filename, ".desktop"))
             continue;
 
-        path = g_build_filename (XSESSIONS_DIR, filename, NULL);
+        path = g_build_filename (sessions_dir, filename, NULL);
 
         key_file = g_key_file_new ();
         result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
@@ -151,7 +156,10 @@ update_sessions (void)
             key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
             session = load_session (key_file, key);
             if (session)
+            {
                 g_debug ("Loaded session %s (%s, %s)", path, GET_PRIVATE (session)->name, GET_PRIVATE (session)->comment);
+                sessions = g_list_insert_sorted (sessions, session, compare_session);
+            }
             else
                 g_debug ("Ignoring session %s", path);
             g_free (key);
@@ -162,6 +170,60 @@ update_sessions (void)
     }
 
     g_dir_close (directory);
+  
+    return sessions;
+}
+
+static GList *
+load_sessions (const gchar *sessions_dir)
+{
+    GList *sessions = NULL;
+    gchar **dirs;
+    int i;
+
+    dirs = g_strsplit (sessions_dir, ":", -1);
+    for (i = 0; dirs[i]; i++)
+        sessions = load_sessions_dir (sessions, dirs[i]);
+    g_strfreev (dirs);
+  
+    return sessions;
+}
+
+static void
+update_sessions (void)
+{
+    gchar *sessions_dir;
+    gchar *remote_sessions_dir;
+    gchar *value;
+
+    if (have_sessions)
+        return;
+
+    sessions_dir = g_strdup (SESSIONS_DIR);
+    remote_sessions_dir = g_strdup (REMOTE_SESSIONS_DIR);
+
+    /* Use session directory from configuration */
+    config_load_from_standard_locations (config_get_instance (), NULL, NULL);
+      
+    value = config_get_string (config_get_instance (), "LightDM", "sessions-directory");
+    if (value)
+    {
+        g_free (sessions_dir);
+        sessions_dir = value;
+    }
+
+    value = config_get_string (config_get_instance (), "LightDM", "remote-sessions-directory");
+    if (value)
+    {
+        g_free (remote_sessions_dir);
+        remote_sessions_dir = value;
+    }
+
+    local_sessions = load_sessions (sessions_dir);
+    remote_sessions = load_sessions (remote_sessions_dir);
+
+    g_free (sessions_dir);
+    g_free (remote_sessions_dir);
 
     have_sessions = TRUE;
 }
@@ -177,11 +239,25 @@ GList *
 lightdm_get_sessions (void)
 {
     update_sessions ();
-    return sessions;
+    return local_sessions;
+}
+
+/**
+ * lightdm_get_remote_sessions:
+ *
+ * Get the available remote sessions.
+ *
+ * Return value: (element-type LightDMSession) (transfer none): A list of #LightDMSession
+ **/
+GList *
+lightdm_get_remote_sessions (void)
+{
+    update_sessions ();
+    return remote_sessions;
 }
 
 /**
- * lightdm_session_get_key
+ * lightdm_session_get_key:
  * @session: A #LightDMSession
  * 
  * Get the key for a session
@@ -196,7 +272,22 @@ lightdm_session_get_key (LightDMSession *session)
 }
 
 /**
- * lightdm_session_get_name
+ * lightdm_session_get_session_type:
+ * @session: A #LightDMSession
+ * 
+ * Get the type a session
+ * 
+ * Return value: The session type, e.g. x or mir
+ **/
+const gchar *
+lightdm_session_get_session_type (LightDMSession *session)
+{
+    g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
+    return GET_PRIVATE (session)->type;
+}
+
+/**
+ * lightdm_session_get_name:
  * @session: A #LightDMSession
  * 
  * Get the name for a session
@@ -211,7 +302,7 @@ lightdm_session_get_name (LightDMSession *session)
 }
 
 /**
- * lightdm_session_get_comment
+ * lightdm_session_get_comment:
  * @session: A #LightDMSession
  * 
  * Get the comment for a session
@@ -265,6 +356,18 @@ lightdm_session_get_property (GObject    *object,
     }
 }
 
+static void
+lightdm_session_finalize (GObject *object)
+{
+    LightDMSession *self = LIGHTDM_SESSION (object);
+    LightDMSessionPrivate *priv = GET_PRIVATE (self);
+
+    g_free (priv->key);
+    g_free (priv->type);
+    g_free (priv->name);
+    g_free (priv->comment);
+}
+
 static void
 lightdm_session_class_init (LightDMSessionClass *klass)
 {
@@ -274,6 +377,7 @@ lightdm_session_class_init (LightDMSessionClass *klass)
 
     object_class->set_property = lightdm_session_set_property;
     object_class->get_property = lightdm_session_get_property;
+    object_class->finalize = lightdm_session_finalize;
 
     g_object_class_install_property (object_class,
                                      PROP_KEY,