~ubuntu-branches/ubuntu/trusty/gdm/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/00git_logind_check.patch/daemon/gdm-local-display-factory.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha, Tim Lunn, Jeremy Bicha, Robert Ancell
  • Date: 2013-05-31 22:36:08 UTC
  • mfrom: (1.4.55)
  • Revision ID: package-import@ubuntu.com-20130531223608-33uo85niksee5460
Tags: 3.8.1.1-0ubuntu1
[ Tim Lunn ]
* New upstream release
* debian/patches/ubuntu_dont_catch_sigsegv.patch:
  - Dropped, obsolete
* debian/rules:
  - Don't rename gdm binary since that's already been
    done in the new version

[ Jeremy Bicha ]
* debian/control.in: Bump minimum glib
* debian/watch: Watch for unstable releases
* debian/patches/00git_logind_check.patch:
  - Dropped, applied in new release
* debian/patches/08_frequent-users_greeter.patch: Refreshed

[ Robert Ancell ]
* New upstream release
* debian/patches/ubuntu_daemon_autologin_tracking.patch:
* debian/patches/ubuntu_ensure_dirs.patch:
* debian/patches/ubuntu_slave-only-set-up-autologin.patch:
  - Applied upstream

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) 2007 William Jon McCann <mccann@jhu.edu>
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
 
 
26
 
#include <glib.h>
27
 
#include <glib/gi18n.h>
28
 
#include <glib-object.h>
29
 
#include <gio/gio.h>
30
 
 
31
 
#ifdef WITH_SYSTEMD
32
 
#include <systemd/sd-daemon.h>
33
 
#endif
34
 
 
35
 
#include "gdm-manager.h"
36
 
#include "gdm-display-factory.h"
37
 
#include "gdm-local-display-factory.h"
38
 
#include "gdm-local-display-factory-glue.h"
39
 
 
40
 
#include "gdm-display-store.h"
41
 
#include "gdm-static-display.h"
42
 
#include "gdm-transient-display.h"
43
 
 
44
 
#define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate))
45
 
 
46
 
#define CK_SEAT1_PATH                       "/org/freedesktop/ConsoleKit/Seat1"
47
 
#define SYSTEMD_SEAT0_PATH                  "seat0"
48
 
 
49
 
#define GDM_DBUS_PATH                       "/org/gnome/DisplayManager"
50
 
#define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory"
51
 
#define GDM_MANAGER_DBUS_NAME               "org.gnome.DisplayManager.LocalDisplayFactory"
52
 
 
53
 
#define MAX_DISPLAY_FAILURES 5
54
 
 
55
 
struct GdmLocalDisplayFactoryPrivate
56
 
{
57
 
        GdmDBusLocalDisplayFactory *skeleton;
58
 
        GDBusConnection *connection;
59
 
        GHashTable      *displays;
60
 
 
61
 
        /* FIXME: this needs to be per seat? */
62
 
        guint            num_failures;
63
 
 
64
 
#ifdef WITH_SYSTEMD
65
 
        guint            seat_new_id;
66
 
        guint            seat_removed_id;
67
 
#endif
68
 
};
69
 
 
70
 
enum {
71
 
        PROP_0,
72
 
};
73
 
 
74
 
static void     gdm_local_display_factory_class_init    (GdmLocalDisplayFactoryClass *klass);
75
 
static void     gdm_local_display_factory_init          (GdmLocalDisplayFactory      *factory);
76
 
static void     gdm_local_display_factory_finalize      (GObject                     *object);
77
 
 
78
 
static GdmDisplay *create_display                       (GdmLocalDisplayFactory      *factory,
79
 
                                                         const char                  *seat_id,
80
 
                                                         gboolean                    initial_display);
81
 
 
82
 
static void     on_display_status_changed               (GdmDisplay                  *display,
83
 
                                                         GParamSpec                  *arg1,
84
 
                                                         GdmLocalDisplayFactory      *factory);
