~darkxst/ubuntu/raring/gdm/lp982889

« back to all changes in this revision

Viewing changes to utils/gdmflexiserver.c

  • Committer: Package Import Robot
  • Author(s): Tim Lunn, Jeremy Bicha, Tim Lunn
  • Date: 2012-10-16 15:18:58 UTC
  • mfrom: (1.4.54)
  • Revision ID: package-import@ubuntu.com-20121016151858-dqip6h63lo0xj5hy
Tags: 3.6.1-0ubuntu1
[ Jeremy Bicha ]
* New upstream release (LP: #1067492)
  - Fix "Switch User" not working in Unity or GNOME Classic,
    thanks Tim! (LP: #1057841)
* debian/patches/ubuntu_user_switching.patch:
  - Dropped, applied in new version

[ Tim Lunn ]
* debian/gdm.prerm:
  - Do not try to stop gdm service if its not running. (LP: #1055359)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
18
 *
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
 
 
23
#include <stdlib.h>
 
24
#include <stdio.h>
 
25
#include <unistd.h>
 
26
#include <string.h>
 
27
#include <locale.h>
 
28
 
 
29
#include <glib/gi18n.h>
 
30
#include <gtk/gtk.h>
 
31
 
 
32
#ifdef WITH_SYSTEMD
 
33
#include <systemd/sd-daemon.h>
 
34
#include <systemd/sd-login.h>
 
35
#endif
 
36
 
 
37
#define GDM_DBUS_NAME                            "org.gnome.DisplayManager"
 
38
#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH      "/org/gnome/DisplayManager/LocalDisplayFactory"
 
39
#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE "org.gnome.DisplayManager.LocalDisplayFactory"
 
40
 
 
41
#ifdef WITH_CONSOLE_KIT
 
42
#define CK_NAME      "org.freedesktop.ConsoleKit"
 
43
#define CK_PATH      "/org/freedesktop/ConsoleKit"
 
44
#define CK_INTERFACE "org.freedesktop.ConsoleKit"
 
45
 
 
46
#define CK_MANAGER_PATH      "/org/freedesktop/ConsoleKit/Manager"
 
47
#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
 
48
#define CK_SEAT_INTERFACE    "org.freedesktop.ConsoleKit.Seat"
 
49
#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
 
50
#endif
 
51
 
 
52
static const char *send_command     = NULL;
 
53
static gboolean    use_xnest        = FALSE;
 
54
static gboolean    no_lock          = FALSE;
 
55
static gboolean    debug_in         = FALSE;
 
56
static gboolean    authenticate     = FALSE;
 
57
static gboolean    startnew         = FALSE;
 
58
static gboolean    monte_carlo_pi   = FALSE;
 
59
static gboolean    show_version     = FALSE;
 
60
static char      **args_remaining   = NULL;
 
61
 
 
62
/* Keep all config options for compatibility even if they are noops */
 
63
GOptionEntry options [] = {
 
64
        { "command", 'c', 0, G_OPTION_ARG_STRING, &send_command, "Only the VERSION command is supported", "COMMAND" },
 
65
        { "xnest", 'n', 0, G_OPTION_ARG_NONE, &use_xnest, "Ignored — retained for compatibility", NULL },
 
66
        { "no-lock", 'l', 0, G_OPTION_ARG_NONE, &no_lock, "Ignored — retained for compatibility", NULL },
 
67
        { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug_in, "Debugging output", NULL },
 
68
        { "authenticate", 'a', 0, G_OPTION_ARG_NONE, &authenticate, "Ignored — retained for compatibility", NULL },
 
69
        { "startnew", 's', 0, G_OPTION_ARG_NONE, &startnew, "Ignored — retained for compatibility", NULL },
 
70
        { "monte-carlo-pi", 0, 0, G_OPTION_ARG_NONE, &monte_carlo_pi, NULL, NULL },
 
71
        { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Version of this application", NULL },
 
72
        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args_remaining, NULL, NULL },
 
73
        { NULL }
 
74
};
 
75
 
 
76
#define GDM_FLEXISERVER_ERROR gdm_flexiserver_error_quark ()
 
77
static GQuark
 
78
gdm_flexiserver_error_quark (void)
 
79
{
 
80
        static GQuark ret = 0;
 
81
        if (ret == 0) {
 
82
                ret = g_quark_from_static_string ("gdm_flexiserver_error");
 
83
        }
 
84
 
 
85
        return ret;
 
86
}
 
87
 
 
88
static gboolean
 
89
is_program_in_path (const char *program)
 
90
{
 
91
        char *tmp = g_find_program_in_path (program);
 
92
        if (tmp != NULL) {
 
93
                g_free (tmp);
 
94
                return TRUE;
 
95
        } else {
 
96
                return FALSE;
 
97
        }
 
98
}
 
99
 
 
100
static void
 
101
maybe_lock_screen (void)
 
102
{
 
103
        gboolean   use_gscreensaver = FALSE;
 
104
        GError    *error            = NULL;
 
105
        char      *command;
 
106
 
 
107
        if (is_program_in_path ("gnome-screensaver-command")) {
 
108
                use_gscreensaver = TRUE;
 
109
        } else if (! is_program_in_path ("xscreensaver-command")) {
 
110
                return;
 
111
        }
 
112
 
 
113
        if (use_gscreensaver) {
 
114
                command = g_strdup ("gnome-screensaver-command --lock");
 
115
        } else {
 
116
                command = g_strdup ("xscreensaver-command -lock");
 
117
        }
 
118
 
 
119
        if (! g_spawn_command_line_async (command, &error)) {
 
120
                g_warning ("Cannot lock screen: %s", error->message);
 
121
                g_error_free (error);
 
122
        }
 
123
 
 
124
        g_free (command);
 
125
 
 
126
        if (! use_gscreensaver) {
 
127
                command = g_strdup ("xscreensaver-command -throttle");
 
128
                if (! g_spawn_command_line_async (command, &error)) {
 
129
                        g_warning ("Cannot disable screensaver engines: %s", error->message);
 
130
                        g_error_free (error);
 
131
                }
 
132
 
 
133
                g_free (command);
 
134
        }
 
135
}
 
136
 
 
137
static void
 
138
calc_pi (void)
 
139
{
 
140
        unsigned long n = 0, h = 0;
 
141
        double x, y;
 
142
        printf ("\n");
 
143
        for (;;) {
 
144
                x = g_random_double ();
 
145
                y = g_random_double ();
 
146
                if (x*x + y*y <= 1)
 
147
                        h++;
 
148
                n++;
 
149
                if ( ! (n & 0xfff))
 
150
                        printf ("pi ~~ %1.10f\t(%lu/%lu * 4) iteration: %lu \r",
 
151
                                ((double)h)/(double)n * 4.0, h, n, n);
 
152
        }
 
153
}
 
154
 
 
155
static gboolean
 
156
create_transient_display (GDBusConnection *connection,
 
157
                          GError         **error)
 
158
{
 
159
        GError *local_error = NULL;
 
160
        GVariant *reply;
 
161
        const char     *value;
 
162
 
 
163
        reply = g_dbus_connection_call_sync (connection,
 
164
                                             GDM_DBUS_NAME,
 
165
                                             GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH,
 
166
                                             GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE,
 
167
                                             "CreateTransientDisplay",
 
168
                                             NULL, /* parameters */
 
169
                                             G_VARIANT_TYPE ("(o)"),
 
170
                                             G_DBUS_CALL_FLAGS_NONE,
 
171
                                             -1,
 
172
                                             NULL, &local_error);
 
173
        if (reply == NULL) {
 
174
                g_warning ("Unable to create transient display: %s", local_error->message);
 
175
                g_propagate_error (error, local_error);
 
176
                return FALSE;
 
177
        }
 
178
 
 
179
        g_variant_get (reply, "(&o)", &value);
 
180
        g_debug ("Started %s", value);
 
181
 
 
182
        g_variant_unref (reply);
 
183
        return TRUE;
 
184
}
 
185
 
 
186
#ifdef WITH_CONSOLE_KIT
 
187
 
 
188
static gboolean
 
189
get_current_session_id (GDBusConnection  *connection,
 
190
                        char            **session_id)
 
191
{
 
192
        GError *local_error = NULL;
 
193
        GVariant *reply;
 
194
 
 
195
        reply = g_dbus_connection_call_sync (connection,
 
196
                                             CK_NAME,
 
197
                                             CK_MANAGER_PATH,
 
198
                                             CK_MANAGER_INTERFACE,
 
199
                                             "GetCurrentSession",
 
200
                                             NULL, /* parameters */
 
201
                                             G_VARIANT_TYPE ("(o)"),
 
202
                                             G_DBUS_CALL_FLAGS_NONE,
 
203
                                             -1,
 
204
                                             NULL, &local_error);
 
205
        if (reply == NULL) {
 
206
                g_warning ("Unable to determine session: %s", local_error->message);
 
207
                g_error_free (local_error);
 
208
                return FALSE;
 
209
        }
 
210
 
 
211
        g_variant_get (reply, "(o)", session_id);
 
212
        g_variant_unref (reply);
 
213
 
 
214
        return TRUE;
 
215
}
 
216
 
 
217
static gboolean
 
218
get_seat_id_for_session (GDBusConnection  *connection,
 
219
                         const char       *session_id,
 
220
                         char            **seat_id)
 
221
{
 
222
        GError *local_error = NULL;
 
223
        GVariant *reply;
 
224
 
 
225
        reply = g_dbus_connection_call_sync (connection,
 
226
                                             CK_NAME,
 
227
                                             session_id,
 
228
                                             CK_SESSION_INTERFACE,
 
229
                                             "GetSeatId",
 
230
                                             NULL, /* parameters */
 
231
                                             G_VARIANT_TYPE ("(o)"),
 
232
                                             G_DBUS_CALL_FLAGS_NONE,
 
233
                                             -1,
 
234
                                             NULL, &local_error);
 
235
        if (reply == NULL) {
 
236
                g_warning ("Unable to determine seat: %s", local_error->message);
 
237
                g_error_free (local_error);
 
238
                return FALSE;
 
239
        }
 
240
 
 
241
        g_variant_get (reply, "(o)", seat_id);
 
242
        g_variant_unref (reply);
 
243
 
 
244
        return TRUE;
 
245
}
 
246
 
 
247
static char *
 
248
get_current_seat_id (GDBusConnection *connection)
 
249
{
 
250
        gboolean res;
 
251
        char    *session_id;
 
252
        char    *seat_id;
 
253
 
 
254
        session_id = NULL;
 
255
        seat_id = NULL;
 
256
 
 
257
        res = get_current_session_id (connection, &session_id);
 
258
        if (res) {
 
259
                res = get_seat_id_for_session (connection, session_id, &seat_id);
 
260
        }
 
261
        g_free (session_id);
 
262
 
 
263
        return seat_id;
 
264
}
 
265
 
 
266
static gboolean
 
267
activate_session_id_for_ck (GDBusConnection *connection,
 
268
                            const char      *seat_id,
 
269
                            const char      *session_id)
 
270
{
 
271
        GError *local_error = NULL;
 
272
        GVariant *reply;
 
273
 
 
274
        reply = g_dbus_connection_call_sync (connection,
 
275
                                             CK_NAME,
 
276
                                             seat_id,
 
277
                                             CK_SEAT_INTERFACE,
 
278
                                             "ActivateSession",
 
279
                                             g_variant_new ("(o)", session_id),
 
280
                                             NULL,
 
281
                                             G_DBUS_CALL_FLAGS_NONE,
 
282
                                             -1,
 
283
                                             NULL, &local_error);
 
284
        if (reply == NULL) {
 
285
                g_warning ("Unable to activate session: %s", local_error->message);
 
286
                g_error_free (local_error);
 
287
                return FALSE;
 
288
        }
 
289
 
 
290
        g_variant_unref (reply);
 
291
 
 
292
        return TRUE;
 
293
}
 
294
 
 
295
static gboolean
 
296
session_is_login_window (GDBusConnection *connection,
 
297
                         const char      *session_id)
 
298
{
 
299
        GError *local_error = NULL;
 
300
        GVariant *reply;
 
301
        const char *value;
 
302
        gboolean ret;
 
303
 
 
304
        reply = g_dbus_connection_call_sync (connection,
 
305
                                             CK_NAME,
 
306
                                             session_id,
 
307
                                             CK_SESSION_INTERFACE,
 
308
                                             "GetSessionType",
 
309
                                             NULL,
 
310
                                             G_VARIANT_TYPE ("(s)"),
 
311
                                             G_DBUS_CALL_FLAGS_NONE,
 
312
                                             -1,
 
313
                                             NULL, &local_error);
 
314
        if (reply == NULL) {
 
315
                g_warning ("Unable to determine session type: %s", local_error->message);
 
316
                g_error_free (local_error);
 
317
                return FALSE;
 
318
        }
 
319
 
 
320
        g_variant_get (reply, "(&s)", &value);
 
321
 
 
322
        if (value == NULL || value[0] == '\0' || strcmp (value, "LoginWindow") != 0) {
 
323
                ret = FALSE;
 
324
        } else {
 
325
                ret = TRUE;
 
326
        }
 
327
 
 
328
        g_variant_unref (reply);
 
329
 
 
330
        return ret;
 
331
}
 
332
 
 
333
static gboolean
 
334
seat_can_activate_sessions (GDBusConnection *connection,
 
335
                            const char      *seat_id)
 
336
{
 
337
        GError *local_error = NULL;
 
338
        GVariant *reply;
 
339
        gboolean ret;
 
340
 
 
341
        reply = g_dbus_connection_call_sync (connection,
 
342
                                             CK_NAME,
 
343
                                             seat_id,
 
344
                                             CK_SEAT_INTERFACE,
 
345
                                             "CanActivateSessions",
 
346
                                             NULL,
 
347
                                             G_VARIANT_TYPE ("(b)"),
 
348
                                             G_DBUS_CALL_FLAGS_NONE,
 
349
                                             -1,
 
350
                                             NULL, &local_error);
 
351
        if (reply == NULL) {
 
352
                g_warning ("Unable to determine if can activate sessions: %s", local_error->message);
 
353
                g_error_free (local_error);
 
354
                return FALSE;
 
355
        }
 
356
 
 
357
        g_variant_get (reply, "(b)", &ret);
 
358
        g_variant_unref (reply);
 
359
 
 
360
        return ret;
 
361
}
 
362
 
 
363
static const char **
 
364
seat_get_sessions (GDBusConnection *connection,
 
365
                   const char      *seat_id)
 
366
{
 
367
        GError *local_error = NULL;
 
368
        GVariant *reply;
 
369
        const char **value;
 
370
 
 
371
        reply = g_dbus_connection_call_sync (connection,
 
372
                                             CK_NAME,
 
373
                                             seat_id,
 
374
                                             CK_SEAT_INTERFACE,
 
375
                                             "GetSessions",
 
376
                                             NULL,
 
377
                                             G_VARIANT_TYPE ("(ao)"),
 
378
                                             G_DBUS_CALL_FLAGS_NONE,
 
379
                                             -1,
 
380
                                             NULL, &local_error);
 
381
        if (reply == NULL) {
 
382
                g_warning ("Unable to list sessions: %s", local_error->message);
 
383
                g_error_free (local_error);
 
384
                return FALSE;
 
385
        }
 
386
 
 
387
        g_variant_get (reply, "(^ao)", &value);
 
388
        g_variant_unref (reply);
 
389
 
 
390
        return value;
 
391
}
 
392
 
 
393
static gboolean
 
394
get_login_window_session_id_for_ck (GDBusConnection  *connection,
 
395
                                    const char       *seat_id,
 
396
                                    char            **session_id)
 
397
{
 
398
        gboolean     can_activate_sessions;
 
399
        const char **sessions;
 
400
        int          i;
 
401
 
 
402
        *session_id = NULL;
 
403
        sessions = NULL;
 
404
 
 
405
        g_debug ("checking if seat can activate sessions");
 
406
 
 
407
        can_activate_sessions = seat_can_activate_sessions (connection, seat_id);
 
408
        if (! can_activate_sessions) {
 
409
                g_debug ("seat is unable to activate sessions");
 
410
                return FALSE;
 
411
        }
 
412
 
 
413
        sessions = seat_get_sessions (connection, seat_id);
 
414
        for (i = 0; sessions [i] != NULL; i++) {
 
415
                const char *ssid;
 
416
 
 
417
                ssid = sessions [i];
 
418
 
 
419
                if (session_is_login_window (connection, ssid)) {
 
420
                        *session_id = g_strdup (ssid);
 
421
                        break;
 
422
                }
 
423
        }
 
424
        g_free (sessions);
 
425
 
 
426
        return TRUE;
 
427
}
 
428
 
 
429
static gboolean
 
430
goto_login_session_for_ck (GDBusConnection  *connection,
 
431
                           GError          **error)
 
432
{
 
433
        gboolean        ret;
 
434
        gboolean        res;
 
435
        char           *session_id;
 
436
        char           *seat_id;
 
437
 
 
438
        ret = FALSE;
 
439
 
 
440
        /* First look for any existing LoginWindow sessions on the seat.
 
441
           If none are found, create a new one. */
 
442
 
 
443
        seat_id = get_current_seat_id (connection);
 
444
        if (seat_id == NULL || seat_id[0] == '\0') {
 
445
                g_debug ("seat id is not set; can't switch sessions");
 
446
                g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "Could not identify the current session.");
 
447
 
 
448
                return FALSE;
 
449
        }
 
450
 
 
451
        res = get_login_window_session_id_for_ck (connection, seat_id, &session_id);
 
452
        if (! res) {
 
453
                g_set_error (error, GDM_FLEXISERVER_ERROR, 1, "User unable to switch sessions.");
 
454
                return FALSE;
 
455
        }
 
456
 
 
457
        if (session_id != NULL) {
 
458
                res = activate_session_id_for_ck (connection, seat_id, session_id);
 
459
                if (res) {
 
460
                        ret = TRUE;
 
461
                }
 
462
        }
 
463
 
 
464
        if (! ret && g_strcmp0 (seat_id, "/org/freedesktop/ConsoleKit/Seat1") == 0) {
 
465
                res = create_transient_display (connection, error);
 
466
                if (res) {
 
467
                        ret = TRUE;
 
468
                }
 
469
        }
 
470
 
 
471
        return ret;
 
472
}
 
473
#endif
 
474
 
 
475
#ifdef WITH_SYSTEMD
 
476
 
 
477
static gboolean
 
478
activate_session_id_for_systemd (GDBusConnection *connection,
 
479
                                 const char      *seat_id,
 
480
                                 const char      *session_id)
 
481
{
 
482
        GError *local_error = NULL;
 
483
        GVariant *reply;
 
484
 
 
485
        reply = g_dbus_connection_call_sync (connection,
 
486
                                             "org.freedesktop.login1",
 
487
                                             "/org/freedesktop/login1",
 
488
                                             "org.freedesktop.login1.Manager",
 
489
                                             "ActivateSessionOnSeat",
 
490
                                             g_variant_new ("(ss)", session_id, seat_id),
 
491
                                             NULL,
 
492
                                             G_DBUS_CALL_FLAGS_NONE,
 
493
                                             -1,
 
494
                                             NULL, &local_error);
 
495
        if (reply == NULL) {
 
496
                g_warning ("Unable to activate session: %s", local_error->message);
 
497
                g_error_free (local_error);
 
498
                return FALSE;
 
499
        }
 
500
 
 
501
        g_variant_unref (reply);
 
502
 
 
503
        return TRUE;
 
504
}
 
505
 
 
506
static gboolean
 
507
get_login_window_session_id_for_systemd (const char  *seat_id,
 
508
                                         char       **session_id)
 
509
{
 
510
        gboolean   ret;
 
511
        int        res, i;
 
512
        char     **sessions;
 
513
        char      *service_id;
 
514
        char      *service_class;
 
515
        char      *state;
 
516
 
 
517
        res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL);
 
518
        if (res < 0) {
 
519
                g_debug ("Failed to determine sessions: %s", strerror (-res));
 
520
                return FALSE;
 
521
        }
 
522
 
 
523
        if (sessions == NULL || sessions[0] == NULL) {
 
524
                *session_id = NULL;
 
525
                ret = TRUE;
 
526
                goto out;
 
527
        }
 
528
 
 
529
        for (i = 0; sessions[i]; i ++) {
 
530
 
 
531
                res = sd_session_get_class (sessions[i], &service_class);
 
532
                if (res < 0) {
 
533
                        g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res));
 
534
                        ret = FALSE;
 
535
                        goto out;
 
536
                }
 
537
 
 
538
                if (strcmp (service_class, "greeter") != 0) {
 
539
                        free (service_class);
 
540
                        continue;
 
541
                }
 
542
 
 
543
                free (service_class);
 
544
 
 
545
                ret = sd_session_get_state (sessions[i], &state);
 
546
                if (ret < 0) {
 
547
                        g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res));
 
