source: proiecte/PPPP/gdm/daemon/gdm-manager.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: 15.1 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 <signal.h>
29#include <sys/stat.h>
30#include <sys/types.h>
31
32#include <glib.h>
33#include <glib/gi18n.h>
34#include <glib/gstdio.h>
35#include <glib-object.h>
36#define DBUS_API_SUBJECT_TO_CHANGE
37#include <dbus/dbus-glib.h>
38#include <dbus/dbus-glib-lowlevel.h>
39
40#include "gdm-common.h"
41
42#include "gdm-manager.h"
43#include "gdm-manager-glue.h"
44#include "gdm-display-store.h"
45#include "gdm-display-factory.h"
46#include "gdm-local-display-factory.h"
47#include "gdm-xdmcp-display-factory.h"
48
49#define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate))
50
51#define GDM_DBUS_PATH         "/org/gnome/DisplayManager"
52#define GDM_MANAGER_DBUS_PATH GDM_DBUS_PATH "/Manager"
53#define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.Manager"
54
55struct GdmManagerPrivate
56{
57        GdmDisplayStore        *display_store;
58        GdmLocalDisplayFactory *local_factory;
59#ifdef HAVE_LIBXDMCP
60        GdmXdmcpDisplayFactory *xdmcp_factory;
61#endif
62        gboolean                xdmcp_enabled;
63
64        gboolean                started;
65        gboolean                wait_for_go;
66        gboolean                no_console;
67
68        DBusGProxy             *bus_proxy;
69        DBusGConnection        *connection;
70};
71
72enum {
73        PROP_0,
74        PROP_XDMCP_ENABLED
75};
76
77enum {
78        DISPLAY_ADDED,
79        DISPLAY_REMOVED,
80        LAST_SIGNAL
81};
82
83static guint signals [LAST_SIGNAL] = { 0, };
84
85static void     gdm_manager_class_init  (GdmManagerClass *klass);
86static void     gdm_manager_init        (GdmManager      *manager);
87static void     gdm_manager_finalize    (GObject         *object);
88
89static gpointer manager_object = NULL;
90
91G_DEFINE_TYPE (GdmManager, gdm_manager, G_TYPE_OBJECT)
92
93GQuark
94gdm_manager_error_quark (void)
95{
96        static GQuark ret = 0;
97        if (ret == 0) {
98                ret = g_quark_from_static_string ("gdm_manager_error");
99        }
100
101        return ret;
102}
103
104static gboolean
105listify_display_ids (const char *id,
106                     GdmDisplay *display,
107                     GPtrArray **array)
108{
109        g_ptr_array_add (*array, g_strdup (id));
110
111        /* return FALSE to continue */
112        return FALSE;
113}
114
115/*
116  Example:
117  dbus-send --system --dest=org.gnome.DisplayManager \
118  --type=method_call --print-reply --reply-timeout=2000 \
119  /org/gnome/DisplayManager/Manager \
120  org.gnome.DisplayManager.Manager.GetDisplays
121*/
122gboolean
123gdm_manager_get_displays (GdmManager *manager,
124                          GPtrArray **displays,
125                          GError    **error)
126{
127        g_return_val_if_fail (GDM_IS_MANAGER (manager), FALSE);
128
129        if (displays == NULL) {
130                return FALSE;
131        }
132
133        *displays = g_ptr_array_new ();
134        gdm_display_store_foreach (manager->priv->display_store,
135                                   (GdmDisplayStoreFunc)listify_display_ids,
136                                   displays);
137
138        return TRUE;
139}
140
141void
142gdm_manager_stop (GdmManager *manager)
143{
144        g_debug ("GdmManager: GDM stopping");
145
146        if (manager->priv->local_factory != NULL) {
147                gdm_display_factory_stop (GDM_DISPLAY_FACTORY (manager->priv->local_factory));
148        }
149
150#ifdef HAVE_LIBXDMCP
151        if (manager->priv->xdmcp_factory != NULL) {
152                gdm_display_factory_stop (GDM_DISPLAY_FACTORY (manager->priv->xdmcp_factory));
153        }
154#endif
155
156        manager->priv->started = FALSE;
157}
158
159void
160gdm_manager_start (GdmManager *manager)
161{
162        g_debug ("GdmManager: GDM starting to manage displays");
163
164        if (! manager->priv->wait_for_go) {
165                gdm_display_factory_start (GDM_DISPLAY_FACTORY (manager->priv->local_factory));
166        }
167
168#ifdef HAVE_LIBXDMCP
169        /* Accept remote connections */
170        if (manager->priv->xdmcp_enabled && ! manager->priv->wait_for_go) {
171                if (manager->priv->xdmcp_factory != NULL) {
172                        g_debug ("GdmManager: Accepting XDMCP connections...");
173                        gdm_display_factory_start (GDM_DISPLAY_FACTORY (manager->priv->xdmcp_factory));
174                }
175        }
176#endif
177
178        manager->priv->started = TRUE;
179}
180
181void
182gdm_manager_set_wait_for_go (GdmManager *manager,
183                             gboolean    wait_for_go)
184{
185        if (manager->priv->wait_for_go != wait_for_go) {
186                manager->priv->wait_for_go = wait_for_go;
187
188                if (! wait_for_go) {
189                        /* we got a go */
190                        gdm_display_factory_start (GDM_DISPLAY_FACTORY (manager->priv->local_factory));
191
192#ifdef HAVE_LIBXDMCP
193                        if (manager->priv->xdmcp_enabled && manager->priv->xdmcp_factory != NULL) {
194                                g_debug ("GdmManager: Accepting XDMCP connections...");
195                                gdm_display_factory_start (GDM_DISPLAY_FACTORY (manager->priv->xdmcp_factory));
196                        }
197#endif
198                }
199        }
200}
201
202typedef struct {
203        const char *service_name;
204        GdmManager *manager;
205} RemoveDisplayData;
206
207static gboolean
208remove_display_for_connection (char              *id,
209                               GdmDisplay        *display,
210                               RemoveDisplayData *data)
211{
212        g_assert (display != NULL);
213        g_assert (data->service_name != NULL);
214
215        /* FIXME: compare service name to that of display */
216#if 0
217        if (strcmp (info->service_name, data->service_name) == 0) {
218                remove_session_for_cookie (data->manager, cookie, NULL);
219                leader_info_cancel (info);
220                return TRUE;
221        }
222#endif
223
224        return FALSE;
225}
226
227static void
228remove_displays_for_connection (GdmManager *manager,
229                                const char *service_name)
230{
231        RemoveDisplayData data;
232
233        data.service_name = service_name;
234        data.manager = manager;
235
236        gdm_display_store_foreach_remove (manager->priv->display_store,
237                                          (GdmDisplayStoreFunc)remove_display_for_connection,
238                                          &data);
239}
240
241static void
242bus_name_owner_changed (DBusGProxy  *bus_proxy,
243                        const char  *service_name,
244                        const char  *old_service_name,
245                        const char  *new_service_name,
246                        GdmManager  *manager)
247{
248        if (strlen (new_service_name) == 0) {
249                remove_displays_for_connection (manager, old_service_name);
250        }
251}
252
253static gboolean
254register_manager (GdmManager *manager)
255{
256        GError *error = NULL;
257
258        error = NULL;
259        manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
260        if (manager->priv->connection == NULL) {
261                if (error != NULL) {
262                        g_critical ("error getting system bus: %s", error->message);
263                        g_error_free (error);
264                }
265                exit (1);
266        }
267
268        manager->priv->bus_proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
269                                                              DBUS_SERVICE_DBUS,
270                                                              DBUS_PATH_DBUS,
271                                                              DBUS_INTERFACE_DBUS);
272        dbus_g_proxy_add_signal (manager->priv->bus_proxy,
273                                 "NameOwnerChanged",
274                                 G_TYPE_STRING,
275                                 G_TYPE_STRING,
276                                 G_TYPE_STRING,
277                                 G_TYPE_INVALID);
278        dbus_g_proxy_connect_signal (manager->priv->bus_proxy,
279                                     "NameOwnerChanged",
280                                     G_CALLBACK (bus_name_owner_changed),
281                                     manager,
282                                     NULL);
283
284        dbus_g_connection_register_g_object (manager->priv->connection, GDM_MANAGER_DBUS_PATH, G_OBJECT (manager));
285
286        return TRUE;
287}
288
289void
290gdm_manager_set_xdmcp_enabled (GdmManager *manager,
291                               gboolean    enabled)
292{
293        g_return_if_fail (GDM_IS_MANAGER (manager));
294
295        if (manager->priv->xdmcp_enabled != enabled) {
296                manager->priv->xdmcp_enabled = enabled;
297
298                if (manager->priv->xdmcp_enabled) {
299                        manager->priv->xdmcp_factory = gdm_xdmcp_display_factory_new (manager->priv->display_store);
300                        if (manager->priv->started) {
301                                gdm_display_factory_start (GDM_DISPLAY_FACTORY (manager->priv->xdmcp_factory));
302                        }
303                } else {
304                        if (manager->priv->started) {
305                                gdm_display_factory_stop (GDM_DISPLAY_FACTORY (manager->priv->xdmcp_factory));
306                        }
307
308                        g_object_unref (manager->priv->xdmcp_factory);
309                        manager->priv->xdmcp_factory = NULL;
310                }
311        }
312
313}
314
315static void
316gdm_manager_set_property (GObject      *object,
317                          guint         prop_id,
318                          const GValue  *value,
319                          GParamSpec    *pspec)
320{
321        GdmManager *self;
322
323        self = GDM_MANAGER (object);
324
325        switch (prop_id) {
326        case PROP_XDMCP_ENABLED:
327                gdm_manager_set_xdmcp_enabled (self, g_value_get_boolean (value));
328                break;
329        default:
330                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
331                break;
332        }
333}
334
335static void
336gdm_manager_get_property (GObject    *object,
337                          guint       prop_id,
338                          GValue     *value,
339                          GParamSpec *pspec)
340{
341        GdmManager *self;
342
343        self = GDM_MANAGER (object);
344
345        switch (prop_id) {
346        case PROP_XDMCP_ENABLED:
347                g_value_set_boolean (value, self->priv->xdmcp_enabled);
348                break;
349        default:
350                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
351                break;
352        }
353}
354
355static GObject *
356gdm_manager_constructor (GType                  type,
357                         guint                  n_construct_properties,
358                         GObjectConstructParam *construct_properties)
359{
360        GdmManager      *manager;
361
362        manager = GDM_MANAGER (G_OBJECT_CLASS (gdm_manager_parent_class)->constructor (type,
363                                                                                       n_construct_properties,
364                                                                                       construct_properties));
365
366        manager->priv->local_factory = gdm_local_display_factory_new (manager->priv->display_store);
367
368#ifdef HAVE_LIBXDMCP
369        if (manager->priv->xdmcp_enabled) {
370                manager->priv->xdmcp_factory = gdm_xdmcp_display_factory_new (manager->priv->display_store);
371        }
372#endif
373
374        return G_OBJECT (manager);
375}
376
377static void
378gdm_manager_class_init (GdmManagerClass *klass)
379{
380        GObjectClass   *object_class = G_OBJECT_CLASS (klass);
381
382        object_class->get_property = gdm_manager_get_property;
383        object_class->set_property = gdm_manager_set_property;
384        object_class->constructor = gdm_manager_constructor;
385        object_class->finalize = gdm_manager_finalize;
386
387        signals [DISPLAY_ADDED] =
388                g_signal_new ("display-added",
389                              G_TYPE_FROM_CLASS (object_class),
390                              G_SIGNAL_RUN_LAST,
391                              G_STRUCT_OFFSET (GdmManagerClass, display_added),
392                              NULL,
393                              NULL,
394                              g_cclosure_marshal_VOID__STRING,
395                              G_TYPE_NONE,
396                              1, G_TYPE_STRING);
397        signals [DISPLAY_REMOVED] =
398                g_signal_new ("display-removed",
399                              G_TYPE_FROM_CLASS (object_class),
400                              G_SIGNAL_RUN_LAST,
401                              G_STRUCT_OFFSET (GdmManagerClass, display_removed),
402                              NULL,
403                              NULL,
404                              g_cclosure_marshal_VOID__STRING,
405                              G_TYPE_NONE,
406                              1, G_TYPE_STRING);
407
408        g_object_class_install_property (object_class,
409                                         PROP_XDMCP_ENABLED,
410                                         g_param_spec_boolean ("xdmcp-enabled",
411                                                               NULL,
412                                                               NULL,
413                                                               FALSE,
414                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
415
416        g_type_class_add_private (klass, sizeof (GdmManagerPrivate));
417
418        dbus_g_object_type_install_info (GDM_TYPE_MANAGER, &dbus_glib_gdm_manager_object_info);
419}
420
421static void
422gdm_manager_init (GdmManager *manager)
423{
424
425        manager->priv = GDM_MANAGER_GET_PRIVATE (manager);
426
427        manager->priv->display_store = gdm_display_store_new ();
428}
429
430static void
431gdm_manager_finalize (GObject *object)
432{
433        GdmManager *manager;
434
435        g_return_if_fail (object != NULL);
436        g_return_if_fail (GDM_IS_MANAGER (object));
437
438        manager = GDM_MANAGER (object);
439
440        g_return_if_fail (manager->priv != NULL);
441
442#ifdef HAVE_LIBXDMCP
443        if (manager->priv->xdmcp_factory != NULL) {
444                g_object_unref (manager->priv->xdmcp_factory);
445        }
446#endif
447
448        gdm_display_store_clear (manager->priv->display_store);
449        g_object_unref (manager->priv->display_store);
450
451        G_OBJECT_CLASS (gdm_manager_parent_class)->finalize (object);
452}
453
454GdmManager *
455gdm_manager_new (void)
456{
457        if (manager_object != NULL) {
458                g_object_ref (manager_object);
459        } else {
460                gboolean res;
461
462                manager_object = g_object_new (GDM_TYPE_MANAGER, NULL);
463                g_object_add_weak_pointer (manager_object,
464                                           (gpointer *) &manager_object);
465                res = register_manager (manager_object);
466                if (! res) {
467                        g_object_unref (manager_object);
468                        return NULL;
469                }
470        }
471
472        return GDM_MANAGER (manager_object);
473}
Note: See TracBrowser for help on using the repository browser.