~robert-ancell/lightdm/xorg-displayfd

« back to all changes in this revision

Viewing changes to src/login1.c

  • Committer: Robert Ancell
  • Date: 2015-08-10 00:13:50 UTC
  • mfrom: (1947.2.216 trunk)
  • Revision ID: robert.ancell@canonical.com-20150810001350-mrigcdovq3xkw68u
Merge with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 * license.
11
11
 */
12
12
 
 
13
#include <string.h>
13
14
#include <gio/gio.h>
14
15
 
15
16
#include "login1.h"
16
17
 
 
18
#define LOGIN1_SERVICE_NAME "org.freedesktop.login1"
 
19
#define LOGIN1_OBJECT_NAME "/org/freedesktop/login1"
 
20
#define LOGIN1_MANAGER_INTERFACE_NAME "org.freedesktop.login1.Manager"
 
21
 
 
22
enum {
 
23
    SEAT_ADDED,
 
24
    SEAT_REMOVED,
 
25
    LAST_SERVICE_SIGNAL
 
26
};
 
27
static guint service_signals[LAST_SERVICE_SIGNAL] = { 0 };
 
28
 
 
29
struct Login1ServicePrivate
 
30
{
 
31
    /* Connection to bus service is running on */
 
32
    GDBusConnection *connection;
 
33
 
 
34
    /* TRUE if have connected to service */
 
35
    gboolean connected;
 
36
 
 
37
    /* Seats the service is reporting */
 
38
    GList *seats;
 
39
 
 
40
    /* Handle to signal subscription */
 
41
    guint signal_id;
 
42
};
 
43
 
 
44
enum {
 
45
    CAN_GRAPHICAL_CHANGED,
 
46
    ACTIVE_SESSION_CHANGED,
 
47
    LAST_SEAT_SIGNAL
 
48
};
 
49
static guint seat_signals[LAST_SEAT_SIGNAL] = { 0 };
 
50
 
 
51
struct Login1SeatPrivate
 
52
{
 
53
    /* Connection to bus seat is running on */
 
54
    GDBusConnection *connection;
 
55
 
 
56
    /* Seat Id */
 
57
    gchar *id;
 
58
 
 
59
    /* D-Bus path for this seat */
 
60
    gchar *path;
 
61
 
 
62
    /* Handle to signal subscription */
 
63
    guint signal_id;
 
64
 
 
65
    /* TRUE if can run a graphical display on this seat */
 
66
    gboolean can_graphical;
 
67
 
 
68
    /* TRUE if can do session switching */
 
69
    gboolean can_multi_session;
 
70
};
 
71
 
 
72
G_DEFINE_TYPE (Login1Service, login1_service, G_TYPE_OBJECT);
 
73
G_DEFINE_TYPE (Login1Seat, login1_seat, G_TYPE_OBJECT);
 
74
 
 
75
static Login1Service *singleton = NULL;
 
76
 
 
77
Login1Service *
 
78
login1_service_get_instance (void)
 
79
{
 
80
    if (!singleton)
 
81
        singleton = g_object_new (LOGIN1_SERVICE_TYPE, NULL);
 
82
    return singleton;
 
83
}
 
84
 
 
85
static void
 
86
update_property (Login1Seat *seat, const gchar *name, GVariant *value)
 
87
{
 
88
    if (strcmp (name, "CanGraphical") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN))
 
89
    {
 
90
        seat->priv->can_graphical = g_variant_get_boolean (value);
 
91
        g_signal_emit (seat, seat_signals[CAN_GRAPHICAL_CHANGED], 0);
 
92
    }
 
93
    else if (strcmp (name, "ActiveSession") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE ("(so)")))
 
94
    {
 
95
        const gchar *login1_session_id;
 
96
        g_variant_get (value, "(&so)", &login1_session_id, NULL);
 
97
        g_signal_emit (seat, seat_signals[ACTIVE_SESSION_CHANGED], 0, login1_session_id);
 
98
    }
 
99
}
 
100
 
 
101
static void
 
102
seat_properties_changed_cb (GDBusConnection *connection,
 
103
                            const gchar *sender_name,
 
104
                            const gchar *object_path,
 
105
                            const gchar *interface_name,
 
106
                            const gchar *signal_name,
 
107
                            GVariant *parameters,
 
108
                            gpointer user_data)
 
