~ubuntu-branches/ubuntu/oneiric/gdm3/oneiric

« back to all changes in this revision

Viewing changes to gui/simple-chooser/gdm-chooser-client.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2010-03-25 20:02:20 UTC
  • Revision ID: james.westby@ubuntu.com-20100325200220-12cap62s6p304nuh
Tags: upstream-2.29.92
ImportĀ upstreamĀ versionĀ 2.29.92

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 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 <unistd.h>
 
26
#include <string.h>
 
27
 
 
28
#include <glib.h>
 
29
#include <glib/gi18n.h>
 
30
#include <glib-object.h>
 
31
#define DBUS_API_SUBJECT_TO_CHANGE
 
32
#include <dbus/dbus.h>
 
33
#include <dbus/dbus-glib.h>
 
34
#include <dbus/dbus-glib-lowlevel.h>
 
35
 
 
36
#include "gdm-chooser-client.h"
 
37
 
 
38
#define GDM_CHOOSER_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_CHOOSER_CLIENT, GdmChooserClientPrivate))
 
39
 
 
40
#define CHOOSER_SERVER_DBUS_PATH      "/org/gnome/DisplayManager/ChooserServer"
 
41
#define CHOOSER_SERVER_DBUS_INTERFACE "org.gnome.DisplayManager.ChooserServer"
 
42
 
 
43
#define GDM_DBUS_NAME              "org.gnome.DisplayManager"
 
44
#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display"
 
45
 
 
46
struct GdmChooserClientPrivate
 
47
{
 
48
        DBusConnection   *connection;
 
49
        char             *address;
 
50
};
 
51
 
 
52
enum {
 
53
        PROP_0,
 
54
};
 
55
 
 
56
static void     gdm_chooser_client_class_init  (GdmChooserClientClass *klass);
 
57
static void     gdm_chooser_client_init        (GdmChooserClient      *chooser_client);
 
58
static void     gdm_chooser_client_finalize    (GObject               *object);
 
59
 
 
60
G_DEFINE_TYPE (GdmChooserClient, gdm_chooser_client, G_TYPE_OBJECT)
 
61
 
 
62
static gpointer client_object = NULL;
 
63
 
 
64
GQuark
 
65
gdm_chooser_client_error_quark (void)
 
66
{
 
67
        static GQuark error_quark = 0;
 
68
 
 
69
        if (error_quark == 0)
 
70
                error_quark = g_quark_from_static_string ("gdm-chooser-client");
 
71
 
 
72
        return error_quark;
 
73
}
 
74
 
 
75
static gboolean
 
76
send_dbus_string_method (DBusConnection *connection,
 
77
                         const char     *method,
 
78
                         const char     *payload)
 
79
{
 
80
        DBusError       error;
 
81
        DBusMessage    *message;
 
82
        DBusMessage    *reply;
 
83
        DBusMessageIter iter;
 
84
        const char     *str;
 
85
 
 
86
        if (payload != NULL) {
 
87
                str = payload;
 
88
        } else {
 
89
                str = "";
 
90
        }
 
91
 
 
92
        g_debug ("GdmChooserClient: Calling %s", method);
 
93
        message = dbus_message_new_method_call (NULL,
 
94
                                                CHOOSER_SERVER_DBUS_PATH,
 
95
                                                CHOOSER_SERVER_DBUS_INTERFACE,
 
96
                                                method);
 
97
        if (message == NULL) {
 
98
                g_warning ("Couldn't allocate the D-Bus message");
 
99
                return FALSE;
 
100
        }
 
101
 
 
102
        dbus_message_iter_init_append (message, &iter);
 
103
        dbus_message_iter_append_basic (&iter,
 
104
                                        DBUS_TYPE_STRING,
 
105
                                        &str);
 
106
 
 
107
        dbus_error_init (&error);
 
108
        reply = dbus_connection_send_with_reply_and_block (connection,
 
109
                                                           message,
 
110
                                                           -1,
 
111
                                                           &error);
 
112
 
 
113
        dbus_message_unref (message);
 
114
 
 
115
        if (dbus_error_is_set (&error)) {
 
116
                g_warning ("%s %s raised: %s\n",
 
117
                           method,
 
118
                           error.name,
 
119
                           error.message);
 
120
                return FALSE;
 
121
        }
 
122
        if (reply != NULL) {
 
123
                dbus_message_unref (reply);
 
124
        }
 
125
        dbus_connection_flush (connection);
 
126
 
 
127
        return TRUE;
 
128
}
 
129
 
 
130
 
 
131
static gboolean
 
132
send_dbus_void_method (DBusConnection *connection,
 
133
                       const char     *method)
 
