2 * Copyright (C) 2010 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 2 or version 3 of the License.
8 * See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
12 #include <gio/gdesktopappinfo.h>
14 #include "configuration.h"
15 #include "lightdm/session.h"
30 } LightDMSessionPrivate;
32 G_DEFINE_TYPE (LightDMSession, lightdm_session, G_TYPE_OBJECT);
34 #define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_SESSION, LightDMSessionPrivate)
36 static gboolean have_sessions = FALSE;
37 static GList *local_sessions = NULL;
38 static GList *remote_sessions = NULL;
41 compare_session (gconstpointer a, gconstpointer b)
43 LightDMSessionPrivate *priv_a = GET_PRIVATE (a);
44 LightDMSessionPrivate *priv_b = GET_PRIVATE (b);
45 return strcmp (priv_a->name, priv_b->name);
48 static LightDMSession *
49 load_session (GKeyFile *key_file, const gchar *key)
51 gchar *type, *domain, *name;
52 LightDMSession *session;
53 LightDMSessionPrivate *priv;
56 if (g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL) ||
57 g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, NULL))
60 type = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-LightDM-Session-Type", NULL);
64 #ifdef G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN
65 domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, NULL);
67 domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL);
69 name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, domain, NULL);
72 g_warning ("Ignoring session without name");
77 try_exec = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TRY_EXEC, domain, NULL);
82 full_path = g_find_program_in_path (try_exec);
94 session = g_object_new (LIGHTDM_TYPE_SESSION, NULL);
95 priv = GET_PRIVATE (session);
98 priv->key = g_strdup (key);
101 priv->type = g_strdup (type);
106 g_free (priv->comment);
107 priv->comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, domain, NULL);
109 priv->comment = g_strdup ("");
117 load_sessions_dir (GList *sessions, const gchar *sessions_dir)
120 GError *error = NULL;
122 directory = g_dir_open (sessions_dir, 0, &error);
123 if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
124 g_warning ("Failed to open sessions directory: %s", error->message);
125 g_clear_error (&error);
131 const gchar *filename;
136 filename = g_dir_read_name (directory);
137 if (filename == NULL)
140 if (!g_str_has_suffix (filename, ".desktop"))
143 path = g_build_filename (sessions_dir, filename, NULL);
145 key_file = g_key_file_new ();
146 result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
148 g_warning ("Failed to load session file %s: %s:", path, error->message);
149 g_clear_error (&error);
154 LightDMSession *session;
156 key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
157 session = load_session (key_file, key);
160 g_debug ("Loaded session %s (%s, %s)", path, GET_PRIVATE (session)->name, GET_PRIVATE (session)->comment);
161 sessions = g_list_insert_sorted (sessions, session, compare_session);
164 g_debug ("Ignoring session %s", path);
169 g_key_file_free (key_file);
172 g_dir_close (directory);
178 load_sessions (const gchar *sessions_dir)
180 GList *sessions = NULL;
184 dirs = g_strsplit (sessions_dir, ":", -1);
185 for (i = 0; dirs[i]; i++)
186 sessions = load_sessions_dir (sessions, dirs[i]);
193 update_sessions (void)
195 gchar *config_path = NULL;
197 gchar *remote_sessions_dir;
199 GError *error = NULL;
204 sessions_dir = g_strdup (SESSIONS_DIR);
205 remote_sessions_dir = g_strdup (REMOTE_SESSIONS_DIR);
207 /* Use session directory from configuration */
208 /* FIXME: This should be sent in the greeter connection */
209 config_path = g_build_filename (CONFIG_DIR, "lightdm.conf", NULL);
210 /* FIXME: This should load from lightdm.conf.d as well */
211 result = config_load_from_file (config_get_instance (), config_path, &error);
212 if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
213 g_warning ("Failed to open configuration file: %s", error->message);
214 g_clear_error (&error);
219 value = config_get_string (config_get_instance (), "LightDM", "sessions-directory");
222 g_free (sessions_dir);
223 sessions_dir = value;
226 value = config_get_string (config_get_instance (), "LightDM", "remote-sessions-directory");
229 g_free (remote_sessions_dir);
230 remote_sessions_dir = value;
233 g_free (config_path);
235 local_sessions = load_sessions (sessions_dir);
236 remote_sessions = load_sessions (remote_sessions_dir);
238 g_free (sessions_dir);
239 g_free (remote_sessions_dir);
241 have_sessions = TRUE;
245 * lightdm_get_sessions:
247 * Get the available sessions.
249 * Return value: (element-type LightDMSession) (transfer none): A list of #LightDMSession
252 lightdm_get_sessions (void)
255 return local_sessions;
259 * lightdm_get_remote_sessions:
261 * Get the available remote sessions.
263 * Return value: (element-type LightDMSession) (transfer none): A list of #LightDMSession
266 lightdm_get_remote_sessions (void)
269 return remote_sessions;
273 * lightdm_session_get_key:
274 * @session: A #LightDMSession
276 * Get the key for a session
278 * Return value: The session key
281 lightdm_session_get_key (LightDMSession *session)
283 g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
284 return GET_PRIVATE (session)->key;
288 * lightdm_session_get_session_type:
289 * @session: A #LightDMSession
291 * Get the type a session
293 * Return value: The session type, e.g. x or mir
296 lightdm_session_get_session_type (LightDMSession *session)
298 g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
299 return GET_PRIVATE (session)->type;
303 * lightdm_session_get_name:
304 * @session: A #LightDMSession
306 * Get the name for a session
308 * Return value: The session name
311 lightdm_session_get_name (LightDMSession *session)
313 g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
314 return GET_PRIVATE (session)->name;
318 * lightdm_session_get_comment:
319 * @session: A #LightDMSession
321 * Get the comment for a session
323 * Return value: The session comment
326 lightdm_session_get_comment (LightDMSession *session)
328 g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
329 return GET_PRIVATE (session)->comment;
333 lightdm_session_init (LightDMSession *session)
338 lightdm_session_set_property (GObject *object,
343 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
347 lightdm_session_get_property (GObject *object,
352 LightDMSession *self;
354 self = LIGHTDM_SESSION (object);
358 g_value_set_string (value, lightdm_session_get_key (self));
361 g_value_set_string (value, lightdm_session_get_name (self));
364 g_value_set_string (value, lightdm_session_get_comment (self));
367 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
373 lightdm_session_finalize (GObject *object)
375 LightDMSession *self = LIGHTDM_SESSION (object);
376 LightDMSessionPrivate *priv = GET_PRIVATE (self);
381 g_free (priv->comment);
385 lightdm_session_class_init (LightDMSessionClass *klass)
387 GObjectClass *object_class = G_OBJECT_CLASS (klass);
389 g_type_class_add_private (klass, sizeof (LightDMSessionPrivate));
391 object_class->set_property = lightdm_session_set_property;
392 object_class->get_property = lightdm_session_get_property;
393 object_class->finalize = lightdm_session_finalize;
395 g_object_class_install_property (object_class,
397 g_param_spec_string ("key",
402 g_object_class_install_property (object_class,
404 g_param_spec_string ("name",
409 g_object_class_install_property (object_class,
411 g_param_spec_string ("comment",