]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - src/session-manager.c
Use GDesktopAppInfo for session .desktop files
[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 #include <gio/gdesktopappinfo.h>
14
15 #include "session-manager.h"
16 #include "session-manager-glue.h"
17
18 struct SessionManagerPrivate
19 {
20     gboolean sessions_loaded;
21     GList *sessions;
22 };
23
24 G_DEFINE_TYPE (SessionManager, session_manager, G_TYPE_OBJECT);
25
26 SessionManager *
27 session_manager_new (void)
28 {
29     return g_object_new (SESSION_MANAGER_TYPE, NULL);
30 }
31
32 static void
33 session_free (Session *session)
34 {
35     g_free (session->key);  
36     g_free (session->name);
37     g_free (session->comment);
38     g_free (session->exec);
39     g_free (session);
40 }
41
42 static void
43 load_sessions (SessionManager *manager)
44 {
45     GDir *directory;
46     GError *error = NULL;
47     GKeyFile *key_file;
48
49     if (manager->priv->sessions_loaded)
50         return;
51
52     directory = g_dir_open (XSESSIONS_DIR, 0, &error);
53     if (!directory)
54         g_warning ("Failed to open sessions directory: %s", error->message);
55     g_clear_error (&error);
56     if (!directory)
57         return;
58
59     key_file = g_key_file_new ();
60     while (TRUE)
61     {
62         const gchar *filename;
63         gchar *key, *path;
64         gboolean result;
65
66         filename = g_dir_read_name (directory);
67         if (filename == NULL)
68             break;
69
70         if (!g_str_has_suffix (filename, ".desktop"))
71             continue;
72
73         key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
74         path = g_build_filename (XSESSIONS_DIR, filename, NULL);
75         g_debug ("Loading session %s", path);
76
77         result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
78         if (!result)
79             g_warning ("Failed to load session file %s: %s:", path, error->message);
80         g_clear_error (&error);
81
82         if (result)
83         {
84             GDesktopAppInfo *desktop_file;
85
86             desktop_file = g_desktop_app_info_new_from_keyfile (key_file);
87
88             if (g_app_info_should_show (G_APP_INFO (desktop_file)))
89             {
90                 Session *session;
91
92                 session = g_malloc0 (sizeof (Session)); 
93                 session->key = g_strdup (key);
94                 session->name = g_strdup (g_app_info_get_name (G_APP_INFO (desktop_file)));
95                 session->comment = g_strdup (g_app_info_get_display_name (G_APP_INFO (desktop_file)));
96                 session->exec = g_strdup (g_app_info_get_executable (G_APP_INFO (desktop_file)));
97
98                 if (session->name && session->comment && session->exec)
99                 {
100                     g_debug ("Loaded session %s (%s, %s)", session->key, session->name, session->comment);
101                     manager->priv->sessions = g_list_append (manager->priv->sessions, session);
102                 }
103                 else
104                 {
105                     g_warning ("Invalid session %s: %s", path, error->message);
106                     session_free (session);
107                 }
108                 g_clear_error (&error);
109             }                
110         }
111
112         g_free (key);      
113         g_free (path);
114     }
115
116     g_dir_close (directory);
117     g_key_file_free (key_file);
118
119     manager->priv->sessions_loaded = TRUE;
120 }
121
122 Session *
123 session_manager_get_session (SessionManager *manager, const gchar *key)
124 {
125     GList *link;
126
127     load_sessions (manager);
128
129     for (link = manager->priv->sessions; link; link = link->next)
130     {
131         Session *session = link->data;
132         if (g_str_equal (session->key, key))
133             return session;
134     }
135
136     return NULL;
137 }
138
139 #define TYPE_SESSION dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID)
140
141 gboolean
142 session_manager_get_sessions (SessionManager *manager, GPtrArray **sessions, GError *error)
143 {
144     GList *link;
145
146     load_sessions (manager);
147
148     *sessions = g_ptr_array_sized_new (g_list_length (manager->priv->sessions));
149     for (link = manager->priv->sessions; link; link = link->next)
150     {
151         Session *session = link->data;
152         GValue value = { 0 };
153
154         g_value_init (&value, TYPE_SESSION);
155         g_value_take_boxed (&value, dbus_g_type_specialized_construct (TYPE_SESSION));
156         dbus_g_type_struct_set (&value, 0, session->key, 1, session->name, 2, session->comment, G_MAXUINT);
157         g_ptr_array_add (*sessions, g_value_get_boxed (&value));
158     }
159
160     return TRUE;
161 }
162
163 static void
164 session_manager_init (SessionManager *manager)
165 {
166     manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, SESSION_MANAGER_TYPE, SessionManagerPrivate);
167 }
168
169 static void
170 session_manager_class_init (SessionManagerClass *klass)
171 {
172     g_type_class_add_private (klass, sizeof (SessionManagerPrivate));
173
174     dbus_g_object_type_install_info (SESSION_MANAGER_TYPE, &dbus_glib_session_manager_object_info);
175 }