85
 
 
86
 
static gpointer local_display_factory_object = NULL;
87
 
 
88
 
G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY)
89
 
 
90
 
GQuark
91
 
gdm_local_display_factory_error_quark (void)
92
 
{
93
 
        static GQuark ret = 0;
94
 
        if (ret == 0) {
95
 
                ret = g_quark_from_static_string ("gdm_local_display_factory_error");
96
 
        }
97
 
 
98
 
        return ret;
99
 
}
100
 
 
101
 
static void
102
 
listify_hash (gpointer    key,
103
 
              GdmDisplay *display,
104
 
              GList     **list)
105
 
{
106
 
        *list = g_list_prepend (*list, key);
107
 
}
108
 
 
109
 
static int
110
 
sort_nums (gpointer a,
111
 
           gpointer b)
112
 
{
113
 
        guint32 num_a;
114
 
        guint32 num_b;
115
 
 
116
 
        num_a = GPOINTER_TO_UINT (a);
117
 
        num_b = GPOINTER_TO_UINT (b);
118
 
 
119
 
        if (num_a > num_b) {
120
 
                return 1;
121
 
        } else if (num_a < num_b) {
122
 
                return -1;
123
 
        } else {
124
 
                return 0;
125
 
        }
126
 
}
127
 
 
128
 
static guint32
129
 
take_next_display_number (GdmLocalDisplayFactory *factory)
130
 
{
131
 
        GList  *list;
132
 
        GList  *l;
133
 
        guint32 ret;
134
 
 
135
 
        ret = 0;
136
 
        list = NULL;
137
 
 
138
 
        g_hash_table_foreach (factory->priv->displays, (GHFunc)listify_hash, &list);
139
 
        if (list == NULL) {
140
 
                goto out;
141
 
        }
142
 
 
143
 
        /* sort low to high */
144
 
        list = g_list_sort (list, (GCompareFunc)sort_nums);
145
 
 
146
 
        g_debug ("GdmLocalDisplayFactory: Found the following X displays:");
147
 
        for (l = list; l != NULL; l = l->next) {
148
 
                g_debug ("GdmLocalDisplayFactory: %u", GPOINTER_TO_UINT (l->data));
149
 
        }
150
 
 
151
 
        for (l = list; l != NULL; l = l->next) {
152
 
                guint32 num;
153
 
                num = GPOINTER_TO_UINT (l->data);
154
 
 
155
 
                /* always fill zero */
156
 
                if (l->prev == NULL && num != 0) {
157
 
                        ret = 0;
158
 
                        break;
159
 
                }
160
 
                /* now find the first hole */
161
 
                if (l->next == NULL || GPOINTER_TO_UINT (l->next->data) != (num + 1)) {
162
 
                        ret = num + 1;
163
 
                        break;
164
 
                }
165
 
        }
166
 
 out:
167
 
 
168
 
        /* now reserve this number */
169
 
        g_debug ("GdmLocalDisplayFactory: Reserving X display: %u", ret);
170
 
        g_hash_table_insert (factory->priv->displays, GUINT_TO_POINTER (ret), NULL);
171
 
 
172
 
        return ret;
173
 
}
174
 
 
175
 
static void
176
 
on_display_disposed (GdmLocalDisplayFactory *factory,
177
 
                     GdmDisplay             *display)
178
 
{
179
 
        g_debug ("GdmLocalDisplayFactory: Display %p disposed", display);
180
 
}
181
 
 
182
 
static void
183
 
store_display (GdmLocalDisplayFactory *factory,
184
 
               guint32                 num,
185
 
               GdmDisplay             *display)
186
 
{
187
 
        GdmDisplayStore *store;
188
 
 
189
 
        g_signal_connect (display, "notify::status",
190
 
                          G_CALLBACK (on_display_status_changed), factory);
191
 
 
192
 
        g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory);
193
 
 
194
 
        store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
195
 
        gdm_display_store_add (store, display);
