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"
23 struct _LightDMSession
31 G_DEFINE_TYPE (LightDMSession, lightdm_session, G_TYPE_OBJECT);
33 static gboolean have_sessions = FALSE;
34 static GList *local_sessions = NULL;
35 static GList *remote_sessions = NULL;
38 compare_session (gconstpointer a, gconstpointer b)
40 const LightDMSession *sa = a, *sb = b;
41 return strcmp (sa->name, sb->name);
44 static LightDMSession *
45 load_session (GKeyFile *key_file, const gchar *key, const gchar *default_type)
47 gchar *domain, *name, *type;
48 LightDMSession *session;
51 if (g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL) ||
52 g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, NULL))
55 #ifdef G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN
56 domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, NULL);
58 domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL);
60 name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, domain, NULL);
63 g_warning ("Ignoring session without name");
68 try_exec = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TRY_EXEC, domain, NULL);
73 full_path = g_find_program_in_path (try_exec);
85 type = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-LightDM-Session-Type", NULL);
87 type = strdup (default_type);
89 session = g_object_new (LIGHTDM_TYPE_SESSION, NULL);
91 g_free (session->key);
92 session->key = g_strdup (key);
94 g_free (session->type);
97 g_free (session->name);
100 g_free (session->comment);
101 session->comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, domain, NULL);
102 if (!session->comment)
103 session->comment = g_strdup ("");
111 load_sessions_dir (GList *sessions, const gchar *sessions_dir, const gchar *default_type)
114 GError *error = NULL;
116 directory = g_dir_open (sessions_dir, 0, &error);
117 if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
118 g_warning ("Failed to open sessions directory: %s", error->message);
119 g_clear_error (&error);
125 const gchar *filename;
130 filename = g_dir_read_name (directory);
131 if (filename == NULL)
134 if (!g_str_has_suffix (filename, ".desktop"))
137 path = g_build_filename (sessions_dir, filename, NULL);
139 key_file = g_key_file_new ();
140 result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
142 g_warning ("Failed to load session file %s: %s:", path, error->message);
143 g_clear_error (&error);
148 LightDMSession *session;
150 key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
151 session = load_session (key_file, key, default_type);
154 g_debug ("Loaded session %s (%s, %s)", path, session->name, session->comment);
155 sessions = g_list_insert_sorted (sessions, session, compare_session);
158 g_debug ("Ignoring session %s", path);
163 g_key_file_free (key_file);
166 g_dir_close (directory);
172 load_sessions (const gchar *sessions_dir)
174 GList *sessions = NULL;
178 dirs = g_strsplit (sessions_dir, ":", -1);
179 for (i = 0; dirs[i]; i++)
181 const gchar *default_type = "x";
183 if (strcmp (dirs[i], WAYLAND_SESSIONS_DIR) == 0)
184 default_type = "wayland";
186 sessions = load_sessions_dir (sessions, dirs[i], default_type);
195 update_sessions (void)
198 gchar *remote_sessions_dir;
204 sessions_dir = g_strdup (SESSIONS_DIR);
205 remote_sessions_dir = g_strdup (REMOTE_SESSIONS_DIR);
207 /* Use session directory from configuration */
208 config_load_from_standard_locations (config_get_instance (), NULL, NULL);
210 value = config_get_string (config_get_instance (), "LightDM", "sessions-directory");
213 g_free (sessions_dir);
214 sessions_dir = value;
217 value = config_get_string (config_get_instance (), "LightDM", "remote-sessions-directory");
220 g_free (remote_sessions_dir);
221 remote_sessions_dir = value;
224 local_sessions = load_sessions (sessions_dir);
225 remote_sessions = load_sessions (remote_sessions_dir);
227 g_free (sessions_dir);
228 g_free (remote_sessions_dir);
230 have_sessions = TRUE;
234 * lightdm_get_sessions:
236 * Get the available sessions.
238 * Return value: (element-type LightDMSession) (transfer none): A list of #LightDMSession
241 lightdm_get_sessions (void)
244 return local_sessions;
248 * lightdm_get_remote_sessions:
250 * Get the available remote sessions.
252 * Return value: (element-type LightDMSession) (transfer none): A list of #LightDMSession
255 lightdm_get_remote_sessions (void)
258 return remote_sessions;
262 * lightdm_session_get_key:
263 * @session: A #LightDMSession
265 * Get the key for a session
267 * Return value: The session key
270 lightdm_session_get_key (LightDMSession *session)
272 g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
277 * lightdm_session_get_session_type:
278 * @session: A #LightDMSession
280 * Get the type a session
282 * Return value: The session type, e.g. x or mir
285 lightdm_session_get_session_type (LightDMSession *session)
287 g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
288 return session->type;
292 * lightdm_session_get_name:
293 * @session: A #LightDMSession
295 * Get the name for a session
297 * Return value: The session name
300 lightdm_session_get_name (LightDMSession *session)
302 g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
303 return session->name;
307 * lightdm_session_get_comment:
308 * @session: A #LightDMSession
310 * Get the comment for a session
312 * Return value: The session comment
315 lightdm_session_get_comment (LightDMSession *session)
317 g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
318 return session->comment;
322 lightdm_session_init (LightDMSession *session)
327 lightdm_session_set_property (GObject *object,
332 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
336 lightdm_session_get_property (GObject *object,
341 LightDMSession *self;
343 self = LIGHTDM_SESSION (object);
347 g_value_set_string (value, lightdm_session_get_key (self));
350 g_value_set_string (value, lightdm_session_get_name (self));
353 g_value_set_string (value, lightdm_session_get_comment (self));
356 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
362 lightdm_session_finalize (GObject *object)
364 LightDMSession *self = LIGHTDM_SESSION (object);
369 g_free (self->comment);
373 lightdm_session_class_init (LightDMSessionClass *klass)
375 GObjectClass *object_class = G_OBJECT_CLASS (klass);
377 object_class->set_property = lightdm_session_set_property;
378 object_class->get_property = lightdm_session_get_property;
379 object_class->finalize = lightdm_session_finalize;
381 g_object_class_install_property (object_class,
383 g_param_spec_string ("key",
388 g_object_class_install_property (object_class,
390 g_param_spec_string ("name",
395 g_object_class_install_property (object_class,
397 g_param_spec_string ("comment",