548
                        ret = FALSE;
 
549
                        goto out;
 
550
                }
 
551
 
 
552
                if (g_strcmp0 (state, "closing") == 0) {
 
553
                        free (state);
 
554
                        continue;
 
555
                }
 
556
                free (state);
 
557
 
 
558
                res = sd_session_get_service (sessions[i], &service_id);
 
559
                if (res < 0) {
 
560
                        g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res));
 
561
                        ret = FALSE;
 
562
                        goto out;
 
563
                }
 
564
 
 
565
                if (strcmp (service_id, "gdm-welcome") == 0) {
 
566
                        *session_id = g_strdup (sessions[i]);
 
567
                        ret = TRUE;
 
568
 
 
569
                        free (service_id);
 
570
                        goto out;
 
571
                }
 
572
 
 
573
                free (service_id);
 
574
        }
 
575
 
 
576
        *session_id = NULL;
 
577
        ret = TRUE;
 
578
 
 
579
out:
 
580
        for (i = 0; sessions[i]; i ++) {
 
581
                free (sessions[i]);
 
582
        }
 
583
 
 
584
        free (sessions);
 
585
 
 
586
        return ret;
 
587
}
 
588
 
 
589
static gboolean
 
590
goto_login_session_for_systemd (GDBusConnection  *connection,
 
591
                                GError          **error)
 