196
 
 
197
 
        /* now fill our reserved spot */
198
 
        g_hash_table_insert (factory->priv->displays, GUINT_TO_POINTER (num), NULL);
199
 
}
200
 
 
201
 
static const char *
202
 
get_seat_of_transient_display (GdmLocalDisplayFactory *factory)
203
 
{
204
 
        const char *seat_id;
205
 
 
206
 
        /* FIXME: don't hardcode seat */
207
 
#ifdef WITH_SYSTEMD
208
 
        seat_id = SYSTEMD_SEAT0_PATH;
209
 
#else
210
 
        seat_id = CK_SEAT1_PATH;
211
 
#endif
212
 
 
213
 
        return seat_id;
214
 
}
215
 
 
216
 
/*
217
 
  Example:
218
 
  dbus-send --system --dest=org.gnome.DisplayManager \
219
 
  --type=method_call --print-reply --reply-timeout=2000 \
220
 
  /org/gnome/DisplayManager/Manager \
221
 
  org.gnome.DisplayManager.Manager.GetDisplays
222
 
*/
223
 
gboolean
224
 
gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory,
225
 
                                                    char                  **id,
226
 
                                                    GError                **error)
227
 
{
228
 
        gboolean         ret;
229
 
        GdmDisplay      *display;
230
 
        guint32          num;
231
 
        const char      *seat_id;
232
 
 
233
 
        g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
234
 
 
235
 
        ret = FALSE;
236
 
 
237
 
        num = take_next_display_number (factory);
238
 
 
239
 
        g_debug ("GdmLocalDisplayFactory: Creating transient display %d", num);
240
 
 
241
 
        display = gdm_transient_display_new (num);
242
 
 
243
 
        seat_id = get_seat_of_transient_display (factory);
244
 
        g_object_set (display, "seat-id", seat_id, NULL);
245
 
 
246
 
        store_display (factory, num, display);
247
 
 
248
 
        if (! gdm_display_manage (display)) {
249
 
                display = NULL;
250
 
                goto out;
251
 
        }
252
 
 
253
 
        if (! gdm_display_get_id (display, id, NULL)) {
254
 
                display = NULL;
255
 
                goto out;
256
 
        }
257
 
 
258
 
        ret = TRUE;
259
 
 out:
260
 
        /* ref either held by store or not at all */
261
 
        g_object_unref (display);
262
 
 
263
 
        return ret;
264
 
}
265
 
 
266
 
static void
267
 
on_display_status_changed (GdmDisplay             *display,
268
 
                           GParamSpec             *arg1,
269
 
                           GdmLocalDisplayFactory *factory)
270
 
{
271
 
        int              status;
272
 
        GdmDisplayStore *store;
273
 
        int              num;
274
 
        char            *seat_id = NULL;
275
 
        gboolean         is_initial = TRUE;
276
 
 
277
 
        num = -1;
278
 
        gdm_display_get_x11_display_number (display, &num, NULL);
279
 
        g_assert (num != -1);
280
 
 
281
 
        store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
282
 
 
283
 
        g_object_get (display, "seat-id", &seat_id, NULL);
284
 
        g_object_get (display, "is-initial", &is_initial, NULL);
285
 
 
286
 
        status = gdm_display_get_status (display);
287
 
 
288
 
        g_debug ("GdmLocalDisplayFactory: display status changed: %d", status);
289
 
        switch (status) {
290
 
        case GDM_DISPLAY_FINISHED:
291
 
                /* remove the display number from factory->priv->displays
292
 
                   so that it may be reused */
293
 
                g_hash_table_remove (factory->priv->displays, GUINT_TO_POINTER (num));
294
 
                gdm_display_store_remove (store, display);
295
 
 
296
 
                /* Create a new equivalent display if it was static */
297
 
                if (GDM_IS_STATIC_DISPLAY (display)) {
298
 
                        /* reset num failures */
299
 
                        factory->priv->num_failures = 0;
300
 
 
301
 
                        create_display (factory, seat_id, is_initial);
302
 
                }
303
 
                break;
304
 
        case GDM_DISPLAY_FAILED:
305
 
                /* leave the display number in factory->priv->displays
306
 
                   so that it doesn't get reused */
307
 
                gdm_display_store_remove (store, display);
308
 
 
309
 
                /* Create a new equivalent display if it was static */
310
 
                if (GDM_IS_STATIC_DISPLAY (display)) {
311
 
 
312
 
                        factory->priv->num_failures++;
313
 
 
314
 
                        if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) {
315
 
                                /* oh shit */
316
 
                                g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors");
317
 
                                /* FIXME: should monitor hardware changes to
318
 
                                   try again when seats change */
319
 
                        } else {
320
 
                                create_display (factory, seat_id, is_initial);
321
 
                        }
322
 
                }
323
 
                break;
324
 
        case GDM_DISPLAY_UNMANAGED:
325
 
                break;
326
 
        case GDM_DISPLAY_PREPARED:
327
 
                break;
328
 
        case GDM_DISPLAY_MANAGED:
329
 
                break;
330
 
        default:
331
 
                g_assert_not_reached ();
332
 
                break;
333
 
        }