134
{
 
135
        DBusError       error;
 
136
        DBusMessage    *message;
 
137
        DBusMessage    *reply;
 
138
 
 
139
        g_debug ("GdmChooserClient: Calling %s", method);
 
140
        message = dbus_message_new_method_call (NULL,
 
141
                                                CHOOSER_SERVER_DBUS_PATH,
 
142
                                                CHOOSER_SERVER_DBUS_INTERFACE,
 
143
                                                method);
 
144
        if (message == NULL) {
 
145
                g_warning ("Couldn't allocate the D-Bus message");
 
146
                return FALSE;
 
147
        }
 
148
 
 
149
        dbus_error_init (&error);
 
150
        reply = dbus_connection_send_with_reply_and_block (connection,
 
151
                                                           message,
 
152
                                                           -1,
 
153
                                                           &error);
 
154
 
 
155
        dbus_message_unref (message);
 
156
 
 
157
        if (dbus_error_is_set (&error)) {
 
158
                g_warning ("%s %s raised: %s\n",
 
159
                           method,
 
160
                           error.name,
 
161
                           error.message);
 
162
                return FALSE;
 
163
        }
 
164
        if (reply != NULL) {
 
165
                dbus_message_unref (reply);
 
166
        }
 
167
        dbus_connection_flush (connection);
 
168
 
 
169
        return TRUE;
 
170
}
 
171
 
 
172
void
 
173
gdm_chooser_client_call_select_hostname (GdmChooserClient *client,
 
174
                                         const char       *text)
 
175
{
 
176
        send_dbus_string_method (client->priv->connection,
 
177
                                 "SelectHostname",
 
178
                                 text);
 
179
}
 
180
 
 
181
void
 
182
gdm_chooser_client_call_disconnect (GdmChooserClient *client)
 
183
{
 
184
        send_dbus_void_method (client->priv->connection,
 
185
                               "Disconnect");
 
186
}
 
187
 
 
188
static DBusHandlerResult
 
189
client_dbus_handle_message (DBusConnection *connection,
 
190
                            DBusMessage    *message,
 
191
                            void           *user_data,
 
192
                            dbus_bool_t     local_interface)
 
193
{
 
194
 
 
195
#if 0
 
196
        g_message ("obj_path=%s interface=%s method=%s destination=%s",
 
197
                   dbus_message_get_path (message),
 
198
                   dbus_message_get_interface (message),
 
199
                   dbus_message_get_member (message),
 
200
                   dbus_message_get_destination (message));
 
201
#endif
 
202
 
 
203
        g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
 
204
        g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
 
205
 
 
206
 
 
207
        return DBUS_HANDLER_RESULT_HANDLED;
 
208
}
 
209
 
 
210
static DBusHandlerResult
 
211
client_dbus_filter_function (DBusConnection *connection,
 
212
                             DBusMessage    *message,
 
213
                             void           *user_data)
 
214
{
 
215
        GdmChooserClient *client = GDM_CHOOSER_CLIENT (user_data);
 
216
        const char       *path;
 
217
 
 
218
        path = dbus_message_get_path (message);
 
219
 
 
220
        g_debug ("GdmChooserClient: obj_path=%s interface=%s method=%s",
 
221
                 dbus_message_get_path (message),
 
222
                 dbus_message_get_interface (message),
 
223
                 dbus_message_get_member (message));
 
224
 
 
225
        if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")
 
226
            && strcmp (path, DBUS_PATH_LOCAL) == 0) {
 
227
 
 
228
                g_message ("Got disconnected from the session message bus");
 
229
 
 
230
                dbus_connection_unref (connection);
 
231
                client->priv->connection = NULL;
 
232
 
 
233
        } else if (dbus_message_is_signal (message,
 
234
                                           DBUS_INTERFACE_DBUS,
 
235
                                           "NameOwnerChanged")) {
 
236
                g_debug ("GdmChooserClient: Name owner changed?");
 
237
        } else {
 
238
                return client_dbus_handle_message (connection, message, user_data, FALSE);
 
239
        }
 
240
 
 
241
        return DBUS_HANDLER_RESULT_HANDLED;
 
242
}
 
243
 
 
244
gboolean
 
245
gdm_chooser_client_start (GdmChooserClient *client,
 
246
                          GError          **error)
 
247
{
 
248
        gboolean  ret;
 
249
        DBusError local_error;
 
250
 
 
251
        g_return_val_if_fail (GDM_IS_CHOOSER_CLIENT (client), FALSE);
 
252
 
 
253
        ret = FALSE;
 
254
 
 
255
        if (client->priv->address == NULL) {
 
256
                g_warning ("GDM_CHOOSER_DBUS_ADDRESS not set");
 
257
                g_set_error (error,
 
258
                             GDM_CHOOSER_CLIENT_ERROR,
 
259
                             GDM_CHOOSER_CLIENT_ERROR_GENERIC,
 
260
                             "GDM_CHOOSER_DBUS_ADDRESS not set");
 
261
                goto out;
 
262
        }
 
263
 
 
264
        g_debug ("GdmChooserClient: connecting to address: %s", client->priv->address);
 
265
 
 
266
        dbus_error_init (&local_error);
 
267
        client->priv->connection = dbus_connection_open (client->priv->address, &local_error);
 
268
        if (client->priv->connection == NULL) {
 
269
                if (dbus_error_is_set (&local_error)) {
 
270
                        g_warning ("error opening connection: %s", local_error.message);
 
271
                        g_set_error (error,
 
272
                                     GDM_CHOOSER_CLIENT_ERROR,
 
273
                                     GDM_CHOOSER_CLIENT_ERROR_GENERIC,
 
274
                                     "%s", local_error.message);
 
275
                        dbus_error_free (&local_error);
 
276
                } else {
 
277
                        g_warning ("Unable to open connection");
 
278
                }
 
279
                goto out;
 
280
        }
 
281
 
 
282
        dbus_connection_setup_with_g_main (client->priv->connection, NULL);
 
283
        dbus_connection_set_exit_on_disconnect (client->priv->connection, TRUE);
 
284
 
 
285
        dbus_connection_add_filter (client->priv->connection,
 
286
                                    client_dbus_filter_function,
 
287
                                    client,
 
288
                                    NULL);
 
289
 
 
290
        ret = TRUE;
 
291
 
 
292
 out:
 
293
        return ret;
 
294
}
 
