source: proiecte/PPPP/gdm/daemon/gdm-factory-slave.c @ 134

Last change on this file since 134 was 134, checked in by (none), 14 years ago

gdm sources with the modifications for webcam

File size: 31.4 KB
Line 
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21#include "config.h"
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <fcntl.h>
26#include <unistd.h>
27#include <string.h>
28#include <sys/types.h>
29#include <sys/wait.h>
30#include <errno.h>
31#include <pwd.h>
32#include <grp.h>
33
34#include <glib.h>
35#include <glib/gi18n.h>
36#include <glib/gstdio.h>
37#include <glib-object.h>
38
39#define DBUS_API_SUBJECT_TO_CHANGE
40#include <dbus/dbus-glib.h>
41#include <dbus/dbus-glib-lowlevel.h>
42
43#include <X11/Xlib.h> /* for Display */
44
45#include "gdm-common.h"
46
47#include "gdm-factory-slave.h"
48#include "gdm-factory-slave-glue.h"
49
50#include "gdm-server.h"
51#include "gdm-greeter-session.h"
52#include "gdm-greeter-server.h"
53
54#include "gdm-session-relay.h"
55
56extern char **environ;
57
58#define GDM_FACTORY_SLAVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_FACTORY_SLAVE, GdmFactorySlavePrivate))
59
60#define GDM_DBUS_NAME                            "org.gnome.DisplayManager"
61#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH      "/org/gnome/DisplayManager/LocalDisplayFactory"
62#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE "org.gnome.DisplayManager.LocalDisplayFactory"
63
64#define MAX_CONNECT_ATTEMPTS 10
65
66struct GdmFactorySlavePrivate
67{
68        char              *id;
69        GPid               pid;
70        guint              greeter_reset_id;
71
72        GPid               server_pid;
73        Display           *server_display;
74        guint              connection_attempts;
75
76        GdmServer         *server;
77        GdmSessionRelay   *session;
78        GdmGreeterServer  *greeter_server;
79        GdmGreeterSession *greeter;
80        DBusGProxy        *factory_proxy;
81        DBusGConnection   *connection;
82};
83
84enum {
85        PROP_0,
86};
87
88static void     gdm_factory_slave_class_init    (GdmFactorySlaveClass *klass);
89static void     gdm_factory_slave_init          (GdmFactorySlave      *factory_slave);
90static void     gdm_factory_slave_finalize      (GObject             *object);
91
92G_DEFINE_TYPE (GdmFactorySlave, gdm_factory_slave, GDM_TYPE_SLAVE)
93
94static gboolean
95greeter_reset_timeout (GdmFactorySlave *slave)
96{
97        gdm_greeter_server_reset (slave->priv->greeter_server);
98        slave->priv->greeter_reset_id = 0;
99        return FALSE;
100}
101
102static void
103queue_greeter_reset (GdmFactorySlave *slave)
104{
105        if (slave->priv->greeter_reset_id > 0) {
106                return;
107        }
108
109        slave->priv->greeter_reset_id = g_timeout_add_seconds (2, (GSourceFunc)greeter_reset_timeout, slave);
110}
111
112static void
113on_greeter_session_start (GdmGreeterSession *greeter,
114                          GdmFactorySlave   *slave)
115{
116        g_debug ("GdmFactorySlave: Greeter started");
117}
118
119static void
120on_greeter_session_stop (GdmGreeterSession *greeter,
121                         GdmFactorySlave   *slave)
122{
123        g_debug ("GdmFactorySlave: Greeter stopped");
124}
125
126static void
127on_greeter_session_exited (GdmGreeterSession    *greeter,
128                           int                   code,
129                           GdmFactorySlave      *slave)
130{
131        g_debug ("GdmSimpleSlave: Greeter exited: %d", code);
132        gdm_slave_stopped (GDM_SLAVE (slave));
133}
134
135static void
136on_greeter_session_died (GdmGreeterSession    *greeter,
137                         int                   signal,
138                         GdmFactorySlave      *slave)
139{
140        g_debug ("GdmSimpleSlave: Greeter died: %d", signal);
141        gdm_slave_stopped (GDM_SLAVE (slave));
142}
143
144
145static void
146on_session_info (GdmSession      *session,
147                 const char      *text,
148                 GdmFactorySlave *slave)
149{
150        g_debug ("GdmFactorySlave: Info: %s", text);
151        gdm_greeter_server_info (slave->priv->greeter_server, text);
152}
153
154static void
155on_session_problem (GdmSession      *session,
156                    const char      *text,
157                    GdmFactorySlave *slave)
158{
159        g_debug ("GdmFactorySlave: Problem: %s", text);
160        gdm_greeter_server_problem (slave->priv->greeter_server, text);
161}
162
163static void
164on_session_info_query (GdmSession      *session,
165                       const char      *text,
166                       GdmFactorySlave *slave)
167{
168
169        g_debug ("GdmFactorySlave: Info query: %s", text);
170        gdm_greeter_server_info_query (slave->priv->greeter_server, text);
171}
172
173static void
174on_session_secret_info_query (GdmSession      *session,
175                              const char      *text,
176                              GdmFactorySlave *slave)
177{
178        g_debug ("GdmFactorySlave: Secret info query: %s", text);
179        gdm_greeter_server_secret_info_query (slave->priv->greeter_server, text);
180}
181
182static void
183on_session_opened (GdmSession      *session,
184                   GdmFactorySlave *slave)
185{
186        g_debug ("GdmFactorySlave:  session opened");
187
188        gdm_greeter_server_ready (slave->priv->greeter_server);
189}
190
191static void
192on_session_setup_complete (GdmSession      *session,
193                           GdmFactorySlave *slave)
194{
195        gdm_session_authenticate (session);
196}
197
198static void
199on_session_setup_failed (GdmSession      *session,
200                         const char      *message,
201                         GdmFactorySlave *slave)
202{
203        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to initialize login system"));
204
205        queue_greeter_reset (slave);
206}
207
208static void
209on_session_reset_complete (GdmSession      *session,
210                           GdmFactorySlave *slave)
211{
212        g_debug ("GdmFactorySlave: PAM reset");
213}
214
215static void
216on_session_reset_failed (GdmSession      *session,
217                         const char      *message,
218                         GdmFactorySlave *slave)
219{
220        g_critical ("Unable to reset PAM");
221}
222
223static void
224on_session_authenticated (GdmSession      *session,
225                          GdmFactorySlave *slave)
226{
227        gdm_session_authorize (session);
228}
229
230static void
231on_session_authentication_failed (GdmSession      *session,
232                                  const char      *message,
233                                  GdmFactorySlave *slave)
234{
235        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to authenticate user"));
236
237        queue_greeter_reset (slave);
238}
239
240static void
241on_session_authorized (GdmSession      *session,
242                       GdmFactorySlave *slave)
243{
244        int flag;
245
246        /* FIXME: check for migration? */
247        flag = GDM_SESSION_CRED_ESTABLISH;
248
249        gdm_session_accredit (session, flag);
250}
251
252static void
253on_session_authorization_failed (GdmSession      *session,
254                                 const char      *message,
255                                 GdmFactorySlave *slave)
256{
257        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to authorize user"));
258
259        queue_greeter_reset (slave);
260}
261
262static void
263on_session_accredited (GdmSession      *session,
264                       GdmFactorySlave *slave)
265{
266        g_debug ("GdmFactorySlave:  session user verified");
267
268        gdm_session_start_session (session);
269
270        gdm_greeter_server_reset (slave->priv->greeter_server);
271}
272
273static void
274on_session_accreditation_failed (GdmSession      *session,
275                                 const char      *message,
276                                 GdmFactorySlave *slave)
277{
278        g_debug ("GdmFactorySlave: could not successfully authenticate user: %s",
279                 message);
280
281        gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to establish credentials"));
282
283        queue_greeter_reset (slave);
284}
285
286static void
287on_session_session_started (GdmSession      *session,
288                            GdmFactorySlave *slave)
289{
290        g_debug ("GdmFactorySlave: Relay session started");
291
292        gdm_greeter_server_reset (slave->priv->greeter_server);
293}
294
295static gboolean
296create_product_display (GdmFactorySlave *slave)
297{
298        char    *parent_display_id;
299        char    *server_address;
300        char    *product_id;
301        GError  *error;
302        gboolean res;
303        gboolean ret;
304
305        ret = FALSE;
306
307        g_debug ("GdmFactorySlave: Create product display");
308
309        g_debug ("GdmFactorySlave: Connecting to local display factory");
310        slave->priv->factory_proxy = dbus_g_proxy_new_for_name (slave->priv->connection,
311                                                                GDM_DBUS_NAME,
312                                                                GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH,
313                                                                GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE);
314        if (slave->priv->factory_proxy == NULL) {
315                g_warning ("Failed to create local display factory proxy");
316                goto out;
317        }
318
319        server_address = gdm_session_relay_get_address (slave->priv->session);
320
321        g_object_get (slave,
322                      "display-id", &parent_display_id,
323                      NULL);
324
325        error = NULL;
326        res = dbus_g_proxy_call (slave->priv->factory_proxy,
327                                 "CreateProductDisplay",
328                                 &error,
329                                 DBUS_TYPE_G_OBJECT_PATH, parent_display_id,
330                                 G_TYPE_STRING, server_address,
331                                 G_TYPE_INVALID,
332                                 DBUS_TYPE_G_OBJECT_PATH, &product_id,
333                                 G_TYPE_INVALID);
334        g_free (server_address);
335        g_free (parent_display_id);
336
337        if (! res) {
338                if (error != NULL) {
339                        g_warning ("Failed to create product display: %s", error->message);
340                        g_error_free (error);
341                } else {
342                        g_warning ("Failed to create product display");
343                }
344                goto out;
345        }
346
347        ret = TRUE;
348
349 out:
350        return ret;
351}
352
353static void
354on_session_relay_disconnected (GdmSessionRelay *session,
355                               GdmFactorySlave *slave)
356{
357        g_debug ("GdmFactorySlave: Relay disconnected");
358
359        /* FIXME: do some kind of loop detection */
360        gdm_greeter_server_reset (slave->priv->greeter_server);
361        create_product_display (slave);
362}
363
364static void
365on_session_relay_connected (GdmSessionRelay *session,
366                            GdmFactorySlave *slave)
367{
368        g_debug ("GdmFactorySlave: Relay Connected");
369
370        gdm_session_open (GDM_SESSION (slave->priv->session));
371}
372
373static void
374on_greeter_begin_verification (GdmGreeterServer *greeter_server,
375                               GdmFactorySlave  *slave)
376{
377        g_debug ("GdmFactorySlave: begin verification");
378        gdm_session_setup (GDM_SESSION (slave->priv->session),
379                           "gdm");
380}
381
382static void
383on_greeter_begin_verification_for_user (GdmGreeterServer *greeter_server,
384                                        const char       *username,
385                                        GdmFactorySlave  *slave)
386{
387        g_debug ("GdmFactorySlave: begin verification for user");
388        gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
389                                    "gdm",
390                                    username);
391}
392
393static void
394on_greeter_answer (GdmGreeterServer *greeter_server,
395                   const char       *text,
396                   GdmFactorySlave  *slave)
397{
398        g_debug ("GdmFactorySlave: Greeter answer");
399        gdm_session_answer_query (GDM_SESSION (slave->priv->session), text);
400}
401
402static void
403on_greeter_session_selected (GdmGreeterServer *greeter_server,
404                             const char       *text,
405                             GdmFactorySlave  *slave)
406{
407        gdm_session_select_session (GDM_SESSION (slave->priv->session), text);
408}
409
410static void
411on_greeter_language_selected (GdmGreeterServer *greeter_server,
412                              const char       *text,
413                              GdmFactorySlave  *slave)
414{
415        gdm_session_select_language (GDM_SESSION (slave->priv->session), text);
416}
417
418static void
419on_greeter_layout_selected (GdmGreeterServer *greeter_server,
420                            const char       *text,
421                            GdmFactorySlave  *slave)
422{
423        gdm_session_select_layout (GDM_SESSION (slave->priv->session), text);
424}
425
426static void
427on_greeter_user_selected (GdmGreeterServer *greeter_server,
428                          const char       *text,
429                          GdmFactorySlave  *slave)
430{
431        gdm_session_select_user (GDM_SESSION (slave->priv->session), text);
432}
433
434static void
435on_greeter_cancel (GdmGreeterServer *greeter_server,
436                   GdmFactorySlave  *slave)
437{
438        gdm_session_cancel (GDM_SESSION (slave->priv->session));
439}
440
441static void
442on_greeter_connected (GdmGreeterServer *greeter_server,
443                      GdmFactorySlave  *slave)
444{
445        g_debug ("GdmFactorySlave: Greeter started");
446
447        create_product_display (slave);
448}
449
450static void
451setup_server (GdmFactorySlave *slave)
452{
453        /* Set the busy cursor */
454        gdm_slave_set_busy_cursor (GDM_SLAVE (slave));
455}
456
457static void
458run_greeter (GdmFactorySlave *slave)
459{
460        gboolean       display_is_local;
461        char          *display_id;
462        char          *display_name;
463        char          *display_device;
464        char          *display_hostname;
465        char          *auth_file;
466        char          *address;
467
468        g_debug ("GdmFactorySlave: Running greeter");
469
470        display_is_local = FALSE;
471        display_id = NULL;
472        display_name = NULL;
473        auth_file = NULL;
474        display_device = NULL;
475        display_hostname = NULL;
476
477        g_object_get (slave,
478                      "display-is-local", &display_is_local,
479                      "display-id", &display_id,
480                      "display-name", &display_name,
481                      "display-hostname", &display_hostname,
482                      "display-x11-authority-file", &auth_file,
483                      NULL);
484
485        if (slave->priv->server != NULL) {
486                display_device = gdm_server_get_display_device (slave->priv->server);
487        }
488
489        /* FIXME: send a signal back to the master */
490
491        /* Run the init script. gdmslave suspends until script has terminated */
492        gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
493
494        slave->priv->greeter_server = gdm_greeter_server_new (display_id);
495        g_signal_connect (slave->priv->greeter_server,
496                          "begin-verification",
497                          G_CALLBACK (on_greeter_begin_verification),
498                          slave);
499        g_signal_connect (slave->priv->greeter_server,
500                          "begin-verification-for-user",
501                          G_CALLBACK (on_greeter_begin_verification_for_user),
502                          slave);
503        g_signal_connect (slave->priv->greeter_server,
504                          "query-answer",
505                          G_CALLBACK (on_greeter_answer),
506                          slave);
507        g_signal_connect (slave->priv->greeter_server,
508                          "session-selected",
509                          G_CALLBACK (on_greeter_session_selected),
510                          slave);
511        g_signal_connect (slave->priv->greeter_server,
512                          "language-selected",
513                          G_CALLBACK (on_greeter_language_selected),
514                          slave);
515        g_signal_connect (slave->priv->greeter_server,
516                          "layout-selected",
517                          G_CALLBACK (on_greeter_layout_selected),
518                          slave);
519        g_signal_connect (slave->priv->greeter_server,
520                          "user-selected",
521                          G_CALLBACK (on_greeter_user_selected),
522                          slave);
523        g_signal_connect (slave->priv->greeter_server,
524                          "connected",
525                          G_CALLBACK (on_greeter_connected),
526                          slave);
527        g_signal_connect (slave->priv->greeter_server,
528                          "cancelled",
529                          G_CALLBACK (on_greeter_cancel),
530                          slave);
531        gdm_greeter_server_start (slave->priv->greeter_server);
532
533        address = gdm_greeter_server_get_address (slave->priv->greeter_server);
534
535        g_debug ("GdmFactorySlave: Creating greeter on %s %s", display_name, display_device);
536        slave->priv->greeter = gdm_greeter_session_new (display_name,
537                                                        display_device,
538                                                        display_hostname,
539                                                        display_is_local);
540        g_signal_connect (slave->priv->greeter,
541                          "started",
542                          G_CALLBACK (on_greeter_session_start),
543                          slave);
544        g_signal_connect (slave->priv->greeter,
545                          "stopped",
546                          G_CALLBACK (on_greeter_session_stop),
547                          slave);
548        g_signal_connect (slave->priv->greeter,
549                          "exited",
550                          G_CALLBACK (on_greeter_session_exited),
551                          slave);
552        g_signal_connect (slave->priv->greeter,
553                          "died",
554                          G_CALLBACK (on_greeter_session_died),
555                          slave);
556        g_object_set (slave->priv->greeter,
557                      "x11-authority-file", auth_file,
558                      NULL);
559        gdm_welcome_session_set_server_address (GDM_WELCOME_SESSION (slave->priv->greeter), address);
560        gdm_welcome_session_start (GDM_WELCOME_SESSION (slave->priv->greeter));
561
562        g_free (address);
563
564        g_free (display_id);
565        g_free (display_name);
566        g_free (display_device);
567        g_free (display_hostname);
568        g_free (auth_file);
569}
570
571static gboolean
572idle_connect_to_display (GdmFactorySlave *slave)
573{
574        gboolean res;
575
576        slave->priv->connection_attempts++;
577
578        g_debug ("GdmFactorySlave: Connect to display");
579
580        res = gdm_slave_connect_to_x11_display (GDM_SLAVE (slave));
581        if (res) {
582                /* FIXME: handle wait-for-go */
583
584                setup_server (slave);
585                run_greeter (slave);
586        } else {
587                if (slave->priv->connection_attempts >= MAX_CONNECT_ATTEMPTS) {
588                        g_warning ("Unable to connect to display after %d tries - bailing out", slave->priv->connection_attempts);
589                        exit (1);
590                }
591                return TRUE;
592        }
593
594        return FALSE;
595}
596
597static void
598on_server_ready (GdmServer       *server,
599                 GdmFactorySlave *slave)
600{
601        g_debug ("GdmFactorySlave: Server ready");
602
603        g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
604}
605
606static void
607on_server_exited (GdmServer       *server,
608                  int              exit_code,
609                  GdmFactorySlave *slave)
610{
611        g_debug ("GdmFactorySlave: server exited with code %d\n", exit_code);
612
613        gdm_slave_stopped (GDM_SLAVE (slave));
614}
615
616static void
617on_server_died (GdmServer       *server,
618                int              signal_number,
619                GdmFactorySlave *slave)
620{
621        g_debug ("GdmFactorySlave: server died with signal %d, (%s)",
622                 signal_number,
623                 g_strsignal (signal_number));
624
625        gdm_slave_stopped (GDM_SLAVE (slave));
626}
627
628static gboolean
629gdm_factory_slave_run (GdmFactorySlave *slave)
630{
631        char    *display_name;
632        char    *auth_file;
633        gboolean display_is_local;
634
635        g_object_get (slave,
636                      "display-is-local", &display_is_local,
637                      "display-name", &display_name,
638                      "display-x11-authority-file", &auth_file,
639                      NULL);
640
641        /* if this is local display start a server if one doesn't
642         * exist */
643        if (display_is_local) {
644                gboolean res;
645
646                slave->priv->server = gdm_server_new (display_name, auth_file);
647                g_signal_connect (slave->priv->server,
648                                  "exited",
649                                  G_CALLBACK (on_server_exited),
650                                  slave);
651                g_signal_connect (slave->priv->server,
652                                  "died",
653                                  G_CALLBACK (on_server_died),
654                                  slave);
655                g_signal_connect (slave->priv->server,
656                                  "ready",
657                                  G_CALLBACK (on_server_ready),
658                                  slave);
659
660                res = gdm_server_start (slave->priv->server);
661                if (! res) {
662                        g_warning (_("Could not start the X "
663                                     "server (your graphical environment) "
664                                     "due to some internal error. "
665                                     "Please contact your system administrator "
666                                     "or check your syslog to diagnose. "
667                                     "In the meantime this display will be "
668                                     "disabled.  Please restart GDM when "
669                                     "the problem is corrected."));
670                        exit (1);
671                }
672
673                g_debug ("GdmFactorySlave: Started X server");
674        } else {
675                g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
676        }
677
678        g_free (display_name);
679        g_free (auth_file);
680
681        return TRUE;
682}
683
684static gboolean
685gdm_factory_slave_start (GdmSlave *slave)
686{
687        gboolean ret;
688
689        ret = FALSE;
690
691        g_debug ("GdmFactorySlave: Starting factory slave");
692
693        GDM_SLAVE_CLASS (gdm_factory_slave_parent_class)->start (slave);
694
695        GDM_FACTORY_SLAVE (slave)->priv->session = gdm_session_relay_new ();
696        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
697                          "opened",
698                          G_CALLBACK (on_session_opened),
699                          slave);
700        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
701                          "setup-complete",
702                          G_CALLBACK (on_session_setup_complete),
703                          slave);
704        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
705                          "setup-failed",
706                          G_CALLBACK (on_session_setup_failed),
707                          slave);
708        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
709                          "reset-complete",
710                          G_CALLBACK (on_session_reset_complete),
711                          slave);
712        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
713                          "reset-failed",
714                          G_CALLBACK (on_session_reset_failed),
715                          slave);
716        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
717                          "authenticated",
718                          G_CALLBACK (on_session_authenticated),
719                          slave);
720        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
721                          "authentication-failed",
722                          G_CALLBACK (on_session_authentication_failed),
723                          slave);
724        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
725                          "authorized",
726                          G_CALLBACK (on_session_authorized),
727                          slave);
728        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
729                          "authorization-failed",
730                          G_CALLBACK (on_session_authorization_failed),
731                          slave);
732        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
733                          "accredited",
734                          G_CALLBACK (on_session_accredited),
735                          slave);
736        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
737                          "accreditation-failed",
738                          G_CALLBACK (on_session_accreditation_failed),
739                          slave);
740        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
741                          "info",
742                          G_CALLBACK (on_session_info),
743                          slave);
744        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
745                          "problem",
746                          G_CALLBACK (on_session_problem),
747                          slave);
748        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
749                          "info-query",
750                          G_CALLBACK (on_session_info_query),
751                          slave);
752        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
753                          "secret-info-query",
754                          G_CALLBACK (on_session_secret_info_query),
755                          slave);
756        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
757                          "session-started",
758                          G_CALLBACK (on_session_session_started),
759                          slave);
760
761        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
762                          "connected",
763                          G_CALLBACK (on_session_relay_connected),
764                          slave);
765        g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
766                          "disconnected",
767                          G_CALLBACK (on_session_relay_disconnected),
768                          slave);
769
770        gdm_session_relay_start (GDM_FACTORY_SLAVE (slave)->priv->session);
771
772        gdm_factory_slave_run (GDM_FACTORY_SLAVE (slave));
773
774        ret = TRUE;
775
776        return ret;
777}
778
779static gboolean
780gdm_factory_slave_stop (GdmSlave *slave)
781{
782        g_debug ("GdmFactorySlave: Stopping factory_slave");
783
784        GDM_SLAVE_CLASS (gdm_factory_slave_parent_class)->stop (slave);
785
786        if (GDM_FACTORY_SLAVE (slave)->priv->session != NULL) {
787                gdm_session_relay_stop (GDM_FACTORY_SLAVE (slave)->priv->session);
788                g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->session);
789                GDM_FACTORY_SLAVE (slave)->priv->session = NULL;
790        }
791
792        if (GDM_FACTORY_SLAVE (slave)->priv->greeter_server != NULL) {
793                gdm_greeter_server_stop (GDM_FACTORY_SLAVE (slave)->priv->greeter_server);
794                g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->greeter_server);
795                GDM_FACTORY_SLAVE (slave)->priv->greeter_server = NULL;
796        }
797
798        if (GDM_FACTORY_SLAVE (slave)->priv->greeter != NULL) {
799                gdm_welcome_session_stop (GDM_WELCOME_SESSION (GDM_FACTORY_SLAVE (slave)->priv->greeter));
800                g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->greeter);
801                GDM_FACTORY_SLAVE (slave)->priv->greeter = NULL;
802        }
803
804        if (GDM_FACTORY_SLAVE (slave)->priv->server != NULL) {
805                gdm_server_stop (GDM_FACTORY_SLAVE (slave)->priv->server);
806                g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->server);
807                GDM_FACTORY_SLAVE (slave)->priv->server = NULL;
808        }
809
810        if (GDM_FACTORY_SLAVE (slave)->priv->factory_proxy != NULL) {
811                g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->factory_proxy);
812        }
813
814        return TRUE;
815}
816
817static void
818gdm_factory_slave_set_property (GObject      *object,
819                               guint          prop_id,
820                               const GValue *value,
821                               GParamSpec   *pspec)
822{
823        switch (prop_id) {
824        default:
825                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
826                break;
827        }
828}
829
830static void
831gdm_factory_slave_get_property (GObject    *object,
832                                guint       prop_id,
833                                GValue     *value,
834                                GParamSpec *pspec)
835{
836        switch (prop_id) {
837        default:
838                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
839                break;
840        }
841}
842
843static GObject *
844gdm_factory_slave_constructor (GType                  type,
845                               guint                  n_construct_properties,
846                               GObjectConstructParam *construct_properties)
847{
848        GdmFactorySlave      *factory_slave;
849
850        factory_slave = GDM_FACTORY_SLAVE (G_OBJECT_CLASS (gdm_factory_slave_parent_class)->constructor (type,
851                                                                                                         n_construct_properties,
852                                                                                                         construct_properties));
853
854        return G_OBJECT (factory_slave);
855}
856
857static void
858gdm_factory_slave_class_init (GdmFactorySlaveClass *klass)
859{
860        GObjectClass  *object_class = G_OBJECT_CLASS (klass);
861        GdmSlaveClass *slave_class = GDM_SLAVE_CLASS (klass);
862
863        object_class->get_property = gdm_factory_slave_get_property;
864        object_class->set_property = gdm_factory_slave_set_property;
865        object_class->constructor = gdm_factory_slave_constructor;
866        object_class->finalize = gdm_factory_slave_finalize;
867
868        slave_class->start = gdm_factory_slave_start;
869        slave_class->stop = gdm_factory_slave_stop;
870
871        g_type_class_add_private (klass, sizeof (GdmFactorySlavePrivate));
872
873        dbus_g_object_type_install_info (GDM_TYPE_FACTORY_SLAVE, &dbus_glib_gdm_factory_slave_object_info);
874}
875
876static void
877gdm_factory_slave_init (GdmFactorySlave *slave)
878{
879        GError *error;
880
881        slave->priv = GDM_FACTORY_SLAVE_GET_PRIVATE (slave);
882
883        slave->priv->pid = -1;
884
885        error = NULL;
886        slave->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
887        if (slave->priv->connection == NULL) {
888                if (error != NULL) {
889                        g_critical ("error getting system bus: %s", error->message);
890                        g_error_free (error);
891                }
892                exit (1);
893        }
894}
895
896static void
897gdm_factory_slave_finalize (GObject *object)
898{
899        GdmFactorySlave *factory_slave;
900
901        g_return_if_fail (object != NULL);
902        g_return_if_fail (GDM_IS_FACTORY_SLAVE (object));
903
904        factory_slave = GDM_FACTORY_SLAVE (object);
905
906        g_debug ("GdmFactorySlave: Finalizing slave");
907
908        g_return_if_fail (factory_slave->priv != NULL);
909
910        gdm_factory_slave_stop (GDM_SLAVE (factory_slave));
911
912        if (factory_slave->priv->greeter_reset_id > 0) {
913                g_source_remove (factory_slave->priv->greeter_reset_id);
914                factory_slave->priv->greeter_reset_id = 0;
915        }
916
917        G_OBJECT_CLASS (gdm_factory_slave_parent_class)->finalize (object);
918}
919
920GdmSlave *
921gdm_factory_slave_new (const char *id)
922{
923        GObject *object;
924
925        object = g_object_new (GDM_TYPE_FACTORY_SLAVE,
926                               "display-id", id,
927                               NULL);
928
929        return GDM_SLAVE (object);
930}
Note: See TracBrowser for help on using the repository browser.