~brian-murray/lightdm/bug-967229

« back to all changes in this revision

Viewing changes to liblightdm-gobject/session.c

  • Committer: robert.ancell at canonical
  • Date: 2011-02-12 00:48:57 UTC
  • Revision ID: robert.ancell@canonical.com-20110212004857-45gpv6k0m0uf0liv
Update changelog link

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2010 Robert Ancell.
3
 
 * Author: Robert Ancell <robert.ancell@canonical.com>
4
 
 * 
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 3 of the License, or (at your option) any
8
 
 * later version. See http://www.gnu.org/copyleft/lgpl.html the full text of the
9
 
 * license.
10
 
 */
11
 
 
12
 
#include <string.h>
13
 
#include <gio/gdesktopappinfo.h>
14
 
 
15
 
#include "lightdm/session.h"
16
 
 
17
 
enum {
18
 
    PROP_0,
19
 
    PROP_KEY,
20
 
    PROP_NAME,
21
 
    PROP_COMMENT
22
 
};
23
 
 
24
 
typedef struct
25
 
{
26
 
    gchar *key;
27
 
    gchar *name;
28
 
    gchar *comment;
29
 
} LightDMSessionPrivate;
30
 
 
31
 
G_DEFINE_TYPE (LightDMSession, lightdm_session, G_TYPE_OBJECT);
32
 
 
33
 
#define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_SESSION, LightDMSessionPrivate)
34
 
 
35
 
static gboolean have_sessions = FALSE;
36
 
static GList *local_sessions = NULL;
37
 
static GList *remote_sessions = NULL;
38
 
 
39
 
static gint 
40
 
compare_session (gconstpointer a, gconstpointer b)
41
 
{
42
 
    LightDMSessionPrivate *priv_a = GET_PRIVATE (a);
43
 
    LightDMSessionPrivate *priv_b = GET_PRIVATE (b);
44
 
    return strcmp (priv_a->name, priv_b->name);
45
 
}
46
 
 
47
 
static LightDMSession *
48
 
load_session (GKeyFile *key_file, const gchar *key)
49
 
{
50
 
    gchar *domain, *name;
51
 
    LightDMSession *session;
52
 
    LightDMSessionPrivate *priv;
53
 
    gchar *try_exec;
54
 
  
55
 
    if (g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL) ||
56
 
        g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, NULL))
57
 
        return NULL;
58
 
 
59
 
#ifdef G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN
60
 
    domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, NULL);
61
 
#else
62
 
    domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL);
63
 
#endif
64
 
    name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, domain, NULL);
65
 
    if (!name)
66
 
    {
67
 
        g_warning ("Ignoring session without name");
68
 
        g_free (domain);
69
 
        return NULL;
70
 
    }
71
 
 
72
 
    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
 
    if (try_exec)
74
 
    {
75
 
        gchar *full_path;
76
 
 
77
 
        full_path = g_find_program_in_path (try_exec);
78
 
        g_free (try_exec);
79
 
 
80
 
        if (!full_path)
81
 
        {
82
 
            g_free (name);
83
 
            g_free (domain);
84
 
            return NULL;
85
 
        }
86
 
        g_free (full_path);
87
 
    }
88
 
 
89
 
    session = g_object_new (LIGHTDM_TYPE_SESSION, NULL);
90
 
    priv = GET_PRIVATE (session);
91
 
 
92
 
    g_free (priv->key);
93
 
    priv->key = g_strdup (key);
94
 
 
95
 
    g_free (priv->name);
96
 
    priv->name = name;
97
 
 
98
 
    g_free (priv->comment);
99
 
    priv->comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, domain, NULL);
100
 
    if (!priv->comment)
101
 
        priv->comment = g_strdup ("");
102
 
 
103
 
    g_free (domain);
104
 
 
105
 
    return session;
106
 
}
107
 
 
108
 
static GList *
109
 
load_sessions (const gchar *sessions_dir)
110
 
