[vino/3] okay. preferences are done now.
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vino/3] okay. preferences are done now.
- Date: Mon, 12 Jul 2010 18:36:40 +0000 (UTC)
commit 58ba9d1331246eaff96838abfb55815c923a91ba
Author: Ryan Lortie <desrt desrt ca>
Date: Wed Jul 7 21:28:24 2010 -0400
okay. preferences are done now.
capplet/vino-message-box.h | 2 +-
capplet/vino-preferences.c | 196 ++++++++++++++++++++++-------------
capplet/vino-preferences.ui | 5 +-
server/vino-dbus-listener.c | 213 ++++++++++---------------------------
server/vino-main.c | 243 ++++++++++++++++++++++++++++++++++---------
server/vino-prefs.c | 89 ----------------
server/vino-util.c | 105 ++++++++++++++++++-
server/vino-util.h | 4 +-
8 files changed, 483 insertions(+), 374 deletions(-)
---
diff --git a/capplet/vino-message-box.h b/capplet/vino-message-box.h
index 0c0714f..409bbe9 100644
--- a/capplet/vino-message-box.h
+++ b/capplet/vino-message-box.h
@@ -46,7 +46,7 @@ struct _VinoMessageBox
VinoMessageBoxPrivate *priv;
};
-GType vino_message_box_get_type (void) G_GNUC_CONST;
+GType vino_message_box_get_type (void);
GtkWidget *vino_message_box_new (void);
diff --git a/capplet/vino-preferences.c b/capplet/vino-preferences.c
index d62e788..4a440eb 100644
--- a/capplet/vino-preferences.c
+++ b/capplet/vino-preferences.c
@@ -39,7 +39,6 @@ typedef struct
GtkApplication parent_instance;
VinoConnectivityInfo *info;
- VinoMessageBox *message_box;
} VinoPreferences;
typedef GtkApplicationClass VinoPreferencesClass;
@@ -48,7 +47,7 @@ static GType vino_preferences_get_type (void);
G_DEFINE_TYPE (VinoPreferences, vino_preferences, GTK_TYPE_APPLICATION)
-/* We define two GSettings mappings here:
+/* We define three GSettings mappings here:
*
* First, a relatively boring boolean inversion mapping.
*/
@@ -69,8 +68,45 @@ set_inverted (const GValue *value,
return g_variant_new_boolean (!g_value_get_boolean (value));
}
+/* Next, one that maps between the array-of-strings list of
+ * authentication mechanisms and a boolean that is FALSE if the 'none'
+ * and TRUE otherwise (ie: for 'vnc' in the list).
+ */
+static gboolean
+get_authtype (GValue *value,
+ GVariant *variant,
+ gpointer user_data)
+{
+ GVariantIter iter;
+ const gchar *type;
+
+ g_variant_iter_init (&iter, variant);
+ g_value_set_boolean (value, TRUE);
+
+ while (g_variant_iter_next (&iter, "s", &type))
+ if (strcmp (type, "none") == 0)
+ g_value_set_boolean (value, FALSE);
+
+ return TRUE;
+}
+
+static GVariant *
+set_authtype (const GValue *value,
+ const GVariantType *type,
+ gpointer user_data)
+{
+ const gchar *authtype;
+
+ if (g_value_get_boolean (value))
+ authtype = "vnc";
+ else
+ authtype = "none";
-/* Next, a somewhat evil mapping for the password setting:
+ return g_variant_new_strv (&authtype, 1);
+}
+
+
+/* Finally, a somewhat evil mapping for the password setting:
*
* If the setting is 'keyring' then we load the password from the
* keyring. Else, it is assumed to be a base64-encoded string which is
@@ -177,19 +213,21 @@ vino_preferences_dialog_response (GtkWidget *widget,
}
static void
-vino_preferences_update_message (VinoPreferences *app)
+vino_preferences_info_changed (VinoConnectivityInfo *info,
+ gpointer user_data)
{
+ VinoMessageBox *message_box = VINO_MESSAGE_BOX (user_data);
gchar *internal_host, *external_host, *avahi_host;
guint16 internal_port, external_port;
- if (!vino_connectivity_info_get (app->info,
+ if (!vino_connectivity_info_get (info,
&internal_host, &internal_port,
&external_host, &external_port,
&avahi_host))
{
- vino_message_box_set_label (app->message_box,
+ vino_message_box_set_label (message_box,
_("Checking the connectivity of this machine..."));
- vino_message_box_show_image (app->message_box);
+ vino_message_box_show_image (message_box);
return;
}
@@ -224,49 +262,95 @@ vino_preferences_update_message (VinoPreferences *app)
g_string_append (url, _(" or "));
g_string_append_printf (url, "<a href=\"vnc://%s::%d\">%s</a>",
avahi_host, internal_port, avahi_host);
- }
-
+ }
g_string_append_printf (message, _("Others can access your computer "
"using the address %s."), url->str);
- vino_message_box_set_label (app->message_box, message->str);
+ vino_message_box_set_label (message_box, message->str);
g_string_free (message, TRUE);
g_string_free (url, TRUE);
}
else
- vino_message_box_set_label (app->message_box,
+ vino_message_box_set_label (message_box,
_("Nobody can access your desktop."));
- vino_message_box_hide_image (app->message_box);
+ vino_message_box_hide_image (message_box);
g_free (internal_host);
g_free (external_host);
g_free (avahi_host);
}
-static void
-vino_preferences_finalize (GObject *object)
+static GtkWindow *
+vino_preferences_connect_ui (VinoPreferences *app,
+ GtkBuilder *builder)
{
- VinoPreferences *app = (VinoPreferences *) object;
+ struct {
+ const gchar *setting;
+ const gchar *name;
+ const gchar *property;
+ GSettingsBindFlags flags;
+ GSettingsBindGetMapping get_mapping;
+ GSettingsBindSetMapping set_mapping;
+ } bindings[] = {
+ { "enabled", "allowed_toggle", "active" },
+
+ { "enabled", "control_settings", "sensitive", G_SETTINGS_BIND_GET },
+ { "view-only", "view_only_toggle", "active", 0, get_inverted, set_inverted },
+
+ { "enabled", "security_settings", "sensitive", G_SETTINGS_BIND_GET },
+ { "prompt-enabled", "prompt_enabled_toggle", "active", },
+ { "authentication-methods", "password_toggle", "active", 0, get_authtype, set_authtype },
+ { "authentication-methods", "password_box", "sensitive", G_SETTINGS_BIND_GET, get_authtype },
+ { "vnc-password", "password_entry", "text", 0, get_password, set_password },
+ { "use-upnp", "use_upnp_toggle", "active", },
+
+ { "enabled", "notification_settings", "sensitive", G_SETTINGS_BIND_GET },
+ { "icon-visibility", "icon_always_radio", "settings-active", }
+ };
+ GSettings *settings;
+ gpointer window;
+ gint i;
- g_object_unref (app->info);
+ settings = g_settings_new ("org.gnome.Vino");
- G_OBJECT_CLASS (vino_preferences_parent_class)
- ->finalize (object);
-}
+ for (i = 0; i < G_N_ELEMENTS (bindings); i++)
+ g_settings_bind_with_mapping (settings, bindings[i].setting,
+ gtk_builder_get_object (builder,
+ bindings[i].name),
+ bindings[i].property,
+ bindings[i].flags,
+ bindings[i].get_mapping,
+ bindings[i].set_mapping,
+ NULL, NULL);
+ window = gtk_builder_get_object (builder, "vino_dialog");
+ g_signal_connect (window, "response",
+ G_CALLBACK (vino_preferences_dialog_response), NULL);
+
+ app->info = vino_connectivity_info_new (gdk_screen_get_number (gtk_window_get_screen (window)));
+ g_signal_connect (app->info, "changed",
+ G_CALLBACK (vino_preferences_info_changed),
+ gtk_builder_get_object (builder, "message"));
+ vino_preferences_info_changed (app->info,
+ gtk_builder_get_object (builder, "message"));
+
+ g_object_unref (settings);
+ g_object_unref (builder);
+
+ return window;
+}
static GtkWindow *
vino_preferences_create_window (GtkApplication *gtk_app)
{
VinoPreferences *app = (VinoPreferences *) gtk_app;
GError *error = NULL;
- GSettings *settings;
GtkBuilder *builder;
const char *ui_file;
- gpointer window;
vino_radio_button_get_type ();
+ vino_message_box_get_type ();
#define VINO_UI_FILE "vino-preferences.ui"
if (g_file_test (VINO_UI_FILE, G_FILE_TEST_EXISTS))
@@ -278,63 +362,23 @@ vino_preferences_create_window (GtkApplication *gtk_app)
builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder, ui_file, &error))
{
- g_warning ("Unable to locate ui file '%s'", ui_file);
+ g_warning ("Unable to load ui file '%s': %s", ui_file, error->message);
g_error_free (error);
- return FALSE;
+ return NULL;
}
- settings = g_settings_new ("org.gnome.Vino");
-
- g_settings_bind (settings, "enabled",
- gtk_builder_get_object (builder, "control_settings"),
- "sensitive", G_SETTINGS_BIND_GET);
-
- g_settings_bind (settings, "enabled",
- gtk_builder_get_object (builder, "security_settings"),
- "sensitive", G_SETTINGS_BIND_GET);
-
- g_settings_bind (settings, "enabled",
- gtk_builder_get_object (builder, "notification_settings"),
- "sensitive", G_SETTINGS_BIND_GET);
-
- g_settings_bind (settings, "enabled",
- gtk_builder_get_object (builder, "allowed_toggle"),
- "active", 0);
-
- g_settings_bind_with_mapping (settings, "view-only",
- gtk_builder_get_object (builder,
- "view_only_toggle"),
- "active", 0,
- get_inverted, set_inverted, NULL, NULL);
-
- g_settings_bind_with_mapping (settings, "vnc-password",
- gtk_builder_get_object (builder,
- "password_entry"),
- "text", 0,
- get_password, set_password, NULL, NULL);
-
- g_settings_bind (settings, "icon-visibility",
- gtk_builder_get_object (builder, "icon_always_radio"),
- "settings-active", 0);
-
-
- window = gtk_builder_get_object (builder, "vino_dialog");
- g_signal_connect (window, "response",
- G_CALLBACK (vino_preferences_dialog_response), NULL);
-
+ return vino_preferences_connect_ui (app, builder);
+}
- app->info = vino_connectivity_info_new (gdk_screen_get_number (gtk_window_get_screen (window)));
- g_signal_connect_swapped (app->info, "changed",
- G_CALLBACK (vino_preferences_update_message), app);
- app->message_box = VINO_MESSAGE_BOX (vino_message_box_new ());
- gtk_widget_show (GTK_WIDGET (app->message_box));
- gtk_container_add (GTK_CONTAINER (gtk_builder_get_object (builder, "event_box")),
- GTK_WIDGET (app->message_box));
- vino_preferences_update_message (app);
+static void
+vino_preferences_finalize (GObject *object)
+{
+ VinoPreferences *app = (VinoPreferences *) object;
- g_object_unref (builder);
+ g_object_unref (app->info);
- return window;
+ G_OBJECT_CLASS (vino_preferences_parent_class)
+ ->finalize (object);
}
static void
@@ -352,13 +396,17 @@ vino_preferences_class_init (GtkApplicationClass *class)
}
static GtkApplication *
-vino_preferences_new (void)
+vino_preferences_new (gint argc, char **argv)
{
GError *error = NULL;
GtkApplication *app;
+ const gchar **args;
+
+ args = (const gchar **) argv;
app = g_initable_new (vino_preferences_get_type (), NULL, &error,
"application-id", "org.gnome.Vino.Preferences",
+ "argv", g_variant_new_bytestring_array (args, argc),
NULL);
if G_UNLIKELY (app == NULL)
@@ -377,7 +425,7 @@ main (int argc, char **argv)
textdomain (GETTEXT_PACKAGE);
gtk_init (&argc, &argv);
- app = vino_preferences_new ();
+ app = vino_preferences_new (argc, argv);
gtk_application_get_window (app);
gtk_application_run (app);
g_object_unref (app);
diff --git a/capplet/vino-preferences.ui b/capplet/vino-preferences.ui
index a01f697..fa1f582 100644
--- a/capplet/vino-preferences.ui
+++ b/capplet/vino-preferences.ui
@@ -165,11 +165,8 @@
</packing>
</child>
<child>
- <object class="GtkEventBox" id="event_box">
+ <object class="VinoMessageBox" id="message">
<property name="visible">True</property>
- <child>
- <placeholder/>
- </child>
</object>
<packing>
<property name="position">1</property>
diff --git a/server/vino-dbus-listener.c b/server/vino-dbus-listener.c
index d4d4f11..9c8df97 100644
--- a/server/vino-dbus-listener.c
+++ b/server/vino-dbus-listener.c
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2004-2006 William Jon McCann <mccann jhu edu>
- * Copyright (C) 2006 Jonh Wendell <wendell bani com br>
- * Copyright (C) 2007 Mark McLoughlin <markmc skynet ie>
+ * Copyright © 2010 Codethink Limited
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -18,12 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
- * Authors:
- * William Jon McCann <mccann jhu edu>
- * Jonh Wendell <wendell bani com br>
- * Mark McLoughlin <mark skynet ie>
- *
- * Code taken from gnome-screensaver/src/gs-listener-dbus.c
+ * Author: Ryan Lortie <desrt desrt ca>
*/
#include "config.h"
@@ -31,43 +24,15 @@
#include "vino-dbus-listener.h"
#include "vino-dbus.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-
-#include "vino-dbus-error.h"
-
#ifdef HAVE_TELEPATHY_GLIB
#include "vino-tube-servers-manager.h"
#endif
#include "vino-util.h"
-#include "vino-mdns.h"
#ifdef VINO_ENABLE_HTTP_SERVER
#include "vino-http.h"
#endif
-#ifdef HAVE_IFADDRS_H
-#include <ifaddrs.h>
-#else
-#include "libvncserver/ifaddr/ifaddrs.h"
-#endif
-
-#ifdef RFC2553
-#define ADDR_FAMILY_MEMBER ss_family
-#else
-#define ADDR_FAMILY_MEMBER sa_family
-#endif
-
-#define VINO_DBUS_BUS_NAME "org.gnome.Vino"
-
-
struct _VinoDBusListener
{
GObject parent_instance;
@@ -82,124 +47,44 @@ struct _VinoDBusListener
typedef GObjectClass VinoDBusListenerClass;
static GType vino_dbus_listener_get_type (void);
+
G_DEFINE_TYPE (VinoDBusListener, vino_dbus_listener, G_TYPE_OBJECT)
-static char *
-get_local_hostname (VinoDBusListener *listener)
+static void
+vino_dbus_listener_finalize (GObject *object)
{
- char *retval, buf[INET6_ADDRSTRLEN];
- struct ifaddrs *myaddrs, *ifa;
- void *sin;
- const char *server_iface;
- GHashTable *ipv4, *ipv6;
- GHashTableIter iter;
- gpointer key, value;
-
- retval = NULL;
- server_iface = vino_server_get_network_interface (listener->server);
- ipv4 = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
- ipv6 = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
-
- getifaddrs (&myaddrs);
- for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
- {
- if (ifa->ifa_addr == NULL || ifa->ifa_name == NULL || (ifa->ifa_flags & IFF_UP) == 0)
- continue;
-
- switch (ifa->ifa_addr->ADDR_FAMILY_MEMBER)
- {
- case AF_INET:
- sin = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
- inet_ntop (AF_INET, sin, buf, INET6_ADDRSTRLEN);
- g_hash_table_insert (ipv4,
- ifa->ifa_name,
- g_strdup (buf));
- break;
-
- case AF_INET6:
- sin = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
- inet_ntop (AF_INET6, sin, buf, INET6_ADDRSTRLEN);
- g_hash_table_insert (ipv6,
- ifa->ifa_name,
- g_strdup (buf));
- break;
- default: continue;
- }
- }
+ VinoDBusListener *listener = (VinoDBusListener *) object;
- if (server_iface && server_iface[0] != '\0')
- {
- if ((retval = g_strdup (g_hash_table_lookup (ipv4, server_iface))))
- goto the_end;
- if ((retval = g_strdup (g_hash_table_lookup (ipv6, server_iface))))
- goto the_end;
- }
-
- g_hash_table_iter_init (&iter, ipv4);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- if (strncmp (key, "lo", 2) == 0)
- continue;
- retval = g_strdup (value);
- goto the_end;
- }
-
- g_hash_table_iter_init (&iter, ipv6);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- if (strncmp (key, "lo", 2) == 0)
- continue;
- retval = g_strdup (value);
- goto the_end;
- }
+ g_object_unref (listener->connection);
+ g_free (listener->path);
+ if (listener->server)
+ g_object_unref (listener->server);
- if ((retval = g_strdup (g_hash_table_lookup (ipv4, "lo"))))
- goto the_end;
- if ((retval = g_strdup (g_hash_table_lookup (ipv6, "lo"))))
- goto the_end;
-
- the_end:
- freeifaddrs (myaddrs);
- g_hash_table_destroy (ipv4);
- g_hash_table_destroy (ipv6);
-
- return retval;
-}
#ifdef HAVE_TELEPATHY_GLIB
-
-static void
-vino_dbus_listener_dispose (GObject *object)
-{
- VinoDBusListener *listener = VINO_DBUS_LISTENER (object);
-
- if (listener->priv->manager != NULL)
+ if (listener->manager != NULL)
{
g_object_unref (listener->priv->manager);
listener->priv->manager = NULL;
}
+#endif
- if (G_OBJECT_CLASS (vino_dbus_listener_parent_class)->dispose)
- G_OBJECT_CLASS (vino_dbus_listener_parent_class)->dispose (object);
+ G_OBJECT_CLASS (vino_dbus_listener_parent_class)
+ ->finalize (object);
}
-#endif
static void
vino_dbus_listener_init (VinoDBusListener *listener)
{
#ifdef HAVE_TELEPATHY_GLIB
- listener->priv->manager = vino_tube_servers_manager_new ();
+ listener->manager = vino_tube_servers_manager_new ();
#endif
}
static void
-vino_dbus_listener_class_init (VinoDBusListenerClass *klass)
+vino_dbus_listener_class_init (GObjectClass *class)
{
-#ifdef HAVE_TELEPATHY_GLIB
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = vino_dbus_listener_dispose;
-#endif
+ class->finalize = vino_dbus_listener_finalize;
}
static guint16
@@ -223,12 +108,36 @@ vino_dbus_listener_get_property (GDBusConnection *connection,
{
VinoDBusListener *listener = user_data;
+ if (listener->server == NULL)
+ /* We (reasonably) assume that nobody will be doing Vino property
+ * queries during the extremely short period of time between
+ * connecting to the bus and acquiring our well-known name.
+ *
+ * As soon as the well-known name is acquired, GDBus invokes our
+ * name_acquired function (in vino-main.c) and that blocks until all
+ * of the servers have been setup. That completes before any more
+ * messages (ie: to the well-known name) can be dispatched.
+ *
+ * That means that the only possibility that we see property queries
+ * here without listener->server being set is in the case that the
+ * property is being queried against our unique name (which we
+ * assume won't happen).
+ */
+ {
+ g_warning ("Somebody queried vino server properties "
+ "(%s, property %s) before unique name was acquired.",
+ object_path, property_name);
+ return NULL;
+ }
+
if (strcmp (property_name, "Host") == 0)
{
gchar *local_hostname;
+ const gchar *iface;
GVariant *result;
- local_hostname = get_local_hostname (listener);
+ iface = vino_server_get_network_interface (listener->server);
+ local_hostname = vino_util_get_local_hostname (iface);
if (local_hostname)
result = g_variant_new_string (local_hostname);
else
@@ -266,6 +175,22 @@ vino_dbus_listener_get_property (GDBusConnection *connection,
g_assert_not_reached ();
}
+void
+vino_dbus_listener_set_server (VinoDBusListener *listener,
+ VinoServer *server)
+{
+ g_return_if_fail (listener->server == NULL);
+ g_return_if_fail (VINO_IS_SERVER (server));
+ g_return_if_fail (listener->screen ==
+ gdk_screen_get_number (vino_server_get_screen (server)));
+
+ listener->server = g_object_ref (server);
+
+ /* We need not notify for property changes here since we assume that
+ * nobody will have checked properties before now (see large comment
+ * above in get_property()).
+ */
+}
VinoDBusListener *
vino_dbus_listener_new (gint screen)
@@ -288,25 +213,3 @@ vino_dbus_listener_new (gint screen)
return listener;
}
-
-
-void
-vino_dbus_listener_set_server (VinoDBusListener *listener,
- VinoServer *server)
-{
- g_assert (listener->server == NULL);
- g_assert_cmpint (listener->screen, ==,
- gdk_screen_get_number (vino_server_get_screen (server)));
-
- listener->server = server;
-
- /* XXX: emit property change signal, watch for more changes
- */
-}
-
-gboolean
-vino_dbus_request_name (void)
-{
- g_application_new ("org.gnome.Vino", 0, NULL);
- return TRUE;
-}
diff --git a/server/vino-main.c b/server/vino-main.c
index cbf5337..16dc1b2 100644
--- a/server/vino-main.c
+++ b/server/vino-main.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 Sun Microsystems, Inc.
+ * Copyright © 2010 Codethink Limited
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -19,11 +20,11 @@
* Authors:
* Mark McLoughlin <mark skynet ie>
* Jonh Wendell <wendell bani com br>
+ * Ryan Lortie <desrt desrt ca>
*/
-#include <config.h>
+#include "config.h"
-#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <locale.h>
@@ -31,7 +32,6 @@
#include "vino-input.h"
#include "vino-mdns.h"
#include "vino-server.h"
-#include "vino-prefs.h"
#include "vino-util.h"
#include "vino-dbus-listener.h"
#include "eggsmclient.h"
@@ -39,88 +39,235 @@
#ifdef HAVE_GNUTLS
#include <gnutls/gnutls.h>
-#ifdef GNOME_ENABLE_DEBUG
+# ifdef GNOME_ENABLE_DEBUG
static void
vino_debug_gnutls (int level,
- const char *str)
+ const char *str)
{
fputs (str, stderr);
}
-#endif
+# endif
#endif /* HAVE_GNUTLS */
+typedef struct
+{
+ GSettings *settings;
+ GdkDisplay *display;
+ VinoDBusListener **listeners;
+ gint n_screens;
+ EggSMClient *sm_client;
+ GMainLoop *main_loop;
+} VinoApplication;
+
+static void
+enabled_changed (VinoApplication *vino)
+{
+ if (!g_settings_get_boolean (vino->settings, "enabled"))
+ {
+ g_message ("The remote desktop service has been disabled. Exiting.");
+ g_main_loop_quit (vino->main_loop);
+ }
+}
+
+static void
+bus_acquired (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ VinoApplication *vino = user_data;
+ gint i;
+
+ /* Get the listeners on their object paths before we acquire the name.
+ *
+ * This prevents incoming calls to the well-known name from finding
+ * the listeners missing.
+ *
+ * Later (after we acquire the name) we will create the server objects
+ * and register them with the listeners.
+ */
+ vino->display = gdk_display_get_default ();
+ vino->n_screens = gdk_display_get_n_screens (vino->display);
+ vino->listeners = g_new (VinoDBusListener *, vino->n_screens);
+ for (i = 0; i < vino->n_screens; i++)
+ vino->listeners[i] = vino_dbus_listener_new (i);
+}
+
+static void
+name_acquired (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ VinoApplication *vino = user_data;
+ gboolean view_only;
+ gint i;
+
+ /* Name is acquired. Start up the servers and register them with the
+ * listeners.
+ */
+ if ((view_only = !vino_input_init (vino->display)))
+ g_warning (_("Your XServer does not support the XTest extension - "
+ "remote desktop access will be view-only\n"));
+
+ for (i = 0; i < vino->n_screens; i++)
+ {
+ VinoServer *server;
+
+ /* The server is initially "on-hold" while we set everything up. */
+ server = vino_server_new (gdk_display_get_screen (vino->display,
+ i),
+ view_only);
+
+ g_settings_bind (vino->settings, "prompt-enabled",
+ server, "prompt-enabled", G_SETTINGS_BIND_GET);
+
+ /* Only bind to the user's view-only preference if we're not
+ * forced to be view-only by an incapable X server.
+ */
+ if (!view_only)
+ g_settings_bind (vino->settings, "view-only",
+ server, "view-only", G_SETTINGS_BIND_GET);
+
+ g_settings_bind (vino->settings, "network-interface",
+ server, "network-interface", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "use-alternative-port",
+ server, "use-alternative-port", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "alternative-port",
+ server, "alternative-port", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "authentication-methods",
+ server, "auth-methods", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "require-encryption",
+ server, "require-encryption", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "require-encryption",
+ server, "require-encryption", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "vnc-password",
+ server, "vnc-password", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "lock-screen-on-disconnect",
+ server, "lock-screen", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "disable-background",
+ server, "disable-background", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "use-upnp",
+ server, "use-upnp", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "disable-xdamage",
+ server, "disable-xdamage", G_SETTINGS_BIND_GET);
+ g_settings_bind (vino->settings, "icon-visibility",
+ vino_server_get_status_icon (server),
+ "visibility", G_SETTINGS_BIND_GET);
+
+ vino_dbus_listener_set_server (vino->listeners[i], server);
+ vino_server_set_on_hold (server, FALSE);
+
+ g_object_unref (server);
+ }
+}
+
+static void
+name_lost (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ VinoApplication *vino = user_data;
+
+ g_message ("The remote desktop service is already running. Exiting.");
+ g_main_loop_quit (vino->main_loop);
+}
+
+static void
+sm_quit (VinoApplication *vino)
+{
+ g_main_loop_quit (vino->main_loop);
+}
+
int
main (int argc, char **argv)
{
- GOptionContext *context;
- GdkDisplay *display;
- gboolean view_only;
- int i, n_screens;
- GError *error = NULL;
- EggSMClient *client;
+ VinoApplication vino = { 0, };
setlocale (LC_ALL, "");
bindtextdomain (GETTEXT_PACKAGE, VINO_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
- context = g_option_context_new (_("- VNC Server for GNOME"));
- g_option_context_add_group (context, gtk_get_option_group (TRUE));
- g_option_context_add_group (context, egg_sm_client_get_option_group ());
- g_option_context_parse (context, &argc, &argv, &error);
- if (error)
+ /* Parse commandline arguments */
+ {
+ GOptionContext *context;
+ GError *error = NULL;
+
+ context = g_option_context_new (_("- VNC Server for GNOME"));
+ g_option_context_add_group (context, gtk_get_option_group (TRUE));
+ g_option_context_add_group (context, egg_sm_client_get_option_group ());
+ if (!g_option_context_parse (context, &argc, &argv, &error))
+ {
+ g_print ("%s\n%s\n", error->message,
+ _("Run 'vino-server --help' to see a full list of "
+ "available command line options"));
+ g_error_free (error);
+ return 1;
+ }
+ g_option_context_free (context);
+ }
+
+ /* GSettings */
+ vino.settings = g_settings_new ("org.gnome.Vino");
+ g_signal_connect_swapped (vino.settings, "changed::enabled",
+ G_CALLBACK (enabled_changed), &vino);
+ if (!g_settings_get_boolean (vino.settings, "enabled"))
{
- g_print ("%s\n%s\n",
- error->message,
- _("Run 'vino-server --help' to see a full list of available command line options"));
- g_error_free (error);
+ g_warning ("The remote desktop service is not "
+ "enabled, so it should not be run.");
return 1;
}
- client = egg_sm_client_get ();
- egg_sm_client_set_mode (EGG_SM_CLIENT_MODE_NO_RESTART);
- g_signal_connect (client, "quit",
- G_CALLBACK (gtk_main_quit), NULL);
-
- vino_setup_debug_flags ();
+ gtk_window_set_default_icon_name ("preferences-desktop-remote-desktop");
+ g_set_application_name (_("GNOME Remote Desktop"));
+ vino.main_loop = g_main_loop_new (NULL, FALSE);
-#ifdef HAVE_GNUTLS
#ifdef GNOME_ENABLE_DEBUG
+ vino_setup_debug_flags ();
+# ifdef HAVE_GNUTLS
if (_vino_debug_flags & VINO_DEBUG_TLS)
{
gnutls_global_set_log_level (10);
gnutls_global_set_log_function (vino_debug_gnutls);
}
+# endif /* HAVE_GNUTLS */
#endif
-#endif /* HAVE_GNUTLS */
- gtk_window_set_default_icon_name ("preferences-desktop-remote-desktop");
- g_set_application_name (_("GNOME Remote Desktop"));
+ /* Session management */
+ vino.sm_client = egg_sm_client_get ();
+ egg_sm_client_set_mode (EGG_SM_CLIENT_MODE_NO_RESTART);
+ g_signal_connect_swapped (vino.sm_client, "quit",
+ G_CALLBACK (sm_quit), &vino);
- if (!vino_dbus_request_name ())
- return 1;
- display = gdk_display_get_default ();
+ /* Start attempting to acquire the bus name.
+ * This starts everything...
+ */
+ g_bus_own_name (G_BUS_TYPE_SESSION, "org.gnome.Vino",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ bus_acquired, name_acquired, name_lost,
+ &vino, NULL);
- view_only = FALSE;
- if (!vino_input_init (display))
- {
- g_warning (_("Your XServer does not support the XTest extension - "
- "remote desktop access will be view-only\n"));
- view_only = TRUE;
- }
- vino_prefs_init (view_only);
+ g_main_loop_run (vino.main_loop);
- n_screens = gdk_display_get_n_screens (display);
- for (i = 0; i < n_screens; i++)
- vino_dbus_listener_set_server (vino_dbus_listener_new (i), vino_prefs_create_server (gdk_display_get_screen (display, i)));
- gtk_main ();
+ /* Shutdown */
+ if (vino.listeners)
+ {
+ gint i;
+
+ /* We need to finalize these to ensure
+ * that mdns gets shutdown properly.
+ */
+ for (i = 0; i < vino.n_screens; i++)
+ g_object_unref (vino.listeners[i]);
- vino_mdns_shutdown ();
+ g_free (vino.listeners);
+ }
- vino_prefs_shutdown ();
+ g_main_loop_unref (vino.main_loop);
+ g_object_unref (vino.sm_client);
+ g_object_unref (vino.settings);
return 0;
}
diff --git a/server/vino-prefs.c b/server/vino-prefs.c
index f6a54df..87d8df0 100644
--- a/server/vino-prefs.c
+++ b/server/vino-prefs.c
@@ -36,9 +36,6 @@
#include "vino-mdns.h"
#include "vino-status-icon.h"
-#define VINO_PREFS_LOCKFILE "vino-server.lock"
-
-static GSettings *background_settings = NULL;
static GSettings *settings = NULL;
static gboolean force_view_only;
@@ -51,15 +48,6 @@ vino_prefs_restart_mdns (VinoServer *server,
vino_mdns_start (vino_server_get_network_interface (server));
}
-static gboolean
-get_inverted_boolean (GValue *value,
- GVariant *variant,
- gpointer user_data)
-{
- g_value_set_boolean (value, !g_variant_get_boolean (variant));
- return TRUE;
-}
-
VinoServer *
vino_prefs_create_server (GdkScreen *screen)
{
@@ -116,82 +104,9 @@ vino_prefs_create_server (GdkScreen *screen)
}
static void
-vino_prefs_restore_background (void)
-{
- if (g_settings_get_boolean (settings, "disable-background"))
- g_settings_set_boolean (background_settings, "draw-background", TRUE);
-}
-
-static gchar *
-vino_prefs_lock_filename (void)
-{
- gchar *dir;
-
- dir = g_build_filename (g_get_user_data_dir (),
- "vino",
- NULL);
- if (!g_file_test (dir, G_FILE_TEST_EXISTS))
- g_mkdir_with_parents (dir, 0755);
-
- g_free (dir);
-
- return g_build_filename (g_get_user_data_dir (),
- "vino",
- VINO_PREFS_LOCKFILE,
- NULL);
-}
-
-static gboolean
-vino_prefs_lock (void)
-{
- gchar *lockfile;
- gboolean res;
-
- res = FALSE;
- lockfile = vino_prefs_lock_filename ();
-
- if (g_file_test (lockfile, G_FILE_TEST_EXISTS))
- {
- dprintf (PREFS, "WARNING: The lock file (%s) already exists\n", lockfile);
- }
- else
- {
- g_creat (lockfile, 0644);
- res = TRUE;
- }
-
- g_free (lockfile);
- return res;
-}
-
-static gboolean
-vino_prefs_unlock (void)
-{
- gchar *lockfile;
- gboolean res;
-
- res = FALSE;
- lockfile = vino_prefs_lock_filename ();
-
- if (!g_file_test (lockfile, G_FILE_TEST_EXISTS))
- {
- dprintf (PREFS, "WARNING: Lock file (%s) not found!\n", lockfile);
- }
- else
- {
- g_unlink (lockfile);
- res = TRUE;
- }
-
- g_free (lockfile);
- return res;
-}
-
-static void
vino_prefs_sighandler (int sig)
{
g_message (_("Received signal %d, exiting...\n"), sig);
- vino_prefs_restore_background ();
vino_mdns_shutdown ();
vino_prefs_shutdown ();
exit (0);
@@ -227,10 +142,6 @@ vino_prefs_init (gboolean view_only)
void
vino_prefs_shutdown (void)
{
- g_object_unref (background_settings);
g_object_unref (settings);
- background_settings = NULL;
settings = NULL;
-
- vino_prefs_unlock ();
}
diff --git a/server/vino-util.c b/server/vino-util.c
index d7e39d8..c41f6cb 100644
--- a/server/vino-util.c
+++ b/server/vino-util.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Jonh Wendell <wendell bani com br>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -17,14 +18,37 @@
* 02111-1307, USA.
*
* Authors:
+ * Jonh Wendell <wendell bani com br>
* Mark McLoughlin <mark skynet ie>
*/
-#include <config.h>
+#include "config.h"
#include "vino-util.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
#include <gtk/gtk.h>
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#else
+#include "libvncserver/ifaddr/ifaddrs.h"
+#endif
+
+#ifdef RFC2553
+#define ADDR_FAMILY_MEMBER ss_family
+#else
+#define ADDR_FAMILY_MEMBER sa_family
+#endif
+
#ifdef GNOME_ENABLE_DEBUG
VinoDebugFlags _vino_debug_flags = VINO_DEBUG_NONE;
@@ -135,3 +159,82 @@ vino_util_show_error (const gchar *title, const gchar *message, GtkWindow *paren
gtk_widget_show_all (GTK_WIDGET(d));
}
+gchar *
+vino_util_get_local_hostname (const gchar *server_iface)
+{
+ char *retval, buf[INET6_ADDRSTRLEN];
+ struct ifaddrs *myaddrs, *ifa;
+ void *sin;
+ GHashTable *ipv4, *ipv6;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ retval = NULL;
+ ipv4 = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
+ ipv6 = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
+
+ getifaddrs (&myaddrs);
+ for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr == NULL || ifa->ifa_name == NULL || (ifa->ifa_flags & IFF_UP) == 0)
+ continue;
+
+ switch (ifa->ifa_addr->ADDR_FAMILY_MEMBER)
+ {
+ case AF_INET:
+ sin = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
+ inet_ntop (AF_INET, sin, buf, INET6_ADDRSTRLEN);
+ g_hash_table_insert (ipv4,
+ ifa->ifa_name,
+ g_strdup (buf));
+ break;
+
+ case AF_INET6:
+ sin = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
+ inet_ntop (AF_INET6, sin, buf, INET6_ADDRSTRLEN);
+ g_hash_table_insert (ipv6,
+ ifa->ifa_name,
+ g_strdup (buf));
+ break;
+ default: continue;
+ }
+ }
+
+ if (server_iface && server_iface[0] != '\0')
+ {
+ if ((retval = g_strdup (g_hash_table_lookup (ipv4, server_iface))))
+ goto the_end;
+ if ((retval = g_strdup (g_hash_table_lookup (ipv6, server_iface))))
+ goto the_end;
+ }
+
+ g_hash_table_iter_init (&iter, ipv4);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ if (strncmp (key, "lo", 2) == 0)
+ continue;
+ retval = g_strdup (value);
+ goto the_end;
+ }
+
+ g_hash_table_iter_init (&iter, ipv6);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ if (strncmp (key, "lo", 2) == 0)
+ continue;
+ retval = g_strdup (value);
+ goto the_end;
+ }
+
+ if ((retval = g_strdup (g_hash_table_lookup (ipv4, "lo"))))
+ goto the_end;
+ if ((retval = g_strdup (g_hash_table_lookup (ipv6, "lo"))))
+ goto the_end;
+
+ the_end:
+ freeifaddrs (myaddrs);
+ g_hash_table_destroy (ipv4);
+ g_hash_table_destroy (ipv6);
+
+ return retval;
+}
diff --git a/server/vino-util.h b/server/vino-util.h
index 97b0ae3..a93437f 100644
--- a/server/vino-util.h
+++ b/server/vino-util.h
@@ -78,8 +78,6 @@ void vino_setup_debug_flags (void);
# define dprintf(args...)
#endif
-#define vino_setup_debug_flags()
-
#endif /* GNOME_ENABLE_DEBUG */
void vino_init_stock_items (void);
@@ -88,6 +86,8 @@ void vino_util_show_error (const gchar *title,
const gchar *message,
GtkWindow *parent);
+gchar *vino_util_get_local_hostname (const gchar *server_iface);
+
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]