109
{
 
110
    Login1Seat *seat = user_data;
 
111
    GVariantIter *iter;
 
112
    GVariantIter *invalidated_properties;
 
113
    const gchar *name;
 
114
    GVariant *value;
 
115
 
 
116
    g_variant_get (parameters, "(sa{sv}as)", NULL, &iter, &invalidated_properties);
 
117
    while (g_variant_iter_loop (iter, "{&sv}", &name, &value))
 
118
        update_property (seat, name, value);
 
119
    g_variant_iter_free (iter);
 
120
    while (g_variant_iter_loop (invalidated_properties, "&s", &name))
 
121
    {
 
122
        GVariant *result;
 
123
        GError *error = NULL;
 
124
 
 
125
        result = g_dbus_connection_call_sync (connection,
 
126
                                              LOGIN1_SERVICE_NAME,
 
127
                                              seat->priv->path,
 
128
                                              "org.freedesktop.DBus.Properties",
 
129
                                              "Get",
 
130
                                              g_variant_new ("(ss)", "org.freedesktop.login1.Seat", name),
 
131
                                              G_VARIANT_TYPE ("(v)"),
 
132
                                              G_DBUS_CALL_FLAGS_NONE,
 
133
                                              -1,
 
134
                                              NULL,
 
135
                                              &error);
 
136
        if (error)
 
137
            g_warning ("Error updating seat property %s: %s", name, error->message);
 
138
        g_clear_error (&error);
 
139
        if (result)
 
140
        {
 
141
            g_variant_get (result, "(v)", &value);
 
142
            update_property (seat, name, value);
 
143
            g_variant_unref (value);
 
144
            g_variant_unref (result);
 
145
        }
 
146
    }
 
147
    g_variant_iter_free (invalidated_properties);
 
148
}
 
149
 
 
150
static Login1Seat *
 
151
add_seat (Login1Service *service, const gchar *id, const gchar *path)
 
152
{
 
153
    Login1Seat *seat;
 
154
    GVariant *result;
 
155
    GError *error = NULL;
 
156
 
 
157
    seat = g_object_new (LOGIN1_SEAT_TYPE, NULL);
 
158
    seat->priv->connection = g_object_ref (service->priv->connection);
 
159
    seat->priv->id = g_strdup (id);
 
160
    seat->priv->path = g_strdup (path);
 
161
 
 
162
    seat->priv->signal_id = g_dbus_connection_signal_subscribe (seat->priv->connection,
 
163
                                                                LOGIN1_SERVICE_NAME,
 
164
                                                                "org.freedesktop.DBus.Properties",
 
165
                                                                "PropertiesChanged",
 
166
                                                                path,
 
167
                                                                "org.freedesktop.login1.Seat",
 
168
                                                                G_DBUS_SIGNAL_FLAGS_NONE,
 
169
                                                                seat_properties_changed_cb,
 
170
                                                                g_object_ref (seat),
 
171
                                                                g_object_unref);
 
172
 
 
173
    /* Get properties for this seat */
 
174
    result = g_dbus_connection_call_sync (seat->priv->connection,
 
175
                                          LOGIN1_SERVICE_NAME,
 
176
                                          path,
 
177
                                          "org.freedesktop.DBus.Properties",
 
178
                                          "GetAll",
 
179
                                          g_variant_new ("(s)", "org.freedesktop.login1.Seat"),
 
180
                                          G_VARIANT_TYPE ("(a{sv})"),
 
181
                                          G_DBUS_CALL_FLAGS_NONE,
 
182
                                          -1,
 
183
                                          NULL,
 
184
                                          &error);
 
185
    if (error)
 
186
        g_warning ("Failed to get seat properties: %s", error->message);
 
187
    g_clear_error (&error);
 
188
    if (result)
 
189
    {
 
190
        GVariantIter *properties;
 
191
        const gchar *name;
 
192
        GVariant *value;
 
193
 
 
194
        g_variant_get (result, "(a{sv})", &properties);
 
195
        while (g_variant_iter_loop (properties, "{&sv}", &name, &value))
 
196
        {
 
197
            if (strcmp (name, "CanGraphical") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN))
 
198
                seat->priv->can_graphical = g_variant_get_boolean (value);
 
199
            else if (strcmp (name, "CanMultiSession") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN))
 
200
                seat->priv->can_multi_session = g_variant_get_boolean (value);
 
201
        }
 
202
        g_variant_iter_free (properties);
 
203
        g_variant_unref (result);
 
204
    }
 