{
111
 
    GDir *directory;
112
 
    GList *sessions = NULL;
113
 
    GError *error = NULL;
114
 
 
115
 
    directory = g_dir_open (sessions_dir, 0, &error);
116
 
    if (error)
117
 
        g_warning ("Failed to open sessions directory: %s", error->message);
118
 
    g_clear_error (&error);
119
 
    if (!directory)
120
 
        return NULL;
121
 
 
122
 
    while (TRUE)
123
 
    {
124
 
        const gchar *filename;
125
 
        gchar *path;
126
 
        GKeyFile *key_file;
127
 
        gboolean result;
128
 
 
129
 
        filename = g_dir_read_name (directory);
130
 
        if (filename == NULL)
131
 
            break;
132
 
 
133
 
        if (!g_str_has_suffix (filename, ".desktop"))
134
 
            continue;
135
 
 
136
 
        path = g_build_filename (sessions_dir, filename, NULL);
137
 
 
138
 
        key_file = g_key_file_new ();
139
 
        result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
140
 
        if (error)
141
 
            g_warning ("Failed to load session file %s: %s:", path, error->message);
142
 
        g_clear_error (&error);
143
 
 
144
 
        if (result)
145
 
        {
146
 
            gchar *key;
147
 
            LightDMSession *session;
148
 
 
149
 
            key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
150
 
            session = load_session (key_file, key);
151
 
            if (session)
152
 
            {
153
 
                g_debug ("Loaded session %s (%s, %s)", path, GET_PRIVATE (session)->name, GET_PRIVATE (session)->comment);
154
 
                sessions = g_list_insert_sorted (sessions, session, compare_session);
155
 
            }
156
 
            else
157
 
                g_debug ("Ignoring session %s", path);
158
 
            g_free (key);
159
 
        }
160
 
 
161
 
        g_free (path);
162
 
        g_key_file_free (key_file);
163
 
    }
164
 
 
165
 
    g_dir_close (directory);
166
 
  
167
 
    return sessions;
168
 
}
169
 
 
170
 
static void
171
 
update_sessions (void)
172
 
{
173
 
    GKeyFile *config_key_file = NULL;
174
 
    gchar *config_path = NULL;
175
 
    gchar *xsessions_dir;
176
 
    gchar *remote_sessions_dir;
177
 
    gboolean result;
178
 
    GError *error = NULL;
179
 
 
180
 
    if (have_sessions)
181
 
        return;
182
 
 
183
 
    xsessions_dir = g_strdup (XSESSIONS_DIR);
184
 
    remote_sessions_dir = g_strdup (REMOTE_SESSIONS_DIR);
185
 
 
186
 
    /* Use session directory from configuration */
187
 
    /* FIXME: This should be sent in the greeter connection */
188
 
    config_path = g_build_filename (CONFIG_DIR, "lightdm.conf", NULL);
189
 
    config_key_file = g_key_file_new ();
190
 
    result = g_key_file_load_from_file (config_key_file, config_path, G_KEY_FILE_NONE, &error);
191
 
    if (error)
192
 
        g_warning ("Failed to open configuration file: %s", error->message);
193
 
    g_clear_error (&error);
194
 
    if (result)
195
 
    {
196
 
        gchar *value;
197
 
      
198
 
        value = g_key_file_get_string (config_key_file, "LightDM", "xsessions-directory", NULL);
199
 
        if (value)
200
 
        {
201
 
            g_free (xsessions_dir);
202
 
            xsessions_dir = value;
203
 
        }
204
 
 
205
 
        value = g_key_file_get_string (config_key_file, "LightDM", "remote-sessions-directory", NULL);
206
 
        if (value)
207
 
        {
208
 
            g_free (remote_sessions_dir);
209
 
            remote_sessions_dir = value;
210
 
        }
211
 
    }
212
 
    g_key_file_free (config_key_file);
213
 
    g_free (config_path);
214
 
 
215
 
    local_sessions = load_sessions (xsessions_dir);
216
 
    remote_sessions = load_sessions (remote_sessions_dir);
217
 
 
218
 
    g_free (xsessions_dir);
219
 
    g_free (remote_sessions_dir);
220
 
 
221
 
    have_sessions = TRUE;
222
 
}
223
 
 
224
 
/**
225
 
 * lightdm_get_sessions:
226
 
 *
227
 
 * Get the available sessions.
228
 
 *
229
 
 * Return value: (element-type LightDMSession) (transfer none): A list of #LightDMSession
230
 
 **/
231
 
GList *
232
 
lightdm_get_sessions (void)
233
 
{
234
 
    update_sessions ();
235
 
    return local_sessions;
236
 
}
237
 
 
238
 
/**
239
 
 * lightdm_get_remote_sessions:
240
 
 *
241
 
 * Get the available remote sessions.
242
 
 *
243
 
 * Return value: (element-type LightDMSession) (transfer none): A list of #LightDMSession
244
 
 **/
245
 
GList *
246
 
lightdm_get_remote_sessions (void)
247
 