592
{
 
593
        gboolean        ret;
 
594
        int             res;
 
595
        char           *our_session;
 
596
        char           *session_id;
 
597
        char           *seat_id;
 
598
 
 
599
        ret = FALSE;
 
600
        session_id = NULL;
 
601
        seat_id = NULL;
 
602
 
 
603
        /* First look for any existing LoginWindow sessions on the seat.
 
604
           If none are found, create a new one. */
 
605
 
 
606
        /* Note that we mostly use free () here, instead of g_free ()
 
607
         * since the data allocated is from libsystemd-logind, which
 
608
         * does not use GLib's g_malloc (). */
 
609
 
 
610
        res = sd_pid_get_session (0, &our_session);
 
611
        if (res < 0) {
 
612
                g_debug ("failed to determine own session: %s", strerror (-res));
 
613
                g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "Could not identify the current session.");
 
614
 
 
615
                return FALSE;
 
616
        }
 
617
 
 
618
        res = sd_session_get_seat (our_session, &seat_id);
 
619
        free (our_session);
 
620
        if (res < 0) {
 
621
                g_debug ("failed to determine own seat: %s", strerror (-res));
 
622
                g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "Could not identify the current seat.");
 
623
 
 
624
                return FALSE;
 
625
        }
 
626
 
 
627
        res = sd_seat_can_multi_session (seat_id);
 