205
 
 
206
    service->priv->seats = g_list_append (service->priv->seats, seat);
 
207
 
 
208
    return seat;
 
209
}
 
210
 
 
211
static void
 
212
signal_cb (GDBusConnection *connection,
 
213
           const gchar *sender_name,
 
214
           const gchar *object_path,
 
215
           const gchar *interface_name,
 
216
           const gchar *signal_name,
 
217
           GVariant *parameters,
 
218
           gpointer user_data)
 
219
{
 
220
    Login1Service *service = user_data;
 
221
 
 
222
    if (strcmp (signal_name, "SeatNew") == 0)
 
223
    {
 
224
        const gchar *id, *path;
 
225
        Login1Seat *seat;
 
226
 
 
227
        g_variant_get (parameters, "(&s&o)", &id, &path);
 
228
        seat = login1_service_get_seat (service, id);
 
229
        if (!seat)
 
230
        {
 
231
            seat = add_seat (service, id, path);
 
232
            g_signal_emit (service, service_signals[SEAT_ADDED], 0, seat);
 
233
        }
 
234
    }
 
235
    else if (strcmp (signal_name, "SeatRemoved") == 0)
 
236
    {
 
237
        const gchar *id, *path;
 
238
        Login1Seat *seat;
 
239
 
 
240
        g_variant_get (parameters, "(&s&o)", &id, &path);
 
241
        seat = login1_service_get_seat (service, id);
 
242
        if (seat)
 
243
        {
 
244
            service->priv->seats = g_list_remove (service->priv->seats, seat);
 
245
            g_signal_emit (service, service_signals[SEAT_REMOVED], 0, seat);
 
246
            g_object_unref (seat);
 
247
        }
 
248
    }
 
249
}
 
250
 
17
251
gboolean
18
 
login1_is_running (void)
19
 
{
20
 
    return access ("/run/systemd/seats/", F_OK) >= 0;
21
 
}
22
 
 
23
 
gchar *
24
 
login1_get_session_id (void)
25
 