334
 
 
335
 
        g_free (seat_id);
336
 
}
337
 
 
338
 
static gboolean
339
 
lookup_by_seat_id (const char *id,
340
 
                   GdmDisplay *display,
341
 
                   gpointer    user_data)
342
 
{
343
 
        const char *looking_for = user_data;
344
 
        char *current;
345
 
        gboolean res;
346
 
 
347
 
        g_object_get (G_OBJECT (display), "seat-id", &current, NULL);
348
 
 
349
 
        res = g_strcmp0 (current, looking_for) == 0;
350
 
 
351
 
        g_free(current);
352
 
 
353
 
        return res;
354
 
}
355
 
 
356
 
static GdmDisplay *
357
 
create_display (GdmLocalDisplayFactory *factory,
358
 
                const char             *seat_id,
359
 
                gboolean                initial)
360
 
{
361
 
        GdmDisplayStore *store;
362
 
        GdmDisplay      *display;
363
 
        guint32          num;
364
 
 
365
 
        /* Ensure we don't create the same display more than once */
366
 
        store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
367
 
        display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
368
 
        if (display != NULL) {
369
 
                return NULL;
370
 
        }
371
 
 
372
 
        g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
373
 
 
374
 
        num = take_next_display_number (factory);
375
 
 
376
 
        display = gdm_static_display_new (num);
377
 
 
378
 
        g_object_set (display, "seat-id", seat_id, NULL);
379
 
        g_object_set (display, "is-initial", initial, NULL);
380
 
 
381
 
        store_display (factory, num, display);
382
 
 
383
 
        /* let store own the ref */
384
 
        g_object_unref (display);
385
 
 
386
 
        if (! gdm_display_manage (display)) {
387
 
                gdm_display_unmanage (display);
388
 
        }
389
 
 
390
 
        return display;
391
 
}
392
 
 
393
 
#ifdef WITH_SYSTEMD
394
 
 
395
 
static void
396
 
delete_display (GdmLocalDisplayFactory *factory,
397
 
                const char             *seat_id) {
398
 
 
399
 
        GdmDisplayStore *store;
400
 
 
401
 
        g_debug ("GdmLocalDisplayFactory: Removing displays on seat %s", seat_id);
402
 
 
403
 
        store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
404
 
        gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id);
405
 
}
406
 
 
407
 
static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory)
408
 
