source: proiecte/PPPP/gdm/daemon/gdm-xdmcp-chooser-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: 14.0 KB
Line 
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., 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
32#include <glib.h>
33#include <glib/gi18n.h>
34#include <glib/gstdio.h>
35#include <glib-object.h>
36
37#define DBUS_API_SUBJECT_TO_CHANGE
38#include <dbus/dbus-glib.h>
39#include <dbus/dbus-glib-lowlevel.h>
40
41#include <X11/Xlib.h> /* for Display */
42
43#include "gdm-common.h"
44
45#include "gdm-xdmcp-chooser-slave.h"
46#include "gdm-xdmcp-chooser-slave-glue.h"
47
48#include "gdm-server.h"
49#include "gdm-chooser-server.h"
50#include "gdm-chooser-session.h"
51#include "gdm-settings-direct.h"
52#include "gdm-settings-keys.h"
53
54#define GDM_XDMCP_CHOOSER_SLAVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_XDMCP_CHOOSER_SLAVE, GdmXdmcpChooserSlavePrivate))
55
56#define GDM_DBUS_NAME              "org.gnome.DisplayManager"
57#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display"
58
59#define MAX_CONNECT_ATTEMPTS  10
60#define DEFAULT_PING_INTERVAL 15
61
62struct GdmXdmcpChooserSlavePrivate
63{
64        char              *id;
65        GPid               pid;
66
67        int                ping_interval;
68
69        guint              connection_attempts;
70
71        GdmChooserServer  *chooser_server;
72        GdmChooserSession *chooser;
73};
74
75enum {
76        PROP_0,
77};
78
79enum {
80        HOSTNAME_SELECTED,
81        LAST_SIGNAL
82};
83
84static guint signals [LAST_SIGNAL] = { 0, };
85
86static void     gdm_xdmcp_chooser_slave_class_init     (GdmXdmcpChooserSlaveClass *klass);
87static void     gdm_xdmcp_chooser_slave_init           (GdmXdmcpChooserSlave      *xdmcp_chooser_slave);
88static void     gdm_xdmcp_chooser_slave_finalize       (GObject                   *object);
89
90G_DEFINE_TYPE (GdmXdmcpChooserSlave, gdm_xdmcp_chooser_slave, GDM_TYPE_SLAVE)
91
92
93static void
94on_chooser_session_start (GdmChooserSession    *chooser,
95                          GdmXdmcpChooserSlave *slave)
96{
97        g_debug ("GdmXdmcpChooserSlave: Chooser started");
98}
99
100static void
101on_chooser_session_stop (GdmChooserSession    *chooser,
102                         GdmXdmcpChooserSlave *slave)
103{
104        g_debug ("GdmXdmcpChooserSlave: Chooser stopped");
105        gdm_slave_stopped (GDM_SLAVE (slave));
106}
107
108static void
109on_chooser_session_exited (GdmChooserSession    *chooser,
110                           int                   code,
111                           GdmXdmcpChooserSlave *slave)
112{
113        g_debug ("GdmXdmcpChooserSlave: Chooser exited: %d", code);
114        gdm_slave_stopped (GDM_SLAVE (slave));
115}
116
117static void
118on_chooser_session_died (GdmChooserSession    *chooser,
119                         int                   signal,
120                         GdmXdmcpChooserSlave *slave)
121{
122        g_debug ("GdmXdmcpChooserSlave: Chooser died: %d", signal);
123        gdm_slave_stopped (GDM_SLAVE (slave));
124}
125
126static void
127on_chooser_hostname_selected (GdmChooserServer     *chooser_server,
128                              const char           *name,
129                              GdmXdmcpChooserSlave *slave)
130{
131        g_debug ("GdmXdmcpChooserSlave: emitting hostname selected: %s", name);
132        g_signal_emit (slave, signals [HOSTNAME_SELECTED], 0, name);
133}
134
135static void
136on_chooser_disconnected (GdmChooserServer     *chooser_server,
137                         GdmXdmcpChooserSlave *slave)
138{
139        g_debug ("GdmXdmcpChooserSlave: Chooser disconnected");
140
141        /* stop pinging */
142        alarm (0);
143
144        gdm_slave_stopped (GDM_SLAVE (slave));
145}
146
147static void
148on_chooser_connected (GdmChooserServer     *chooser_server,
149                      GdmXdmcpChooserSlave *slave)
150{
151        g_debug ("GdmXdmcpChooserSlave: Chooser connected");
152}
153
154static void
155setup_server (GdmXdmcpChooserSlave *slave)
156{
157        /* Set the busy cursor */
158        gdm_slave_set_busy_cursor (GDM_SLAVE (slave));
159}
160
161static void
162run_chooser (GdmXdmcpChooserSlave *slave)
163{
164        char          *display_id;
165        char          *display_name;
166        char          *display_device;
167        char          *display_hostname;
168        char          *auth_file;
169        char          *address;
170        gboolean       res;
171
172        g_debug ("GdmXdmcpChooserSlave: Running chooser");
173
174        display_id = NULL;
175        display_name = NULL;
176        auth_file = NULL;
177        display_device = NULL;
178        display_hostname = NULL;
179
180        g_object_get (slave,
181                      "display-id", &display_id,
182                      "display-name", &display_name,
183                      "display-hostname", &display_hostname,
184                      "display-x11-authority-file", &auth_file,
185                      NULL);
186
187        g_debug ("GdmXdmcpChooserSlave: Creating chooser for %s %s", display_name, display_hostname);
188
189        /* FIXME: send a signal back to the master */
190
191        /* If XDMCP setup pinging */
192        slave->priv->ping_interval = DEFAULT_PING_INTERVAL;
193        res = gdm_settings_direct_get_int (GDM_KEY_PING_INTERVAL,
194                                           &(slave->priv->ping_interval));
195
196        if (slave->priv->ping_interval > 0) {
197                alarm (slave->priv->ping_interval);
198        }
199
200        /* Run the init script. gdmslave suspends until script has terminated */
201        gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
202
203        slave->priv->chooser_server = gdm_chooser_server_new (display_id);
204        g_signal_connect (slave->priv->chooser_server,
205                          "hostname-selected",
206                          G_CALLBACK (on_chooser_hostname_selected),
207                          slave);
208        g_signal_connect (slave->priv->chooser_server,
209                          "disconnected",
210                          G_CALLBACK (on_chooser_disconnected),
211                          slave);
212        g_signal_connect (slave->priv->chooser_server,
213                          "connected",
214                          G_CALLBACK (on_chooser_connected),
215                          slave);
216        gdm_chooser_server_start (slave->priv->chooser_server);
217
218        address = gdm_chooser_server_get_address (slave->priv->chooser_server);
219
220        g_debug ("GdmXdmcpChooserSlave: Creating chooser on %s %s %s", display_name, display_device, display_hostname);
221        slave->priv->chooser = gdm_chooser_session_new (display_name,
222                                                        display_device,
223                                                        display_hostname);
224        g_signal_connect (slave->priv->chooser,
225                          "started",
226                          G_CALLBACK (on_chooser_session_start),
227                          slave);
228        g_signal_connect (slave->priv->chooser,
229                          "stopped",
230                          G_CALLBACK (on_chooser_session_stop),
231                          slave);
232        g_signal_connect (slave->priv->chooser,
233                          "exited",
234                          G_CALLBACK (on_chooser_session_exited),
235                          slave);
236        g_signal_connect (slave->priv->chooser,
237                          "died",
238                          G_CALLBACK (on_chooser_session_died),
239                          slave);
240        g_object_set (slave->priv->chooser,
241                      "x11-authority-file", auth_file,
242                      NULL);
243        gdm_welcome_session_set_server_address (GDM_WELCOME_SESSION (slave->priv->chooser), address);
244        gdm_welcome_session_start (GDM_WELCOME_SESSION (slave->priv->chooser));
245
246        g_free (display_id);
247        g_free (display_name);
248        g_free (display_device);
249        g_free (display_hostname);
250        g_free (auth_file);
251}
252
253static gboolean
254idle_connect_to_display (GdmXdmcpChooserSlave *slave)
255{
256        gboolean res;
257
258        slave->priv->connection_attempts++;
259
260        res = gdm_slave_connect_to_x11_display (GDM_SLAVE (slave));
261        if (res) {
262                /* FIXME: handle wait-for-go */
263
264                setup_server (slave);
265                run_chooser (slave);
266        } else {
267                if (slave->priv->connection_attempts >= MAX_CONNECT_ATTEMPTS) {
268                        g_warning ("Unable to connect to display after %d tries - bailing out", slave->priv->connection_attempts);
269                        exit (1);
270                }
271                return TRUE;
272        }
273
274        return FALSE;
275}
276
277static gboolean
278gdm_xdmcp_chooser_slave_run (GdmXdmcpChooserSlave *slave)
279{
280        char    *display_name;
281        char    *auth_file;
282
283        g_object_get (slave,
284                      "display-name", &display_name,
285                      "display-x11-authority-file", &auth_file,
286                      NULL);
287
288        g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
289
290        g_free (display_name);
291        g_free (auth_file);
292
293        return TRUE;
294}
295
296static gboolean
297gdm_xdmcp_chooser_slave_start (GdmSlave *slave)
298{
299        GDM_SLAVE_CLASS (gdm_xdmcp_chooser_slave_parent_class)->start (slave);
300
301        gdm_xdmcp_chooser_slave_run (GDM_XDMCP_CHOOSER_SLAVE (slave));
302
303        return TRUE;
304}
305
306static gboolean
307gdm_xdmcp_chooser_slave_stop (GdmSlave *slave)
308{
309        g_debug ("GdmXdmcpChooserSlave: Stopping xdmcp_chooser_slave");
310
311        GDM_SLAVE_CLASS (gdm_xdmcp_chooser_slave_parent_class)->stop (slave);
312
313        if (GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser != NULL) {
314                gdm_welcome_session_stop (GDM_WELCOME_SESSION (GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser));
315                g_object_unref (GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser);
316                GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser = NULL;
317        }
318
319        return TRUE;
320}
321
322static void
323gdm_xdmcp_chooser_slave_set_property (GObject      *object,
324                                      guint         prop_id,
325                                      const GValue *value,
326                                      GParamSpec   *pspec)
327{
328        switch (prop_id) {
329        default:
330                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
331                break;
332        }
333}
334
335static void
336gdm_xdmcp_chooser_slave_get_property (GObject    *object,
337                                      guint       prop_id,
338                                      GValue     *value,
339                                      GParamSpec *pspec)
340{
341        switch (prop_id) {
342        default:
343                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
344                break;
345        }
346}
347
348static GObject *
349gdm_xdmcp_chooser_slave_constructor (GType                  type,
350                                     guint                  n_construct_properties,
351                                     GObjectConstructParam *construct_properties)
352{
353        GdmXdmcpChooserSlave      *xdmcp_chooser_slave;
354
355        xdmcp_chooser_slave = GDM_XDMCP_CHOOSER_SLAVE (G_OBJECT_CLASS (gdm_xdmcp_chooser_slave_parent_class)->constructor (type,
356                                                                                                                           n_construct_properties,
357                                                                                                                           construct_properties));
358
359        return G_OBJECT (xdmcp_chooser_slave);
360}
361
362static void
363gdm_xdmcp_chooser_slave_class_init (GdmXdmcpChooserSlaveClass *klass)
364{
365        GObjectClass  *object_class = G_OBJECT_CLASS (klass);
366        GdmSlaveClass *slave_class = GDM_SLAVE_CLASS (klass);
367
368        object_class->get_property = gdm_xdmcp_chooser_slave_get_property;
369        object_class->set_property = gdm_xdmcp_chooser_slave_set_property;
370        object_class->constructor = gdm_xdmcp_chooser_slave_constructor;
371        object_class->finalize = gdm_xdmcp_chooser_slave_finalize;
372
373        slave_class->start = gdm_xdmcp_chooser_slave_start;
374        slave_class->stop = gdm_xdmcp_chooser_slave_stop;
375
376        signals [HOSTNAME_SELECTED] =
377                g_signal_new ("hostname-selected",
378                              G_OBJECT_CLASS_TYPE (object_class),
379                              G_SIGNAL_RUN_FIRST,
380                              G_STRUCT_OFFSET (GdmXdmcpChooserSlaveClass, hostname_selected),
381                              NULL,
382                              NULL,
383                              g_cclosure_marshal_VOID__STRING,
384                              G_TYPE_NONE,
385                              1,
386                              G_TYPE_STRING);
387
388        g_type_class_add_private (klass, sizeof (GdmXdmcpChooserSlavePrivate));
389
390        dbus_g_object_type_install_info (GDM_TYPE_XDMCP_CHOOSER_SLAVE, &dbus_glib_gdm_xdmcp_chooser_slave_object_info);
391}
392
393static void
394gdm_xdmcp_chooser_slave_init (GdmXdmcpChooserSlave *slave)
395{
396        slave->priv = GDM_XDMCP_CHOOSER_SLAVE_GET_PRIVATE (slave);
397}
398
399static void
400gdm_xdmcp_chooser_slave_finalize (GObject *object)
401{
402        GdmXdmcpChooserSlave *xdmcp_chooser_slave;
403
404        g_return_if_fail (object != NULL);
405        g_return_if_fail (GDM_IS_XDMCP_CHOOSER_SLAVE (object));
406
407        xdmcp_chooser_slave = GDM_XDMCP_CHOOSER_SLAVE (object);
408
409        g_return_if_fail (xdmcp_chooser_slave->priv != NULL);
410
411        gdm_xdmcp_chooser_slave_stop (GDM_SLAVE (xdmcp_chooser_slave));
412
413        G_OBJECT_CLASS (gdm_xdmcp_chooser_slave_parent_class)->finalize (object);
414}
415
416GdmSlave *
417gdm_xdmcp_chooser_slave_new (const char *id)
418{
419        GObject *object;
420
421        object = g_object_new (GDM_TYPE_XDMCP_CHOOSER_SLAVE,
422                               "display-id", id,
423                               NULL);
424
425        return GDM_SLAVE (object);
426}
Note: See TracBrowser for help on using the repository browser.