628
        if (res < 0) {
 
629
                free (seat_id);
 
630
 
 
631
                g_debug ("failed to determine whether seat can do multi session: %s", strerror (-res));
 
632
                g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "The system is unable to determine whether to switch to an existing login screen or start up a new login screen.");
 
633
 
 
634
                return FALSE;
 
635
        }
 
636
 
 
637
        if (res == 0) {
 
638
                free (seat_id);
 
639
 
 
640
                g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "The system is unable to start up a new login screen.");
 
641
 
 
642
                return FALSE;
 
643
        }
 
644
 
 
645
        res = get_login_window_session_id_for_systemd (seat_id, &session_id);
 
646
        if (res && session_id != NULL) {
 
647
                res = activate_session_id_for_systemd (connection, seat_id, session_id);
 
648
 
 
649
                if (res) {
 
650
                        ret = TRUE;
 
651
                }
 
652
        }
 
653
 
 
654
        if (! ret && g_strcmp0 (seat_id, "seat0") == 0) {
 
655
                res = create_transient_display (connection, error);
 
656
                if (res) {
 
657
                        ret = TRUE;
 
658
                }
 
659
        }
 
660
 
 
661
        free (seat_id);
 
662
        g_free (session_id);
 
663
 
 
664
        return ret;
 
665
}
 