{
409
 
        GError *error = NULL;
410
 
        GVariant *result;
411
 
        GVariant *array;
412
 
        GVariantIter iter;
413
 
        const char *seat;
414
 
 
415
 
        result = g_dbus_connection_call_sync (factory->priv->connection,
416
 
                                              "org.freedesktop.login1",
417
 
                                              "/org/freedesktop/login1",
418
 
                                              "org.freedesktop.login1.Manager",
419
 
                                              "ListSeats",
420
 
                                              NULL,
421
 
                                              G_VARIANT_TYPE ("(a(so))"),
422
 
                                              G_DBUS_CALL_FLAGS_NONE,
423
 
                                              -1,
424
 
                                              NULL, &error);
425
 
 
426
 
        if (!result) {
427
 
                g_warning ("GdmLocalDisplayFactory: Failed to issue method call: %s", error->message);
428
 
                g_clear_error (&error);
429
 
                return FALSE;
430
 
        }
431
 
 
432
 
        array = g_variant_get_child_value (result, 0);
433
 
        g_variant_iter_init (&iter, array);
434
 
 
435
 
        while (g_variant_iter_loop (&iter, "(&so)", &seat, NULL))
436
 
                create_display (factory, seat, TRUE);
437
 
 
438
 
        g_variant_unref (result);
439
 
        g_variant_unref (array);
440
 
        return TRUE;
441
 
}
442
 
 
443
 
static void
444
 
on_seat_new (GDBusConnection *connection,
445
 
             const gchar     *sender_name,
446
 
             const gchar     *object_path,
447
 
             const gchar     *interface_name,
448
 
             const gchar     *signal_name,
449
 
             GVariant        *parameters,
450
 
             gpointer         user_data)
451
 
{
452
 
        const char *seat;
453
 
 
454
 
        g_variant_get (parameters, "(&s&o)", &seat, NULL);
455
 
        create_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat, FALSE);
456
 
}
457
 
 
458
 
static void
459
 
on_seat_removed (GDBusConnection *connection,
460
 
                 const gchar     *sender_name,
461
 
                 const gchar     *object_path,
462
 
                 const gchar     *interface_name,
463
 
                 const gchar     *signal_name,
464
 
                 GVariant        *parameters,
465
 
                 gpointer         user_data)
466
 
{
467
 
        const char *seat;
468
 
 
469
 
        g_variant_get (parameters, "(&s&o)", &seat, NULL);
470
 
        delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat);
471
 
}
472
 
 
473
 
static void
474
 
gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory)
475
 
{
476
 
        factory->priv->seat_new_id = g_dbus_connection_signal_subscribe (factory->priv->connection,
477
 
                                                                         "org.freedesktop.login1",
478
 
                                                                         "org.freedesktop.login1.Manager",
479
 
                                                                         "SeatNew",
480
 
                                                                         "/org/freedesktop/login1",
481
 
                                                                         NULL,
482
 
                                                                         G_DBUS_SIGNAL_FLAGS_NONE,
483
 
                                                                         on_seat_new,
484
 
                                                                         g_object_ref (factory),
485
 
                                                                         g_object_unref);
486
 
        factory->priv->seat_removed_id = g_dbus_connection_signal_subscribe (factory->priv->connection,
487
 
                                                                             "org.freedesktop.login1",
488
 
                                                                             "org.freedesktop.login1.Manager",
489
 
                                                                             "SeatRemoved",
490
 
                                                                             "/org/freedesktop/login1",
491
 
                                                                             NULL,
492
 
                                                                             G_DBUS_SIGNAL_FLAGS_NONE,
493
 
                                                                             on_seat_removed,
494
 
                                                                             g_object_ref (factory),
495
 
                                                                             g_object_unref);
496
 
}
497
 
 
498
 
static void
499
 
gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
500
 
{
501
 
        if (factory->priv->seat_new_id) {
502
 
                g_dbus_connection_signal_unsubscribe (factory->priv->connection,
503
 
                                                      factory->priv->seat_new_id);
504
 
                factory->priv->seat_new_id = 0;
505
 
        }
506
 
        if (factory->priv->seat_removed_id) {
507
 
                g_dbus_connection_signal_unsubscribe (factory->priv->connection,
508
 
                                                      factory->priv->seat_removed_id);
509
 
                factory->priv->seat_removed_id = 0;
510
 
        }
511
 
}
512
 
 
513
 
