]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - src/session-manager.c
3e1e83c34ed360445d08f827db3dea7d63694778
[sojka/lightdm.git] / src / session-manager.c
1 /*
2  * Copyright (C) 2010 Robert Ancell.
3  * Author: Robert Ancell <robert.ancell@canonical.com>
4  * 
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
9  * license.
10  */
11
12 #include <string.h>
13
14 #include "session-manager.h"
15 #include "session-manager-glue.h"
16
17 struct SessionManagerPrivate
18 {
19     gboolean sessions_loaded;
20     GList *sessions;
21 };
22
23 G_DEFINE_TYPE (SessionManager, session_manager, G_TYPE_OBJECT);
24
25 SessionManager *
26 session_manager_new (void)
27 {
28     return g_object_new (SESSION_MANAGER_TYPE, NULL);
29 }
30
31 static void
32 session_free (Session *session)
33 {
34     g_free (session->key);  
35     g_free (session->name);
36     g_free (session->comment);
37     g_free (session->exec);
38     g_free (session);
39 }
40
41 static Session *
42 load_session (GKeyFile *key_file, const gchar *key, GError **error)
43 {
44     Session *session;
45   
46     session = g_malloc0 (sizeof (Session));
47   
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);
50     if (!session->name)
51     {
52         session_free (session);
53         return NULL;
54     }
55
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)
58     {
59         session_free (session);
60         return NULL;
61     }
62
63     session->exec = g_key_file_get_value(key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, error);
64     if (!session->exec)
65     {
66         session_free (session);
67         return NULL;
68     }
69
70     return session;
71 }
72
73 static void
74 load_sessions (SessionManager *manager)
75 {
76     GDir *directory;
77     GError *error = NULL;
78     GKeyFile *key_file;
79
80     if (manager->priv->sessions_loaded)
81         return;
82
83     directory = g_dir_open (XSESSIONS_DIR, 0, &error);
84     if (!directory)
85         g_warning ("Failed to open sessions directory: %s", error->message);
86     g_clear_error (&error);
87     if (!directory)
88         return;
89
90     key_file = g_key_file_new ();
91     while (TRUE)
92     {
93         const gchar *filename;
94         gchar *key, *path;
95         gboolean result;
96         Session *session;
97
98         filename = g_dir_read_name (directory);
99         if (filename == NULL)
100             break;
101
102         if (!g_str_has_suffix (filename, ".desktop"))
103             continue;
104
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);
108
109         result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
110         if (!result)
111             g_warning ("Failed to load session file %s: %s:", path, error->message);
112         g_clear_error (&error);
113
114         if (result && !g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL))
115         {
116             session = load_session (key_file, key, &error);
117             if (session)
118             {
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);
121             }
122             else
123                 g_warning ("Invalid session %s: %s", path, error->message);
124             g_clear_error (&error);
125         }
126
127         g_free (key);      
128         g_free (path);
129     }
130
131     g_dir_close (directory);
132     g_key_file_free (key_file);
133
134     manager->priv->sessions_loaded = TRUE;
135 }
136
137 Session *
138 session_manager_get_session (SessionManager *manager, const gchar *key)
139 {
140     GList *link;
141
142     load_sessions (manager);
143
144     for (link = manager->priv->sessions; link; link = link->next)
145     {
146         Session *session = link->data;
147         if (g_str_equal (session->key, key))
148             return session;
149     }
150
151     return NULL;
152 }
153
154 #define TYPE_SESSION dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID)
155
156 gboolean
157 session_manager_get_sessions (SessionManager *manager, GPtrArray **sessions, GError *error)
158 {
159     GList *link;
160
161     load_sessions (manager);
162
163     *sessions = g_ptr_array_sized_new (g_list_length (manager->priv->sessions));
164     for (link = manager->priv->sessions; link; link = link->next)
165     {
166         Session *session = link->data;
167         GValue value = { 0 };
168
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));
173     }
174
175     return TRUE;
176 }
177
178 static void
179 session_manager_init (SessionManager *manager)
180 {
181     manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, SESSION_MANAGER_TYPE, SessionManagerPrivate);
182 }
183
184 static void
185 session_manager_class_init (SessionManagerClass *klass)
186 {
187     g_type_class_add_private (klass, sizeof (SessionManagerPrivate));
188
189     dbus_g_object_type_install_info (SESSION_MANAGER_TYPE, &dbus_glib_session_manager_object_info);
190 }