666
#endif
 
667
 
 
668
static gboolean
 
669
goto_login_session (GError **error)
 
670
{
 
671
        GError *local_error;
 
672
        GDBusConnection *connection;
 
673
 
 
674
        local_error = NULL;
 
675
        connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local_error);
 
676
        if (connection == NULL) {
 
677
                g_debug ("Failed to connect to the D-Bus daemon: %s", local_error->message);
 
678
                g_propagate_error (error, local_error);
 
679
                return FALSE;
 
680
        }
 
681
 
 
682
#ifdef WITH_SYSTEMD
 
683
        if (sd_booted () > 0) {
 
684
                return goto_login_session_for_systemd (connection, error);
 
685
        }
 
686
#endif
 
687
 
 
688
#ifdef WITH_CONSOLE_KIT
 
689
        return goto_login_session_for_ck (connection, error);
 
690
#endif
 
691
}
 
692
 
 
693
int
 
694
main (int argc, char *argv[])
 
695
{
 
696
        GOptionContext *ctx;
 
697
        gboolean        res;
 
698
        GError         *error;
 
699
 
 
700
        bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
 
701
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
702
        textdomain (GETTEXT_PACKAGE);
 
703
        setlocale (LC_ALL, "");
 
704
 
 
705
        /* Option parsing */
 
706
        ctx = g_option_context_new ("- New GDM login");
 
707
        g_option_context_set_translation_domain (ctx, GETTEXT_PACKAGE);
 
708
        g_option_context_add_main_entries (ctx, options, NULL);
 
709
        g_option_context_parse (ctx, &argc, &argv, NULL);
 
710
        g_option_context_free (ctx);
 
711
 
 
712
 
 
713
        if (show_version) {
 
714
                g_print ("%s %s\n", argv [0], VERSION);
 
715
                exit (1);
 
716
        }
 
717
 
 
718
        /* don't support commands other than VERSION */
 
719
        if (send_command != NULL) {
 
720
                if (strcmp (send_command, "VERSION") == 0) {
 
721
                        g_print ("GDM  %s \n", VERSION);
 
722
                        return 0;
 
723
                } else {
 
724
                        g_warning ("No longer supported");
 
725
                }
 
726
                return 1;
 
727
        }
 
728
 
 
729
        gtk_init (&argc, &argv);
 
730
 
 
731
        if (monte_carlo_pi) {
 
732
                calc_pi ();
 
733
                return 0;
 
734
        }
 
735
 
 
736
        if (args_remaining != NULL && args_remaining[0] != NULL) {
 
737
 
 
738
        }
 
739
 
 
740
        if (use_xnest) {
 
741
                g_warning ("Not yet implemented");
 
742
                return 1;
 
743
        }
 
744
 
 
745
        error = NULL;
 
746
        res = goto_login_session (&error);
 
747
        if (! res) {
 
748
                GtkWidget *dialog;
 
749
                char      *message;
 
750
 
 
751
                if (error != NULL) {
 
752
                        message = g_strdup_printf ("%s", error->message);
 
753
                        g_error_free (error);
 
754
                } else {
 
755
                        message = g_strdup ("");
 
756
                }
 
757
 
 
758
                dialog = gtk_message_dialog_new (NULL,
 
759
                                                 GTK_DIALOG_DESTROY_WITH_PARENT,
 
760
                                                 GTK_MESSAGE_ERROR,
 
761
                                                 GTK_BUTTONS_CLOSE,
 
762
                                                 "%s", "Unable to start new display");
 
763
 
 
764
                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
 
765
                                                          "%s", message);
 
766
                g_free (message);
 
767
 
 
768
                gtk_window_set_title (GTK_WINDOW (dialog), "");
 
769
                gtk_window_set_icon_name (GTK_WINDOW (dialog), "session-properties");
 
770
                gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
 
771
                gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14);
 
772
 
 
773
                gtk_dialog_run (GTK_DIALOG (dialog));
 
774
                gtk_widget_destroy (dialog);
 
775
        } else {
 
776
                maybe_lock_screen ();
 
777
        }
 
778
 
 
779
        return 1;
 
780
}