1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
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.
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.
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.
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>
36
#include "gdm-chooser-client.h"
38
#define GDM_CHOOSER_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_CHOOSER_CLIENT, GdmChooserClientPrivate))
40
#define CHOOSER_SERVER_DBUS_PATH "/org/gnome/DisplayManager/ChooserServer"
41
#define CHOOSER_SERVER_DBUS_INTERFACE "org.gnome.DisplayManager.ChooserServer"
43
#define GDM_DBUS_NAME "org.gnome.DisplayManager"
44
#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display"
46
struct GdmChooserClientPrivate
48
DBusConnection *connection;
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);
60
G_DEFINE_TYPE (GdmChooserClient, gdm_chooser_client, G_TYPE_OBJECT)
62
static gpointer client_object = NULL;
65
gdm_chooser_client_error_quark (void)
67
static GQuark error_quark = 0;
70
error_quark = g_quark_from_static_string ("gdm-chooser-client");
76
send_dbus_string_method (DBusConnection *connection,
86
if (payload != NULL) {
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,
97
if (message == NULL) {
98
g_warning ("Couldn't allocate the D-Bus message");
102
dbus_message_iter_init_append (message, &iter);
103
dbus_message_iter_append_basic (&iter,
107
dbus_error_init (&error);
108
reply = dbus_connection_send_with_reply_and_block (connection,
113
dbus_message_unref (message);
115
if (dbus_error_is_set (&error)) {
116
g_warning ("%s %s raised: %s\n",
123
dbus_message_unref (reply);
125
dbus_connection_flush (connection);
132
send_dbus_void_method (DBusConnection *connection,
136
DBusMessage *message;
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,
144
if (message == NULL) {
145
g_warning ("Couldn't allocate the D-Bus message");
149
dbus_error_init (&error);
150
reply = dbus_connection_send_with_reply_and_block (connection,
155
dbus_message_unref (message);
157
if (dbus_error_is_set (&error)) {
158
g_warning ("%s %s raised: %s\n",
165
dbus_message_unref (reply);
167
dbus_connection_flush (connection);
173
gdm_chooser_client_call_select_hostname (GdmChooserClient *client,
176
send_dbus_string_method (client->priv->connection,
182
gdm_chooser_client_call_disconnect (GdmChooserClient *client)
184
send_dbus_void_method (client->priv->connection,
188
static DBusHandlerResult
189
client_dbus_handle_message (DBusConnection *connection,
190
DBusMessage *message,
192
dbus_bool_t local_interface)
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));
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);
207
return DBUS_HANDLER_RESULT_HANDLED;
210
static DBusHandlerResult
211
client_dbus_filter_function (DBusConnection *connection,
212
DBusMessage *message,
215
GdmChooserClient *client = GDM_CHOOSER_CLIENT (user_data);
218
path = dbus_message_get_path (message);
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));
225
if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")
226
&& strcmp (path, DBUS_PATH_LOCAL) == 0) {
228
g_message ("Got disconnected from the session message bus");
230
dbus_connection_unref (connection);
231
client->priv->connection = NULL;
233
} else if (dbus_message_is_signal (message,
235
"NameOwnerChanged")) {
236
g_debug ("GdmChooserClient: Name owner changed?");
238
return client_dbus_handle_message (connection, message, user_data, FALSE);
241
return DBUS_HANDLER_RESULT_HANDLED;
245
gdm_chooser_client_start (GdmChooserClient *client,
249
DBusError local_error;
251
g_return_val_if_fail (GDM_IS_CHOOSER_CLIENT (client), FALSE);
255
if (client->priv->address == NULL) {
256
g_warning ("GDM_CHOOSER_DBUS_ADDRESS not set");
258
GDM_CHOOSER_CLIENT_ERROR,
259
GDM_CHOOSER_CLIENT_ERROR_GENERIC,
260
"GDM_CHOOSER_DBUS_ADDRESS not set");
264
g_debug ("GdmChooserClient: connecting to address: %s", client->priv->address);
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);
272
GDM_CHOOSER_CLIENT_ERROR,
273
GDM_CHOOSER_CLIENT_ERROR_GENERIC,
274
"%s", local_error.message);
275
dbus_error_free (&local_error);
277
g_warning ("Unable to open connection");
282
dbus_connection_setup_with_g_main (client->priv->connection, NULL);
283
dbus_connection_set_exit_on_disconnect (client->priv->connection, TRUE);
285
dbus_connection_add_filter (client->priv->connection,
286
client_dbus_filter_function,
297
gdm_chooser_client_stop (GdmChooserClient *client)
299
g_return_if_fail (GDM_IS_CHOOSER_CLIENT (client));
304
gdm_chooser_client_set_property (GObject *object,
311
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
317
gdm_chooser_client_get_property (GObject *object,
324
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
330
gdm_chooser_client_constructor (GType type,
331
guint n_construct_properties,
332
GObjectConstructParam *construct_properties)
334
GdmChooserClient *chooser_client;
336
chooser_client = GDM_CHOOSER_CLIENT (G_OBJECT_CLASS (gdm_chooser_client_parent_class)->constructor (type,
337
n_construct_properties,
338
construct_properties));
340
return G_OBJECT (chooser_client);
344
gdm_chooser_client_dispose (GObject *object)
346
g_debug ("GdmChooserClient: Disposing chooser_client");
348
G_OBJECT_CLASS (gdm_chooser_client_parent_class)->dispose (object);
352
gdm_chooser_client_class_init (GdmChooserClientClass *klass)
354
GObjectClass *object_class = G_OBJECT_CLASS (klass);
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;
362
g_type_class_add_private (klass, sizeof (GdmChooserClientPrivate));
366
gdm_chooser_client_init (GdmChooserClient *client)
369
client->priv = GDM_CHOOSER_CLIENT_GET_PRIVATE (client);
371
client->priv->address = g_strdup (g_getenv ("GDM_CHOOSER_DBUS_ADDRESS"));
375
gdm_chooser_client_finalize (GObject *object)
377
GdmChooserClient *client;
379
g_return_if_fail (object != NULL);
380
g_return_if_fail (GDM_IS_CHOOSER_CLIENT (object));
382
client = GDM_CHOOSER_CLIENT (object);
384
g_return_if_fail (client->priv != NULL);
386
g_free (client->priv->address);
388
G_OBJECT_CLASS (gdm_chooser_client_parent_class)->finalize (object);
392
gdm_chooser_client_new (void)
394
if (client_object != NULL) {
395
g_object_ref (client_object);
397
client_object = g_object_new (GDM_TYPE_CHOOSER_CLIENT, NULL);
398
g_object_add_weak_pointer (client_object,
399
(gpointer *) &client_object);
402
return GDM_CHOOSER_CLIENT (client_object);