#endif
514
 
 
515
 
static gboolean
516
 
gdm_local_display_factory_start (GdmDisplayFactory *base_factory)
517
 
{
518
 
        GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory);
519
 
        GdmDisplay             *display;
520
 
 
521
 
        g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
522
 
 
523
 
#ifdef WITH_SYSTEMD
524
 
        if (sd_booted () > 0) {
525
 
                gdm_local_display_factory_start_monitor (factory);
526
 
                return gdm_local_display_factory_sync_seats (factory);
527
 
        }
528
 
#endif
529
 
 
530
 
        /* On ConsoleKit just create Seat1, and that's it. */
531
 
        display = create_display (factory, CK_SEAT1_PATH, TRUE);
532
 
 
533
 
        return display != NULL;
534
 
}
535
 
 
536
 
static gboolean
537
 
gdm_local_display_factory_stop (GdmDisplayFactory *base_factory)
538
 
{
539
 
        GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory);
540
 
 
541
 
        g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
542
 
 
543
 
#ifdef WITH_SYSTEMD
544
 
        gdm_local_display_factory_stop_monitor (factory);
545
 
#endif
546
 
 
547
 
        return TRUE;
548
 
}
549
 
 
550
 
static void
551
 
gdm_local_display_factory_set_property (GObject       *object,
552
 
                                        guint          prop_id,
553
 
                                        const GValue  *value,
554
 
                                        GParamSpec    *pspec)
555
 
{
556
 
        switch (prop_id) {
557
 
        default:
558
 
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
559
 
                break;
560
 
        }
561
 
}
562
 
 
563
 
static void
564
 
gdm_local_display_factory_get_property (GObject    *object,
565
 
                                        guint       prop_id,
566
 
                                        GValue     *value,
567
 
                                        GParamSpec *pspec)
568
 
{
569
 
        switch (prop_id) {
570
 
        default:
571
 
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
572
 
                break;
573
 
        }
574
 
}
575
 
 
576
 
static gboolean
577
 
handle_create_transient_display (GdmDBusLocalDisplayFactory *skeleton,
578
 
                                 GDBusMethodInvocation      *invocation,
579
 
                                 GdmLocalDisplayFactory     *factory)
580
 
{
581
 
        GError *error = NULL;
582
 
        gboolean created;
583
 
        char *id = NULL;
584
 
 
585
 
        created = gdm_local_display_factory_create_transient_display (factory,
586
 
                                                                      &id,
587
 
                                                                      &error);
588
 
        if (!created) {
589
 
                g_dbus_method_invocation_return_gerror (invocation, error);
590
 
        } else {
591
 
                gdm_dbus_local_display_factory_complete_create_transient_display (skeleton, invocation, id);
592
 
        }
593
 
 
594
 
        g_free (id);
595
 
        return TRUE;
596
 
}
597
 
 
598
 
static gboolean
599
 
register_factory (GdmLocalDisplayFactory *factory)
600
 
{
601
 
        GError *error = NULL;
602
 
 
603
 
        error = NULL;
604
 
        factory->priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
605
 
        if (factory->priv->connection == NULL) {
606
 
                g_critical ("error getting system bus: %s", error->message);
607
 
                g_error_free (error);
608
 
                exit (1);
609
 
        }
610
 
 
611
 
        factory->priv->skeleton = GDM_DBUS_LOCAL_DISPLAY_FACTORY (gdm_dbus_local_display_factory_skeleton_new ());
612
 
 
613
 
        g_signal_connect (factory->priv->skeleton,
614
 
                          "handle-create-transient-display",
615
 
                          G_CALLBACK (handle_create_transient_display),
616
 
                          factory);
617
 
 
618
 
        if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (factory->priv->skeleton),
619
 
                                               factory->priv->connection,
620
 
                                               GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH,
621
 
                                               &error)) {
622
 
                g_critical ("error exporting LocalDisplayFactory object: %s", error->message);
623
 
                g_error_free (error);
624
 
                exit (1);
625
 
        }
