2 * Copyright (C) 2010 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
5 * This program is free software: you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option) any later
8 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
14 #include "session-manager.h"
15 #include "session-manager-glue.h"
17 struct SessionManagerPrivate
19 gboolean sessions_loaded;
23 G_DEFINE_TYPE (SessionManager, session_manager, G_TYPE_OBJECT);
26 session_manager_new (void)
28 return g_object_new (SESSION_MANAGER_TYPE, NULL);
32 session_free (Session *session)
34 g_free (session->key);
35 g_free (session->name);
36 g_free (session->comment);
37 g_free (session->exec);
42 load_session (GKeyFile *key_file, const gchar *key, GError **error)
46 session = g_malloc0 (sizeof (Session));
48 session->key = g_strdup (key);
49 session->name = g_key_file_get_locale_string(key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, error);
52 session_free (session);
56 session->comment = g_key_file_get_locale_string(key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, error);
57 if (!session->comment)
59 session_free (session);
63 session->exec = g_key_file_get_value(key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, error);
66 session_free (session);
74 load_sessions (SessionManager *manager)
80 if (manager->priv->sessions_loaded)
83 directory = g_dir_open (XSESSIONS_DIR, 0, &error);
85 g_warning ("Failed to open sessions directory: %s", error->message);
86 g_clear_error (&error);
90 key_file = g_key_file_new ();
93 const gchar *filename;
98 filename = g_dir_read_name (directory);
102 if (!g_str_has_suffix (filename, ".desktop"))
105 key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
106 path = g_build_filename (XSESSIONS_DIR, filename, NULL);
107 g_debug ("Loading session %s", path);
109 result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
111 g_warning ("Failed to load session file %s: %s:", path, error->message);
112 g_clear_error (&error);
114 if (result && !g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL))
116 session = load_session (key_file, key, &error);
119 g_debug ("Loaded session %s (%s, %s)", session->key, session->name, session->comment);
120 manager->priv->sessions = g_list_append (manager->priv->sessions, session);
123 g_warning ("Invalid session %s: %s", path, error->message);
124 g_clear_error (&error);
131 g_dir_close (directory);
132 g_key_file_free (key_file);
134 manager->priv->sessions_loaded = TRUE;
138 session_manager_get_session (SessionManager *manager, const gchar *key)
142 load_sessions (manager);
144 for (link = manager->priv->sessions; link; link = link->next)
146 Session *session = link->data;
147 if (g_str_equal (session->key, key))
154 #define TYPE_SESSION dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID)
157 session_manager_get_sessions (SessionManager *manager, GPtrArray **sessions, GError *error)
161 load_sessions (manager);
163 *sessions = g_ptr_array_sized_new (g_list_length (manager->priv->sessions));
164 for (link = manager->priv->sessions; link; link = link->next)
166 Session *session = link->data;
167 GValue value = { 0 };
169 g_value_init (&value, TYPE_SESSION);
170 g_value_take_boxed (&value, dbus_g_type_specialized_construct (TYPE_SESSION));
171 dbus_g_type_struct_set (&value, 0, session->key, 1, session->name, 2, session->comment, G_MAXUINT);
172 g_ptr_array_add (*sessions, g_value_get_boxed (&value));
179 session_manager_init (SessionManager *manager)
181 manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, SESSION_MANAGER_TYPE, SessionManagerPrivate);
185 session_manager_class_init (SessionManagerClass *klass)
187 g_type_class_add_private (klass, sizeof (SessionManagerPrivate));
189 dbus_g_object_type_install_info (SESSION_MANAGER_TYPE, &dbus_glib_session_manager_object_info);