{
26
 
    GDBusConnection *bus;
 
252
login1_service_connect (Login1Service *service)
 
253
{
27
254
    GVariant *result;
28
 
    gchar *session_path;
 
255
    GVariantIter *seat_iter;
 
256
    const gchar *id, *path;
29
257
    GError *error = NULL;
30
258
 
31
 
    bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
 
259
    g_return_val_if_fail (service != NULL, FALSE);
 
260
 
 
261
    if (service->priv->connected)
 
262
        return TRUE;
 
263
 
 
264
    service->priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
32
265
    if (error)
33
266
        g_warning ("Failed to get system bus: %s", error->message);
34
267
    g_clear_error (&error);
35
 
    if (!bus)
36
 
        return NULL;
37
 
    result = g_dbus_connection_call_sync (bus,
38
 
                                          "org.freedesktop.login1",
39
 
                                          "/org/freedesktop/login1",
40
 
                                          "org.freedesktop.login1.Manager",
41
 
                                          "GetSessionByPID",
42
 
                                          g_variant_new ("(u)", getpid()),
43
 
                                          G_VARIANT_TYPE ("(o)"),
 
268
    if (!service->priv->connection)
 
269
        return FALSE;
 
270
 
 
271
    service->priv->signal_id = g_dbus_connection_signal_subscribe (service->priv->connection,
 
272
                                                                   LOGIN1_SERVICE_NAME,
 
273
                                                                   LOGIN1_MANAGER_INTERFACE_NAME,
 
274
                                                                   NULL,
 
275
                                                                   LOGIN1_OBJECT_NAME,
 
276
                                                                   NULL,
 
277
                                                                   G_DBUS_SIGNAL_FLAGS_NONE,
 
278
                                                                   signal_cb,
 
279
                                                                   g_object_ref (service),
 
280
                                                                   g_object_unref);
 
281
 
 
282
    result = g_dbus_connection_call_sync (service->priv->connection,
 
283
                                          LOGIN1_SERVICE_NAME,
 
284
                                          LOGIN1_OBJECT_NAME,
 
285
                                          LOGIN1_MANAGER_INTERFACE_NAME,
 
286
                                          "ListSeats",
 
287
                                          g_variant_new ("()"),
 
288
                                          G_VARIANT_TYPE ("(a(so))"),
44
289
                                          G_DBUS_CALL_FLAGS_NONE,
45
290
                                          -1,
46
291
                                          NULL,
47
292
                                          &error);
48
 
    g_object_unref (bus);
49
 
 
50
293
    if (error)
51
 
        g_warning ("Failed to open login1 session: %s", error->message);
 
294
        g_warning ("Failed to get list of logind seats: %s", error->message);
52
295
    g_clear_error (&error);
53
296
    if (!result)
54
 
        return NULL;
 
297
        return FALSE;
55
298
 
56
 
    g_variant_get (result, "(o)", &session_path);
 
299
    g_variant_get (result, "(a(so))", &seat_iter);
 
300
    while (g_variant_iter_loop (seat_iter, "(&s&o)", &id, &path))
 
301
        add_seat (service, id, path);
 
302
    g_variant_iter_free (seat_iter);
57
303
    g_variant_unref (result);
58
 
    g_debug ("Got login1 session id: %s", session_path);
59
 
 
60
 
    return session_path;
 
304
 
 
305
    service->priv->connected = TRUE;
 
306
 
 
307
    return TRUE;
 
308
}
 
309
 
 
310
gboolean
 
311
login1_service_get_is_connected (Login1Service *service)
 
312
{
 
313
    g_return_val_if_fail (service != NULL, FALSE);
 
314
    return service->priv->connected;
 
315
}
 
316
 
 
317
GList *
 
318
login1_service_get_seats (Login1Service *service)
 
319
{
 
320
    g_return_val_if_fail (service != NULL, NULL);
 
321
    return service->priv->seats;
 
322
}
 
323
 
 
324
Login1Seat *
 
325
login1_service_get_seat (Login1Service *service, const gchar *id)
 
326
{
 
327
    GList *link;
 
328
 
 
329
    g_return_val_if_fail (service != NULL, NULL);
 
330
 
 
331
    for (link = service->priv->seats; link; link = link->next)
 
332
    {
 
333
        Login1Seat *seat = link->data;
 
334
        if (strcmp (seat->priv->id, id) == 0)
 
335
            return seat;
 
336
    }
 
337
 
 
338
    return NULL;
61
339
}
62
340
 
63
341
void
64
 
login1_lock_session (const gchar *session_path)
 
342
login1_service_lock_session (Login1Service *service, const gchar *session_id)
65
343
{
66
 
    GDBusConnection *bus;
67
344
    GError *error = NULL;
68
345
 
69
 
    g_return_if_fail (session_path != NULL);
70
 
 
71
 
    g_debug ("Locking login1 session %s", session_path);
72
 
 
73
 
    bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
74
 
    if (error)
75
 
        g_warning ("Failed to get system bus: %s", error->message);
76
 
    g_clear_error (&error);
77
 
    if (!bus)
78
 
        return;
79
 
 
80
 
    if (session_path)
 
346
    g_return_if_fail (service != NULL);
 
347
    g_return_if_fail (session_id != NULL);
 
348
 
 
349
    g_debug ("Locking login1 session %s", session_id);
 
350
 
 
351
    if (session_id)
81
352
    {
82
353
        GVariant *result;
83
354
 
84
 
        result = g_dbus_connection_call_sync (bus,
85
 
                                              "org.freedesktop.login1",
86
 
                                              session_path,
87
 
                                              "org.freedesktop.login1.Session",
88
 
                                              "Lock",
89
 
                                              g_variant_new ("()"),
 
355
        result = g_dbus_connection_call_sync (service->priv->connection,
 
356
                                              LOGIN1_SERVICE_NAME,
 
357
                                              LOGIN1_OBJECT_NAME,
 
358
                                              LOGIN1_MANAGER_INTERFACE_NAME,
 
359
                                              "LockSession",
 
360
                                              g_variant_new ("(s)", session_id),
90
361
                                              G_VARIANT_TYPE ("()"),
91
362
                                              G_DBUS_CALL_FLAGS_NONE,
92
363
                                              -1,
98
369
        if (result)
99
370
            g_variant_unref (result);
100
371
    }
101
 
    g_object_unref (bus);
102
372
}
103
373
 
104
374
void
105
 
login1_unlock_session (const gchar *session_path)
 
375
login1_service_unlock_session (Login1Service *service, const gchar *session_id)
106
376
{
107
 
    GDBusConnection *bus;
108
377
    GError *error = NULL;
109
378
 
110
 
    g_return_if_fail (session_path != NULL);
111
 
 
112
 
    g_debug ("Unlocking login1 session %s", session_path);
113
 
 
114
 
    bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
115
 
    if (error)
116
 
        g_warning ("Failed to get system bus: %s", error->message);
117
 
    g_clear_error (&error);
118
 
    if (!bus)
119
 
        return;
120
 
 
121
 
    if (session_path)
 
379
    g_return_if_fail (service != NULL);
 
380
    g_return_if_fail (session_id != NULL);
 
381
 
 
382
    g_debug ("Unlocking login1 session %s", session_id);
 
383
 
 
384
    if (session_id)
122
385
    {
123
386
        GVariant *result;
124
387
 
125
 
        result = g_dbus_connection_call_sync (bus,
126
 
                                              "org.freedesktop.login1",
127
 
                                              session_path,
128
 
                                              "org.freedesktop.login1.Session",
129
 
                                              "Unlock",
130
 
                                              g_variant_new ("()"),
 
388
        result = g_dbus_connection_call_sync (service->priv->connection,
 
389
                                              LOGIN1_SERVICE_NAME,
 
390
                                              LOGIN1_OBJECT_NAME,
 
391
                                              LOGIN1_MANAGER_INTERFACE_NAME,
 
392
                                              "UnlockSession",
 
393
                                              g_variant_new ("(s)", session_id),
131
394
                                              G_VARIANT_TYPE ("()"),
132
395
                                              G_DBUS_CALL_FLAGS_NONE,
133
396
                                              -1,
139
402
        if (result)
140
403
            g_variant_unref (result);
141
404
    }
142
 
    g_object_unref (bus);
143
405
}
144
406
 
145
407
void
146
 
login1_activate_session (const gchar *session_path)
 
408
login1_service_activate_session (Login1Service *service, const gchar *session_id)
147
409
{
148
 
    GDBusConnection *bus;
149
410
    GError *error = NULL;
150
411
 
151
 
    g_return_if_fail (session_path != NULL);
152
 
 
153
 
    g_debug ("Activating login1 session %s", session_path);
154
 
 
155
 
    bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
156
 
    if (error)
157
 
        g_warning ("Failed to get system bus: %s", error->message);
158
 
    g_clear_error (&error);
159
 
    if (!bus)
160
 
        return;
161
 
 
162
 
    if (session_path)
 
412
    g_return_if_fail (service != NULL);
 
413
    g_return_if_fail (session_id != NULL);
 
414
 
 
415
    g_debug ("Activating login1 session %s", session_id);
 
416
 
 
417
    if (session_id)
163
418
    {
164
419
        GVariant *result;
165
420
 
166
 
        result = g_dbus_connection_call_sync (bus,
167
 
                                              "org.freedesktop.login1",
168
 
                                              session_path,
169
 
                                              "org.freedesktop.login1.Session",
170
 
                                              "Activate",
171
 
                                              g_variant_new ("()"),
 
421
        result = g_dbus_connection_call_sync (service->priv->connection,
 
422
                                              LOGIN1_SERVICE_NAME,
 
423
                                              LOGIN1_OBJECT_NAME,
 
424
                                              LOGIN1_MANAGER_INTERFACE_NAME,
 
425
                                              "ActivateSession",
 
426
                                              g_variant_new ("(s)", session_id),
172
427
                                              G_VARIANT_TYPE ("()"),
173
428
                                              G_DBUS_CALL_FLAGS_NONE,
174
429
                                              -1,
180
435
        if (result)
181
436
            g_variant_unref (result);
182
437
    }
183
 
    g_object_unref (bus);
 
438
}
 
439
 
 
440
static void
 
441
login1_service_init (Login1Service *service)
 
442
{
 
443
    service->priv = G_TYPE_INSTANCE_GET_PRIVATE (service, LOGIN1_SERVICE_TYPE, Login1ServicePrivate);
 
444
}
 
445
 
 
446
static void
 
447
login1_service_finalize (GObject *object)
 
448
{
 
449
    Login1Service *self = LOGIN1_SERVICE (object);
 
450
 
 
451
    g_list_free_full (self->priv->seats, g_object_unref);
 
452
    g_dbus_connection_signal_unsubscribe (self->priv->connection, self->priv->signal_id);
 
453
    g_object_unref (self->priv->connection);
 
454
 
 
455
    G_OBJECT_CLASS (login1_service_parent_class)->finalize (object);
 
456
}
 
457
 
 
458
static void
 
459
login1_service_class_init (Login1ServiceClass *klass)
 
460
{
 
461
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
462
 
 
463
    object_class->finalize = login1_service_finalize;
 
464
 
 
465
    g_type_class_add_private (klass, sizeof (Login1ServicePrivate));
 
466
 
 
467
    service_signals[SEAT_ADDED] =
 
468
        g_signal_new (LOGIN1_SERVICE_SIGNAL_SEAT_ADDED,
 
469
                      G_TYPE_FROM_CLASS (klass),
 
470
                      G_SIGNAL_RUN_LAST,
 
471
                      G_STRUCT_OFFSET (Login1ServiceClass, seat_added),
 
472
                      NULL, NULL,
 
473
                      NULL,
 
474
                      G_TYPE_NONE, 1, LOGIN1_SEAT_TYPE);
 
475
    service_signals[SEAT_REMOVED] =
 
476
        g_signal_new (LOGIN1_SERVICE_SIGNAL_SEAT_REMOVED,
 
477
                      G_TYPE_FROM_CLASS (klass),
 
478
                      G_SIGNAL_RUN_LAST,
 
479
                      G_STRUCT_OFFSET (Login1ServiceClass, seat_removed),
 
480
                      NULL, NULL,
 
481
                      NULL,
 
482
                      G_TYPE_NONE, 1, LOGIN1_SEAT_TYPE);
 
483
}
 
484
 
 
485
const gchar *
 
486
login1_seat_get_id (Login1Seat *seat)
 
487
{
 
488
    g_return_val_if_fail (seat != NULL, NULL);
 
489
    return seat->priv->id;
 
490
}
 
491
 
 
492
gboolean
 
493
login1_seat_get_can_graphical (Login1Seat *seat)
 
494
{
 
495
    g_return_val_if_fail (seat != NULL, FALSE);
 
496
    return seat->priv->can_graphical;
 
497
}
 
498
 
 
499
gboolean
 
500
login1_seat_get_can_multi_session (Login1Seat *seat)
 
501
{
 
502
    g_return_val_if_fail (seat != NULL, FALSE);
 
503
    return seat->priv->can_multi_session;
 
504
}
 
505
 
 
506
static void
 
507
login1_seat_init (Login1Seat *seat)
 
508
{
 
509
    seat->priv = G_TYPE_INSTANCE_GET_PRIVATE (seat, LOGIN1_SEAT_TYPE, Login1SeatPrivate);
 
510
}
 
511
 
 
512
static void
 
513
login1_seat_finalize (GObject *object)
 
514
{
 
515
    Login1Seat *self = LOGIN1_SEAT (object);
 
516
 
 
517
    g_free (self->priv->id);
 
518
    g_free (self->priv->path);
 
519
    g_dbus_connection_signal_unsubscribe (self->priv->connection, self->priv->signal_id);
 
520
    g_object_unref (self->priv->connection);
 
521
 
 
522
    G_OBJECT_CLASS (login1_seat_parent_class)->finalize (object);
 
523
}
 
524
 
 
525
static void
 
526
login1_seat_class_init (Login1SeatClass *klass)
 
527
{
 
528
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
529
 
 
530
    object_class->finalize = login1_seat_finalize;
 
531
 
 
532
    g_type_class_add_private (klass, sizeof (Login1SeatPrivate));
 
533
 
 
534
    seat_signals[CAN_GRAPHICAL_CHANGED] =
 
535
        g_signal_new (LOGIN1_SEAT_SIGNAL_CAN_GRAPHICAL_CHANGED,
 
536
                      G_TYPE_FROM_CLASS (klass),
 
537
                      G_SIGNAL_RUN_LAST,
 
538
                      G_STRUCT_OFFSET (Login1SeatClass, can_graphical_changed),
 
539
                      NULL, NULL,
 
540
                      NULL,
 
541
                      G_TYPE_NONE, 0);
 
542
 
 
543
    seat_signals[ACTIVE_SESSION_CHANGED] =
 
544
        g_signal_new (LOGIN1_SIGNAL_ACTIVE_SESION_CHANGED,
 
545
                      G_TYPE_FROM_CLASS (klass),
 
546
                      G_SIGNAL_RUN_LAST,
 
547
                      G_STRUCT_OFFSET (Login1SeatClass, active_session_changed),
 
548
                      NULL, NULL,
 
549
                      NULL,
 
550
                      G_TYPE_NONE, 1, G_TYPE_STRING);
184
551
}