626
 
 
627
 
        return TRUE;
628
 
}
629
 
 
630
 
static GObject *
631
 
gdm_local_display_factory_constructor (GType                  type,
632
 
                                       guint                  n_construct_properties,
633
 
                                       GObjectConstructParam *construct_properties)
634
 
{
635
 
        GdmLocalDisplayFactory      *factory;
636
 
        gboolean                     res;
637
 
 
638
 
        factory = GDM_LOCAL_DISPLAY_FACTORY (G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->constructor (type,
639
 
                                                                                                                   n_construct_properties,
640
 
                                                                                                                   construct_properties));
641
 
 
642
 
        res = register_factory (factory);
643
 
        if (! res) {
644
 
                g_warning ("Unable to register local display factory with system bus");
645
 
        }
646
 
 
647
 
        return G_OBJECT (factory);
648
 
}
649
 
 
650
 
static void
651
 
gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass)
652
 
{
653
 
        GObjectClass           *object_class = G_OBJECT_CLASS (klass);
654
 
        GdmDisplayFactoryClass *factory_class = GDM_DISPLAY_FACTORY_CLASS (klass);
655
 
 
656
 
        object_class->get_property = gdm_local_display_factory_get_property;
657
 
        object_class->set_property = gdm_local_display_factory_set_property;
658
 
        object_class->finalize = gdm_local_display_factory_finalize;
659
 
        object_class->constructor = gdm_local_display_factory_constructor;
660
 
 
661
 
        factory_class->start = gdm_local_display_factory_start;
662
 
        factory_class->stop = gdm_local_display_factory_stop;
663
 
 
664
 
        g_type_class_add_private (klass, sizeof (GdmLocalDisplayFactoryPrivate));
665
 
}
666
 
 
667
 
static void
668
 
gdm_local_display_factory_init (GdmLocalDisplayFactory *factory)
669
 
{
670
 
        factory->priv = GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE (factory);
671
 
 
672
 
        factory->priv->displays = g_hash_table_new (NULL, NULL);
673
 
}
674
 
 
675
 
static void
676
 
gdm_local_display_factory_finalize (GObject *object)
677
 
{
678
 
        GdmLocalDisplayFactory *factory;
679
 
 
680
 
        g_return_if_fail (object != NULL);
681
 
        g_return_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (object));
682
 
 
683
 
        factory = GDM_LOCAL_DISPLAY_FACTORY (object);
684
 
 
685
 
        g_return_if_fail (factory->priv != NULL);
686
 
 
687
 
        g_clear_object (&factory->priv->connection);
688
 
        g_clear_object (&factory->priv->skeleton);
689
 
 
690
 
        g_hash_table_destroy (factory->priv->displays);
691
 
 
692
 
#ifdef WITH_SYSTEMD
693
 
        gdm_local_display_factory_stop_monitor (factory);
694
 
#endif
695
 
 
696
 
        G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->finalize (object);
697
 
}
698
 
 
699
 
GdmLocalDisplayFactory *
700
 
gdm_local_display_factory_new (GdmDisplayStore *store)
701
 
{
702
 
        if (local_display_factory_object != NULL) {
703
 
                g_object_ref (local_display_factory_object);
704
 
        } else {
705
 
                local_display_factory_object = g_object_new (GDM_TYPE_LOCAL_DISPLAY_FACTORY,
706
 
                                                             "display-store", store,
707
 
                                                             NULL);
708
 
                g_object_add_weak_pointer (local_display_factory_object,
709
 
                                           (gpointer *) &local_display_factory_object);
710
 
        }
711
 
 
712
 
        return GDM_LOCAL_DISPLAY_FACTORY (local_display_factory_object);
713
 
}