{
248
 
    update_sessions ();
249
 
    return remote_sessions;
250
 
}
251
 
 
252
 
/**
253
 
 * lightdm_session_get_key:
254
 
 * @session: A #LightDMSession
255
 
 * 
256
 
 * Get the key for a session
257
 
 * 
258
 
 * Return value: The session key
259
 
 **/
260
 
const gchar *
261
 
lightdm_session_get_key (LightDMSession *session)
262
 
{
263
 
    g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
264
 
    return GET_PRIVATE (session)->key;
265
 
}
266
 
 
267
 
/**
268
 
 * lightdm_session_get_name:
269
 
 * @session: A #LightDMSession
270
 
 * 
271
 
 * Get the name for a session
272
 
 * 
273
 
 * Return value: The session name
274
 
 **/
275
 
const gchar *
276
 
lightdm_session_get_name (LightDMSession *session)
277
 
{
278
 
    g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
279
 
    return GET_PRIVATE (session)->name;
280
 
}
281
 
 
282
 
/**
283
 
 * lightdm_session_get_comment:
284
 
 * @session: A #LightDMSession
285
 
 * 
286
 
 * Get the comment for a session
287
 
 * 
288
 
 * Return value: The session comment
289
 
 **/
290
 
const gchar *
291
 
lightdm_session_get_comment (LightDMSession *session)
292
 
{
293
 
    g_return_val_if_fail (LIGHTDM_IS_SESSION (session), NULL);
294
 
    return GET_PRIVATE (session)->comment;
295
 
}
296
 
 
297
 
static void
298
 
lightdm_session_init (LightDMSession *session)
299
 
{
300
 
}
301
 
 
302
 
static void
303
 
lightdm_session_set_property (GObject      *object,
304
 
                          guint         prop_id,
305
 
                          const GValue *value,
306
 
                          GParamSpec   *pspec)
307
 
{
308
 
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
309
 
}
310
 
 
311
 
static void
312
 
lightdm_session_get_property (GObject    *object,
313
 
                          guint       prop_id,
314
 
                          GValue     *value,
315
 
                          GParamSpec *pspec)
316
 
{
317
 
    LightDMSession *self;
318
 
 
319
 
    self = LIGHTDM_SESSION (object);
320
 
 
321
 
    switch (prop_id) {
322
 
    case PROP_KEY:
323
 
        g_value_set_string (value, lightdm_session_get_key (self));
324
 
        break;
325
 
    case PROP_NAME:
326
 
        g_value_set_string (value, lightdm_session_get_name (self));
327
 
        break;
328
 
    case PROP_COMMENT:
329
 
        g_value_set_string (value, lightdm_session_get_comment (self));
330
 
        break;
331
 
    default:
332
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
333
 
        break;
334
 
    }
335
 
}
336
 
 
337
 
static void
338
 
lightdm_session_finalize (GObject *object)
339
 
{
340
 
    LightDMSession *self = LIGHTDM_SESSION (object);
341
 
    LightDMSessionPrivate *priv = GET_PRIVATE (self);
342
 
 
343
 
    g_free (priv->key);
344
 
    g_free (priv->name);
345
 
    g_free (priv->comment);
346
 
}
347
 
 
348
 
static void
349
 
lightdm_session_class_init (LightDMSessionClass *klass)
350
 
{
351
 
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
352
 
  
353
 
    g_type_class_add_private (klass, sizeof (LightDMSessionPrivate));
354
 
 
355
 
    object_class->set_property = lightdm_session_set_property;
356
 
    object_class->get_property = lightdm_session_get_property;
357
 
    object_class->finalize = lightdm_session_finalize;
358
 
 
359
 
    g_object_class_install_property (object_class,
360
 
                                     PROP_KEY,
361
 
                                     g_param_spec_string ("key",
362
 
                                                          "key",
363
 
                                                          "Session key",
364
 
                                                          NULL,
365
 
                                                          G_PARAM_READABLE));
366
 
    g_object_class_install_property (object_class,
367
 
                                     PROP_NAME,
368
 
                                     g_param_spec_string ("name",
369
 
                                                          "name",
370
 
                                                          "Session name",
371
 
                                                          NULL,
372
 
                                                          G_PARAM_READABLE));
373
 
    g_object_class_install_property (object_class,
374
 
                                     PROP_COMMENT,
375
 
                                     g_param_spec_string ("comment",
376
 
                                                          "comment",
377
 
                                                          "Session comment",
378
 
                                                          NULL,
379
 
                                                          G_PARAM_READABLE));
380
 
}