295
 
 
296
void
 
297
gdm_chooser_client_stop (GdmChooserClient *client)
 
298
{
 
299
        g_return_if_fail (GDM_IS_CHOOSER_CLIENT (client));
 
300
 
 
301
}
 
302
 
 
303
static void
 
304
gdm_chooser_client_set_property (GObject        *object,
 
305
                                 guint           prop_id,
 
306
                                 const GValue   *value,
 
307
                                 GParamSpec     *pspec)
 
308
{
 
309
        switch (prop_id) {
 
310
        default:
 
311
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
312
                break;
 
313
        }
 
314
}
 
315
 
 
316
static void
 
317
gdm_chooser_client_get_property (GObject        *object,
 
318
                                 guint           prop_id,
 
319
                                 GValue         *value,
 
320
                                 GParamSpec     *pspec)
 
321
{
 
322
        switch (prop_id) {
 
323
        default:
 
324
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
325
                break;
 
326
        }
 
327
}
 
328
 
 
329
static GObject *
 
330
gdm_chooser_client_constructor (GType                  type,
 
331
                                 guint                  n_construct_properties,
 
332
                                 GObjectConstructParam *construct_properties)
 
333
{
 
334
        GdmChooserClient      *chooser_client;
 
335
 
 
336
        chooser_client = GDM_CHOOSER_CLIENT (G_OBJECT_CLASS (gdm_chooser_client_parent_class)->constructor (type,
 
337
                                                                                                            n_construct_properties,
 
338
                                                                                                            construct_properties));
 
339
 
 
340
        return G_OBJECT (chooser_client);
 
341
}
 
342
 
 
343
static void
 
344
gdm_chooser_client_dispose (GObject *object)
 
345
{
 
346
        g_debug ("GdmChooserClient: Disposing chooser_client");
 
347
 
 
348
        G_OBJECT_CLASS (gdm_chooser_client_parent_class)->dispose (object);
 
349
}
 
350
 
 
351
static void
 
352
gdm_chooser_client_class_init (GdmChooserClientClass *klass)
 
353
{
 
354
        GObjectClass   *object_class = G_OBJECT_CLASS (klass);
 
355
 
 
356
        object_class->get_property = gdm_chooser_client_get_property;
 
357
        object_class->set_property = gdm_chooser_client_set_property;
 
358
        object_class->constructor = gdm_chooser_client_constructor;
 
359
        object_class->dispose = gdm_chooser_client_dispose;
 
360
        object_class->finalize = gdm_chooser_client_finalize;
 
361
 
 
362
        g_type_class_add_private (klass, sizeof (GdmChooserClientPrivate));
 
363
}
 
364
 
 
365
static void
 
366
gdm_chooser_client_init (GdmChooserClient *client)
 
367
{
 
368
 
 
369
        client->priv = GDM_CHOOSER_CLIENT_GET_PRIVATE (client);
 
370
 
 
371
        client->priv->address = g_strdup (g_getenv ("GDM_CHOOSER_DBUS_ADDRESS"));
 
372
}
 
373
 
 
374
static void
 
375
gdm_chooser_client_finalize (GObject *object)
 
376
{
 
377
        GdmChooserClient *client;
 
378
 
 
379
        g_return_if_fail (object != NULL);
 
380
        g_return_if_fail (GDM_IS_CHOOSER_CLIENT (object));
 
381
 
 
382
        client = GDM_CHOOSER_CLIENT (object);
 
383
 
 
384
        g_return_if_fail (client->priv != NULL);
 
385
 
 
386
        g_free (client->priv->address);
 
387
 
 
388
        G_OBJECT_CLASS (gdm_chooser_client_parent_class)->finalize (object);
 
389
}
 
390
 
 
391
GdmChooserClient *
 
392
gdm_chooser_client_new (void)
 
393
{
 
394
        if (client_object != NULL) {
 
395
                g_object_ref (client_object);
 
396
        } else {
 
397
                client_object = g_object_new (GDM_TYPE_CHOOSER_CLIENT, NULL);
 
398
                g_object_add_weak_pointer (client_object,
 
399
                                           (gpointer *) &client_object);
 
400
        }
 
401
 
 
402
        return GDM_CHOOSER_CLIENT (client_object);
 
403
}