[vino/3] GSettings + GDBus + GtkApplication



commit 854a89544020c087680cce2c36cdcda9f38b841d
Author: Ryan Lortie <desrt desrt ca>
Date:   Sun Jul 4 22:45:22 2010 -0400

    GSettings + GDBus + GtkApplication
    
    goodbye to GConf, dbus-glib, libunique

 Makefile.am                       |    2 +-
 capplet/Makefile.am               |   14 +-
 capplet/vino-connectivity-info.c  |  379 +++++++++++
 capplet/vino-connectivity-info.h  |   12 +
 capplet/vino-preferences.c        | 1317 +++++++------------------------------
 capplet/vino-preferences.ui       |  150 +++--
 common/.gitignore                 |    1 +
 common/Makefile.am                |   10 +
 common/org.gnome.Vino.gschema.xml |  171 +++++
 common/vino-dbus.c                |   90 +++
 common/vino-dbus.h                |   34 +
 common/vino-keyring.c             |  102 +++
 common/vino-keyring.h             |   30 +
 configure.in                      |   41 +-
 server/Makefile.am                |   11 -
 server/vino-fb.c                  |  155 ++---
 server/vino-fb.h                  |    4 +-
 server/vino-prefs.c               |    1 -
 server/vino-server.c              |   32 +-
 19 files changed, 1244 insertions(+), 1312 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index c279b4a..f34df1c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
 ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
-SUBDIRS = server capplet tools docs po
+SUBDIRS = common server capplet tools docs po
 
 EXTRA_DIST =                \
 	MAINTAINERS         \
diff --git a/capplet/Makefile.am b/capplet/Makefile.am
index 4de42c8..27c3db3 100644
--- a/capplet/Makefile.am
+++ b/capplet/Makefile.am
@@ -1,6 +1,7 @@
 NULL =
 
 INCLUDES = \
+	-I$(top_srcdir)/common \
 	-DVINO_LOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"  \
 	-DVINO_UIDIR=\""$(datadir)/vino"\" \
 	-DVINO_ICONDIR=\""$(datadir)/pixmaps\"" \
@@ -15,10 +16,17 @@ INCLUDES = \
 bin_PROGRAMS = vino-preferences
 
 vino_preferences_SOURCES = \
-	vino-preferences.c \
-	vino-message-box.h vino-message-box.c \
-	vino-url-webservice.h vino-url-webservice.c \
+	../common/vino-dbus.c		\
+	../common/vino-keyring.c	\
+	vino-connectivity-info.h	\
+	vino-connectivity-info.c	\
+	vino-url-webservice.h		\
+	vino-url-webservice.c		\
+	vino-message-box.h		\
+	vino-message-box.c		\
+	vino-preferences.c		\
 	$(NULL)
+
 vino_preferences_LDADD = \
 	$(VINO_CAPPLET_LIBS) \
 	$(VINO_KEYRING_LIBS) \
diff --git a/capplet/vino-connectivity-info.c b/capplet/vino-connectivity-info.c
new file mode 100644
index 0000000..35f42cc
--- /dev/null
+++ b/capplet/vino-connectivity-info.c
@@ -0,0 +1,379 @@
+/*
+ * 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
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#include "config.h"
+
+#include "vino-connectivity-info.h"
+
+#include "vino-url-webservice.h"
+#include "vino-dbus.h"
+
+#include <libsoup/soup.h>
+#include <string.h>
+
+struct _VinoConnectivityInfo
+{
+  GObject      parent_instance;
+  SoupSession *soup_session;
+  GDBusProxy  *proxy;
+
+  gboolean     stable;
+
+  gchar       *internal_host;
+  guint16      internal_port;
+  gchar       *avahi_host;
+
+  gchar       *external_host;
+  guint16      external_port;
+
+  /* either all set or all unset */
+  guint16      checking_port;
+  SoupMessage *checking_msg;
+  guint        checking_timeout;
+};
+
+typedef GObjectClass VinoConnectivityInfoClass;
+
+static guint vino_connectivity_info_changed_signal;
+
+static GType vino_connectivity_info_get_type (void);
+G_DEFINE_TYPE (VinoConnectivityInfo,
+               vino_connectivity_info,
+               G_TYPE_OBJECT);
+
+#define VINO_WEBSERVICE_TIMEOUT 6
+
+static void
+vino_connectivity_info_changed (VinoConnectivityInfo *info,
+                                gboolean              stable)
+{
+  if (info->stable || stable)
+    {
+      info->stable = stable;
+      g_signal_emit (info, vino_connectivity_info_changed_signal, 0);
+    }
+}
+
+static void
+vino_connectivity_info_soup_finished (SoupSession *session,
+                                      SoupMessage *msg,
+                                      gpointer     user_data)
+{
+  VinoConnectivityInfo *info = user_data;
+  GHashTable *table;
+  gchar *ip = NULL;
+
+  if (msg->status_code == SOUP_STATUS_OK &&
+      soup_xmlrpc_extract_method_response (msg->response_body->data,
+                                           msg->response_body->length,
+                                           NULL,
+                                           G_TYPE_HASH_TABLE, &table,
+                                           G_TYPE_INVALID))
+    {
+      GHashTableIter iter;
+      gboolean status;
+      gpointer value;
+      gpointer key;
+
+      g_hash_table_iter_init (&iter, table);
+      status = FALSE;
+
+      while (g_hash_table_iter_next (&iter, &key, &value))
+        {
+          if (strcmp (key, "status") == 0 && G_VALUE_HOLDS_BOOLEAN (value))
+            status = g_value_get_boolean (value);
+
+          else if (strcmp (key, "ip") == 0 && G_VALUE_HOLDS_STRING (value))
+            ip = g_value_dup_string (value);
+        }
+
+      g_hash_table_unref (table);
+
+      if (!status)
+        {
+          g_free (ip);
+          ip = NULL;
+        }
+    }
+
+  info->external_port = ip ? info->checking_port : 0;
+  g_free (info->external_host);
+  info->external_host = ip;
+
+  g_source_remove (info->checking_timeout);
+  info->checking_timeout = 0;
+  info->checking_msg = NULL;
+  info->checking_port = 0;
+
+  vino_connectivity_info_changed (info, TRUE);
+}
+
+static gboolean
+vino_connectivity_info_soup_timed_out (gpointer user_data)
+{
+  VinoConnectivityInfo *info = user_data;
+
+  g_assert (info->checking_msg != NULL);
+  soup_session_cancel_message (info->soup_session,
+                               info->checking_msg,
+                               SOUP_STATUS_REQUEST_TIMEOUT);
+  g_assert (info->checking_msg == NULL);
+
+  return FALSE;
+}
+
+static void
+get_property_string (GDBusProxy   *proxy,
+                     const gchar  *property,
+                     gchar       **str)
+{
+  GVariant *value;
+
+  g_free (*str);
+  *str = NULL;
+
+  if ((value = g_dbus_proxy_get_cached_property (proxy, property)))
+    {
+      if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+        {
+          const gchar *tmp = g_variant_get_string (value, NULL);
+
+          if (*tmp)
+            *str = g_strdup (tmp);
+        }
+      g_variant_unref (value);
+    }
+}
+
+static void
+get_property_uint16 (GDBusProxy  *proxy,
+                     const gchar *property,
+                     guint16     *out)
+{
+  GVariant *value;
+
+  *out = 0;
+
+  if ((value = g_dbus_proxy_get_cached_property (proxy, property)))
+    {
+      if (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT16))
+        *out = g_variant_get_uint16 (value);
+      g_variant_unref (value);
+    }
+}
+
+static void
+vino_connectivity_info_properties_changed (VinoConnectivityInfo *info)
+{
+  /* Cancel any in-flight webservice requests */
+  if (info->checking_port)
+    {
+      g_source_remove (info->checking_timeout);
+      info->checking_timeout = 0;
+      info->checking_msg = NULL;
+      info->checking_port = 0;
+
+      soup_session_abort (info->soup_session);
+    }
+
+  get_property_string (info->proxy, "ExternalHost", &info->external_host);
+  get_property_uint16 (info->proxy, "ExternalPort", &info->external_port);
+  get_property_string (info->proxy, "AvahiHost", &info->avahi_host);
+  get_property_string (info->proxy, "Host", &info->internal_host);
+  get_property_uint16 (info->proxy, "Port", &info->internal_port);
+
+  /* No external host without external port */
+  if (info->external_port == 0)
+    {
+      g_free (info->external_host);
+      info->external_host = NULL;
+    }
+
+  /* No internal port without internal host */
+  if (!info->internal_host)
+    info->internal_port = 0;
+
+  /* No internal or avahi hosts without internal port */
+  if (info->internal_port == 0)
+    {
+      g_free (info->internal_host);
+      info->internal_host = NULL;
+      g_free (info->avahi_host);
+      info->avahi_host = NULL;
+    }
+
+  if (!info->external_host)
+    {
+      /* We have no external hostname, so we can try and guess it using
+       * the webservice to connect to the external port (if given) or
+       * internal port (otherwise, if given).
+       */
+      if (info->external_port)
+        info->checking_port = info->external_port;
+      else
+        info->checking_port = info->internal_port;
+
+      info->external_port = 0;
+    }
+
+  if (info->checking_port)
+    {
+      gchar *url;
+
+      url = vino_url_webservice_get_random ();
+
+      if (url)
+        {
+          info->checking_msg =
+            soup_xmlrpc_request_new (url, "vino.check",
+                                     G_TYPE_INT, info->checking_port,
+                                     G_TYPE_INT, VINO_WEBSERVICE_TIMEOUT,
+                                     G_TYPE_INVALID);
+          info->checking_timeout =
+            g_timeout_add (1000 * (VINO_WEBSERVICE_TIMEOUT + 1),
+                           vino_connectivity_info_soup_timed_out,
+                           info);
+
+          soup_session_queue_message (info->soup_session,
+                                      info->checking_msg,
+                                      vino_connectivity_info_soup_finished,
+                                      info);
+          g_free (url);
+        }
+      else
+        info->checking_port = 0;
+    }
+
+  vino_connectivity_info_changed (info, info->checking_port == 0);
+}
+
+static void
+vino_connectivity_info_proxy_ready (GObject      *source,
+                                    GAsyncResult *result,
+                                    gpointer      user_data)
+{
+  VinoConnectivityInfo *info = user_data;
+
+  info->proxy = g_dbus_proxy_new_for_bus_finish (result, NULL);
+
+  if (info->proxy)
+    {
+      g_signal_connect_swapped (info->proxy, "g-properties-changed",
+        G_CALLBACK (vino_connectivity_info_properties_changed), info);
+
+      /* TODO: remove when #623538 is fixed */
+      g_signal_connect_swapped (info->proxy, "notify::g-name-owner",
+        G_CALLBACK (vino_connectivity_info_properties_changed), info);
+
+      vino_connectivity_info_properties_changed (info);
+    }
+  else
+    vino_connectivity_info_changed (info, TRUE);
+}
+
+static void
+vino_connectivity_info_finalize (GObject *object)
+{
+  VinoConnectivityInfo *info = (VinoConnectivityInfo *) object;
+
+  if (info->proxy)
+    g_object_unref (info->proxy);
+
+  if (info->checking_timeout)
+    g_source_remove (info->checking_timeout);
+
+  soup_session_abort (info->soup_session);
+  g_object_unref (info->soup_session);
+  g_free (info->internal_host);
+  g_free (info->external_host);
+  g_free (info->avahi_host);
+
+  G_OBJECT_CLASS (vino_connectivity_info_parent_class)
+    ->finalize (object);
+}
+
+static void
+vino_connectivity_info_init (VinoConnectivityInfo *info)
+{
+}
+
+static void
+vino_connectivity_info_class_init (GObjectClass *class)
+{
+  class->finalize = vino_connectivity_info_finalize;
+
+  vino_connectivity_info_changed_signal =
+    g_signal_new ("changed", vino_connectivity_info_get_type (),
+                  G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+VinoConnectivityInfo *
+vino_connectivity_info_new (gint screen_number)
+{
+  VinoConnectivityInfo *info;
+  gchar *object_path;
+
+  info = g_object_new (vino_connectivity_info_get_type (), NULL);
+  info->soup_session = soup_session_async_new ();
+
+  object_path = g_strdup_printf ("%s%d",
+                                 ORG_GNOME_VINO_SCREEN_PATH_PREFIX,
+                                 screen_number);
+  g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+                            G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+                            ORG_GNOME_VINO_SCREEN_INTERFACE,
+                            ORG_GNOME_VINO_BUS_NAME, object_path,
+                            ORG_GNOME_VINO_SCREEN_INTERFACE_NAME, NULL,
+                            vino_connectivity_info_proxy_ready, info);
+  g_free (object_path);
+
+  return info;
+
+}
+
+gboolean
+vino_connectivity_info_get (VinoConnectivityInfo  *info,
+                            gchar                **internal_host,
+                            guint16               *internal_port,
+                            gchar                **external_host,
+                            guint16               *external_port,
+                            gchar                **avahi_host)
+{
+  if (info->stable)
+    {
+      *external_host = g_strdup (info->external_host);
+      *internal_host = g_strdup (info->internal_host);
+      *avahi_host = g_strdup (info->avahi_host);
+      *external_port = info->external_port;
+      *internal_port = info->internal_port;
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+void
+vino_connectivity_info_check (VinoConnectivityInfo *info)
+{
+  vino_connectivity_info_properties_changed (info);
+}
diff --git a/capplet/vino-connectivity-info.h b/capplet/vino-connectivity-info.h
new file mode 100644
index 0000000..c37698a
--- /dev/null
+++ b/capplet/vino-connectivity-info.h
@@ -0,0 +1,12 @@
+#include <glib.h>
+
+typedef struct _VinoConnectivityInfo VinoConnectivityInfo;
+
+VinoConnectivityInfo * vino_connectivity_info_new (gint screen_number);
+gboolean vino_connectivity_info_get (VinoConnectivityInfo  *info,
+                                     gchar                **internal_host,
+                                     guint16               *internal_port,
+                                     gchar                **external_host,
+                                     guint16               *external_port,
+                                     gchar                **avahi_host);
+void vino_connectivity_info_check (VinoConnectivityInfo *info);
diff --git a/capplet/vino-preferences.c b/capplet/vino-preferences.c
index 7c6f1b6..ca613c5 100644
--- a/capplet/vino-preferences.c
+++ b/capplet/vino-preferences.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2003 Sun Microsystems, Inc.
  * Copyright (C) 2006 Jonh Wendell <wendell bani com br> 
+ * 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
@@ -20,1228 +21,358 @@
  * Authors:
  *      Mark McLoughlin <mark skynet ie>
  *      Jonh Wendell <wendell bani com br>
+ *      Ryan Lortie <desrt desrt ca>
  */
 
-#include <config.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include <gconf/gconf-client.h>
-#include <dbus/dbus-glib.h>
-#include <glib/gi18n.h>
-#include <libsoup/soup.h>
+#include "config.h"
+
+#include "vino-connectivity-info.h"
 #include "vino-message-box.h"
-#include "vino-url-webservice.h"
-
-#ifdef VINO_ENABLE_KEYRING
-#include <gnome-keyring.h>
-#endif
-
-#ifdef VINO_ENABLE_LIBUNIQUE
-#include <unique/unique.h>
-#endif
-
-#define VINO_PREFS_DIR                    "/desktop/gnome/remote_access"
-#define VINO_PREFS_ENABLED                VINO_PREFS_DIR "/enabled"
-#define VINO_PREFS_PROMPT_ENABLED         VINO_PREFS_DIR "/prompt_enabled"
-#define VINO_PREFS_VIEW_ONLY              VINO_PREFS_DIR "/view_only"
-#define VINO_PREFS_AUTHENTICATION_METHODS VINO_PREFS_DIR "/authentication_methods"
-#define VINO_PREFS_VNC_PASSWORD           VINO_PREFS_DIR "/vnc_password"
-#define VINO_PREFS_ICON_VISIBILITY        VINO_PREFS_DIR "/icon_visibility"
-#define VINO_PREFS_USE_UPNP               VINO_PREFS_DIR "/use_upnp"
-
-#define N_LISTENERS                       7
-
-#define VINO_DBUS_BUS_NAME  "org.gnome.Vino"
-#define VINO_DBUS_INTERFACE "org.gnome.VinoScreen"
-
-typedef struct {
-  GtkBuilder  *builder;
-  GConfClient *client;
-
-  GtkWidget   *dialog;
-  GtkWidget   *writability_warning;
-  GtkWidget   *allowed_toggle;
-  GtkWidget   *view_only_toggle;
-  GtkWidget   *message;
-  GtkWidget   *prompt_enabled_toggle;
-  GtkWidget   *password_toggle;
-  GtkWidget   *password_entry;
-  GtkWidget   *icon_always_radio;
-  GtkWidget   *icon_client_radio;
-  GtkWidget   *icon_never_radio;
-  GtkWidget   *use_upnp_toggle;
-#ifdef VINO_ENABLE_LIBUNIQUE
-  UniqueApp   *app;
-#endif
-
-  DBusGConnection *connection;
-  DBusGProxy      *proxy;
-  DBusGProxyCall  *call_id;
-
-  SoupSession     *session;
-  SoupMessage     *msg;
-  gint            port;
-
-  guint        listeners [N_LISTENERS];
-  int          n_listeners;
-  int          expected_listeners;
-
-  guint        use_password : 1;
-  guint        retrieving_info : 1;
-} VinoPreferencesDialog;
-
-static void vino_preferences_dialog_update_message_box (VinoPreferencesDialog *dialog);
-
-
-static char *
-vino_preferences_dialog_get_password_from_keyring (VinoPreferencesDialog *dialog)
-{
-#ifdef VINO_ENABLE_KEYRING
-  GnomeKeyringNetworkPasswordData *found_item;
-  GnomeKeyringResult               result;
-  GList                           *matches;
-  char                            *password;
-  
-  matches = NULL;
-
-  result = gnome_keyring_find_network_password_sync (
-                NULL,           /* user     */
-		NULL,           /* domain   */
-		"vino.local",   /* server   */
-		NULL,           /* object   */
-		"rfb",          /* protocol */
-		"vnc-password", /* authtype */
-		5900,           /* port     */
-		&matches);
-
-  if (result != GNOME_KEYRING_RESULT_OK || matches == NULL || matches->data == NULL)
-    return NULL;
-
-
-  found_item = (GnomeKeyringNetworkPasswordData *) matches->data;
-
-  password = g_strdup (found_item->password);
-
-  gnome_keyring_network_password_list_free (matches);
-
-  return password;
-#else
-  return NULL;
-#endif
-}
+#include "vino-keyring.h"
 
-static gboolean
-vino_preferences_dialog_set_password_in_keyring (VinoPreferencesDialog *dialog,
-                                                 const char            *password)
-{
-#ifdef VINO_ENABLE_KEYRING
-  GnomeKeyringResult result;
-  guint32            item_id;
-
-  result = gnome_keyring_set_network_password_sync (
-                NULL,           /* default keyring */
-                NULL,           /* user            */
-                NULL,           /* domain          */
-                "vino.local",   /* server          */
-                NULL,           /* object          */
-                "rfb",          /* protocol        */
-                "vnc-password", /* authtype        */
-                5900,           /* port            */
-                password,       /* password        */
-                &item_id);
-
-  return result == GNOME_KEYRING_RESULT_OK;
-#else
-  return FALSE;
-#endif
-}
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
 
-static void
-vino_preferences_dialog_update_for_allowed (VinoPreferencesDialog *dialog,
-					    gboolean               allowed)
+typedef struct
 {
-  gtk_widget_set_sensitive (dialog->view_only_toggle,         allowed);
-  gtk_widget_set_sensitive (dialog->prompt_enabled_toggle,    allowed);
-  gtk_widget_set_sensitive (dialog->password_toggle,          allowed);
-  gtk_widget_set_sensitive (dialog->password_entry,           allowed ? dialog->use_password : FALSE);
-  gtk_widget_set_sensitive (dialog->use_upnp_toggle,          allowed);
-  gtk_widget_set_sensitive (dialog->icon_always_radio,        allowed);
-  gtk_widget_set_sensitive (dialog->icon_client_radio,        allowed);
-  gtk_widget_set_sensitive (dialog->icon_never_radio,         allowed);
-}
+  GtkApplication        parent_instance;
 
-static gboolean
-delay_update_message (VinoPreferencesDialog *dialog)
-{
-  vino_preferences_dialog_update_message_box (dialog);
-  return FALSE;
-}
+  VinoConnectivityInfo *info;
+  VinoMessageBox       *message_box;
+} VinoPreferences;
 
-static void
-vino_preferences_dialog_allowed_toggled (GtkToggleButton       *toggle,
-					 VinoPreferencesDialog *dialog)
-{
-  gboolean allowed;
+typedef GtkApplicationClass VinoPreferencesClass;
 
-  allowed = gtk_toggle_button_get_active (toggle);
+static GType vino_preferences_get_type (void);
+G_DEFINE_TYPE (VinoPreferences, vino_preferences, GTK_TYPE_APPLICATION)
 
-  gconf_client_set_bool (dialog->client, VINO_PREFS_ENABLED, allowed, NULL);
-
-  vino_preferences_dialog_update_for_allowed (dialog, allowed);
-  
-  /* ugly: here I delay the GetInfo for 3 seconds, time necessary to server starts */
-  if (allowed)
-    {
-      vino_message_box_show_image (VINO_MESSAGE_BOX (dialog->message));
-      vino_message_box_set_label (VINO_MESSAGE_BOX (dialog->message),
-                                  _("Checking the connectivity of this machine..."));
-      g_timeout_add_seconds (3, (GSourceFunc) delay_update_message, dialog);
-    }
-  else
-    {
-      if (dialog->retrieving_info)
-	{
-	  dialog->retrieving_info = FALSE;
-	  soup_session_cancel_message (dialog->session, dialog->msg, 408);
-	}
-      vino_preferences_dialog_update_message_box (dialog);
-    }
-}
-
-static void
-vino_preferences_dialog_allowed_notify (GConfClient           *client,
-					guint                  cnx_id,
-					GConfEntry            *entry,
-					VinoPreferencesDialog *dialog)
-{
-  gboolean allowed;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-    return;
-
-  allowed = gconf_value_get_bool (entry->value) != FALSE;
-
-  if (allowed != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->allowed_toggle)))
-    {
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->allowed_toggle), allowed);
-    }
-}
 
+/* We define two GSettings mappings here:
+ *
+ * First, a relatively boring boolean inversion mapping.
+ */
 static gboolean
-vino_preferences_dialog_setup_allowed_toggle (VinoPreferencesDialog *dialog)
-{
-  gboolean allowed;
-
-  dialog->allowed_toggle = GTK_WIDGET (gtk_builder_get_object (dialog->builder,
-                                                               "allowed_toggle"));
-  g_assert (dialog->allowed_toggle != NULL);
-
-  allowed = gconf_client_get_bool (dialog->client, VINO_PREFS_ENABLED, NULL);
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->allowed_toggle), allowed);
-
-  g_signal_connect (dialog->allowed_toggle, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_allowed_toggled), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_ENABLED, NULL))
-    {
-      gtk_widget_set_sensitive (dialog->allowed_toggle, FALSE);
-      gtk_widget_show (dialog->writability_warning);
-    }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_ENABLED,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_allowed_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
-
-  return allowed;
-}
-
-static void
-vino_preferences_dialog_prompt_enabled_toggled (GtkToggleButton       *toggle,
-						VinoPreferencesDialog *dialog)
-{
-  gconf_client_set_bool (dialog->client,
-			 VINO_PREFS_PROMPT_ENABLED,
-			 gtk_toggle_button_get_active (toggle),
-			 NULL);
-}
-
-static void
-vino_preferences_dialog_prompt_enabled_notify (GConfClient           *client,
-					       guint                  cnx_id,
-					       GConfEntry            *entry,
-					       VinoPreferencesDialog *dialog)
-{
-  gboolean prompt_enabled;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-    return;
-
-  prompt_enabled = gconf_value_get_bool (entry->value) != FALSE;
-
-  if (prompt_enabled != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->prompt_enabled_toggle)))
-    {
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->prompt_enabled_toggle), prompt_enabled);
-    }
-}
-
-static void
-vino_preferences_dialog_setup_prompt_enabled_toggle (VinoPreferencesDialog *dialog)
-{
-  gboolean prompt_enabled;
-
-  dialog->prompt_enabled_toggle = GTK_WIDGET (gtk_builder_get_object (dialog->builder,
-                                                                      "prompt_enabled_toggle"));
-  g_assert (dialog->prompt_enabled_toggle != NULL);
-
-  prompt_enabled = gconf_client_get_bool (dialog->client, VINO_PREFS_PROMPT_ENABLED, NULL);
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->prompt_enabled_toggle), prompt_enabled);
-
-  g_signal_connect (dialog->prompt_enabled_toggle, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_prompt_enabled_toggled), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_PROMPT_ENABLED, NULL))
-    {
-      gtk_widget_set_sensitive (dialog->prompt_enabled_toggle, FALSE);
-      gtk_widget_show (dialog->writability_warning);
-    }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_PROMPT_ENABLED,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_prompt_enabled_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
-}
-
-static void
-vino_preferences_dialog_view_only_toggled (GtkToggleButton       *toggle,
-					   VinoPreferencesDialog *dialog)
-{
-  gconf_client_set_bool (dialog->client,
-			 VINO_PREFS_VIEW_ONLY,
-			 !gtk_toggle_button_get_active (toggle),
-			 NULL);
-}
-
-static void
-vino_preferences_dialog_view_only_notify (GConfClient           *client,
-					  guint                  cnx_id,
-					  GConfEntry            *entry,
-					  VinoPreferencesDialog *dialog)
+get_inverted (GValue   *value,
+              GVariant *variant,
+              gpointer  user_data)
 {
-  gboolean view_only;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-    return;
-
-  view_only = gconf_value_get_bool (entry->value) != FALSE;
-
-  if (view_only != !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->view_only_toggle)))
-    {
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->view_only_toggle), !view_only);
-    }
+  g_value_set_boolean (value, !g_variant_get_boolean (variant));
+  return TRUE;
 }
 
-static void
-vino_preferences_dialog_setup_view_only_toggle (VinoPreferencesDialog *dialog)
+static GVariant *
+set_inverted (const GValue       *value,
+              const GVariantType *type,
+              gpointer            user_data)
 {
-  gboolean view_only;
-
-  dialog->view_only_toggle = GTK_WIDGET (gtk_builder_get_object (dialog->builder,
-                                                                 "view_only_toggle"));
-  g_assert (dialog->view_only_toggle != NULL);
-
-  view_only = gconf_client_get_bool (dialog->client, VINO_PREFS_VIEW_ONLY, NULL);
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->view_only_toggle), !view_only);
-
-  g_signal_connect (dialog->view_only_toggle, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_view_only_toggled), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_VIEW_ONLY, NULL))
-    {
-      gtk_widget_set_sensitive (dialog->view_only_toggle, FALSE);
-      gtk_widget_show (dialog->writability_warning);
-    }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_VIEW_ONLY,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_view_only_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
+  return g_variant_new_boolean (!g_value_get_boolean (value));
 }
 
-static void
-vino_preferences_dialog_icon_visibility_toggled (GtkToggleButton       *toggle,
-						 VinoPreferencesDialog *dialog)
-{
-  gchar *value = "client";
-
-  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->icon_always_radio)))
-    value = "always";
-  else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->icon_never_radio)))
-    value = "never";
-  
-  gconf_client_set_string (dialog->client,
-			   VINO_PREFS_ICON_VISIBILITY,
-			   value,
-			   NULL);
-}
 
-static void
-vino_preferences_dialog_icon_visibility_notify (GConfClient           *client,
-						guint                  cnx_id,
-						GConfEntry            *entry,
-						VinoPreferencesDialog *dialog)
+/* Next, 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
+ * the actual password.
+ *
+ * On setting the password, we always first try to use the keyring.  If
+ * that is successful we write 'keyring' to the settings.  If it fails
+ * then we base64-encode the password and write it to the settings.
+ *
+ * Doing it this way ensures that there is no ambiguity about what the
+ * password is in the event that gnome-keyring becomes available then
+ * unavailable again.
+ */
+static gboolean
+get_password (GValue   *value,
+              GVariant *variant,
+              gpointer  user_data)
 {
-  const gchar *value;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
-    return;
-
-  value = gconf_value_get_string (entry->value);
-  if (!g_ascii_strcasecmp (value, "always"))
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->icon_always_radio), TRUE);
-  else if (!g_ascii_strcasecmp (value, "client"))
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->icon_client_radio), TRUE);
-  else if (!g_ascii_strcasecmp (value, "never"))
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->icon_never_radio), TRUE);
-}
+  const gchar *setting;
 
+  setting = g_variant_get_string (variant, NULL);
 
-static void
-vino_preferences_dialog_setup_icon_visibility (VinoPreferencesDialog *dialog)
-{
-  gchar *value;
-
-  dialog->icon_always_radio = GTK_WIDGET (gtk_builder_get_object (dialog->builder,
-                                                                  "icon_always_radio"));
-  g_assert (dialog->icon_always_radio != NULL);
-  dialog->icon_client_radio = GTK_WIDGET (gtk_builder_get_object (dialog->builder,
-                                                                  "icon_client_radio"));
-  g_assert (dialog->icon_client_radio != NULL);
-  dialog->icon_never_radio = GTK_WIDGET (gtk_builder_get_object (dialog->builder,
-                                                                 "icon_never_radio"));
-  g_assert (dialog->icon_never_radio != NULL);
-
-  value = gconf_client_get_string (dialog->client, VINO_PREFS_ICON_VISIBILITY, NULL);
-  if (!g_ascii_strcasecmp (value, "always"))
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->icon_always_radio), TRUE);
-  else if (!g_ascii_strcasecmp (value, "client"))
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->icon_client_radio), TRUE);
-  else if (!g_ascii_strcasecmp (value, "never"))
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->icon_never_radio), TRUE);
-
-  g_signal_connect (dialog->icon_always_radio, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_icon_visibility_toggled), dialog);
-  g_signal_connect (dialog->icon_client_radio, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_icon_visibility_toggled), dialog);
-  g_signal_connect (dialog->icon_never_radio, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_icon_visibility_toggled), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_ICON_VISIBILITY, NULL))
+  if (strcmp (setting, "keyring") == 0)
     {
-      gtk_widget_set_sensitive (dialog->icon_always_radio, FALSE);
-      gtk_widget_set_sensitive (dialog->icon_client_radio, FALSE);
-      gtk_widget_set_sensitive (dialog->icon_never_radio, FALSE);
-      gtk_widget_show (dialog->writability_warning);
+      g_value_take_string (value, vino_keyring_get_password ());
+      return TRUE;
     }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_ICON_VISIBILITY,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_icon_visibility_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
-}
-
-static void
-vino_preferences_dialog_use_password_toggled (GtkToggleButton       *toggle,
-					      VinoPreferencesDialog *dialog)
-{
-  GSList *auth_methods = NULL;
-
-  dialog->use_password = gtk_toggle_button_get_active (toggle);
-
-  if (dialog->use_password)
-    auth_methods = g_slist_prepend (auth_methods, "vnc");
   else
-    auth_methods = g_slist_append (auth_methods, "none");
-
-  gconf_client_set_list (dialog->client,
-			 VINO_PREFS_AUTHENTICATION_METHODS,
-			 GCONF_VALUE_STRING,
-			 auth_methods,
-			 NULL);
-
-  g_slist_free (auth_methods);
-
-  gtk_widget_set_sensitive (dialog->password_entry, dialog->use_password);
-}
-
-static void
-vino_preferences_dialog_use_password_notify (GConfClient           *client,
-					     guint                  cnx_id,
-					     GConfEntry            *entry,
-					     VinoPreferencesDialog *dialog)
-{
-  GSList   *auth_methods, *l;
-  gboolean  use_password;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_LIST ||
-      gconf_value_get_list_type (entry->value) != GCONF_VALUE_STRING)
-    return;
-
-  auth_methods = gconf_value_get_list (entry->value);
-
-  use_password = FALSE;
-  for (l = auth_methods; l; l = l->next)
     {
-      GConfValue *value = l->data;
-      const char *method;
+      gchar *decoded;
+      gsize length;
+      gboolean ok;
 
-      method = gconf_value_get_string (value);
+      decoded = (gchar *) g_base64_decode (setting, &length);
 
-      if (!strcmp (method, "vnc"))
-	use_password = TRUE;
-    }
+      if ((ok = g_utf8_validate (decoded, length, NULL)))
+        g_value_take_string (value, g_strndup (decoded, length));
 
-  if (use_password != dialog->use_password)
-    {
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->password_toggle), use_password);
+      return ok;
     }
 }
 
-static gboolean
-vino_preferences_dialog_get_use_password (VinoPreferencesDialog *dialog)
+static GVariant *
+set_password (const GValue       *value,
+              const GVariantType *type,
+              gpointer            user_data)
 {
-  GSList   *auth_methods, *l;
-  gboolean  use_password;
+  const gchar *string;
+  gchar *base64;
 
-  auth_methods = gconf_client_get_list (dialog->client,
-					VINO_PREFS_AUTHENTICATION_METHODS,
-					GCONF_VALUE_STRING,
-					NULL);
-
-  use_password = FALSE;
-  for (l = auth_methods; l; l = l->next)
-    {
-      char *method = l->data;
+  string = g_value_get_string (value);
 
-      if (!strcmp (method, "vnc"))
-	use_password = TRUE;
+  /* first, try to put it in the keyring */
+  if (vino_keyring_set_password (string))
+    return g_variant_new_string ("keyring");
 
-      g_free (method);
-    }
-  g_slist_free (auth_methods);
-
-  return use_password;
+  /* if that failed, store it in GSettings, base64 */
+  base64 = g_base64_encode ((guchar *) string, strlen (string));
+  return g_variant_new_from_data (G_VARIANT_TYPE_STRING,
+                                  base64, strlen (base64) + 1,
+                                  TRUE, g_free, base64);
 }
 
 static void
-vino_preferences_dialog_setup_password_toggle (VinoPreferencesDialog *dialog)
+vino_preferences_dialog_response (GtkWidget *widget,
+                                  gint       response,
+                                  gpointer   user_data)
 {
-  dialog->password_toggle = GTK_WIDGET (gtk_builder_get_object (dialog->builder,
-                                                                "password_toggle"));
-  g_assert (dialog->password_toggle != NULL);
-
-  dialog->use_password = vino_preferences_dialog_get_use_password (dialog);
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->password_toggle), dialog->use_password);
-
-  g_signal_connect (dialog->password_toggle, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_use_password_toggled), dialog);
+  GError *error = NULL;
+  GdkScreen *screen;
 
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_AUTHENTICATION_METHODS, NULL))
+  switch (response)
     {
-      gtk_widget_set_sensitive (dialog->password_toggle, FALSE);
-      gtk_widget_show (dialog->writability_warning);
-    }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_AUTHENTICATION_METHODS,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_use_password_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
-}
+    case GTK_RESPONSE_HELP:
+      screen = gtk_widget_get_screen (widget);
 
-static void
-vino_preferences_vnc_password_notify (GConfClient           *client,
-				      guint                  cnx_id,
-				      GConfEntry            *entry,
-				      VinoPreferencesDialog *dialog)
-{
-  const char *password_b64;
-  guchar     *blob;
-  gsize       blob_len;
-  char       *password;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
-    return;
-
-  password = NULL;
+      if (!gtk_show_uri (screen, "ghelp:user-guide?goscustdesk-90",
+                         GDK_CURRENT_TIME, &error))
+        {
+          GtkWidget *message_dialog;
 
-  password_b64 = gconf_value_get_string (entry->value);
+          message_dialog =
+            gtk_message_dialog_new (GTK_WINDOW (widget),
+                                    GTK_DIALOG_DESTROY_WITH_PARENT,
+                                    GTK_MESSAGE_ERROR,
+                                    GTK_BUTTONS_CLOSE,
+                                    _("There was an error displaying help:\n%s"),
+                                    error->message);
+          gtk_window_set_resizable (GTK_WINDOW (message_dialog), FALSE);
 
-  if (password_b64 && *password_b64)
-    {
-      blob_len = 0;
-      blob = g_base64_decode (password_b64, &blob_len);
-    
-      password = g_strndup ((char *) blob, blob_len);
+          g_signal_connect (message_dialog, "response",
+                            G_CALLBACK (gtk_widget_destroy),
+                            NULL);
 
-      g_free (blob);
-    }
+          gtk_widget_show (message_dialog);
 
-  if (!password || !password [0])
-    {
-      gtk_entry_set_text (GTK_ENTRY (dialog->password_entry), "");
-    }
-  else
-    {
-      const char *old_password;
-
-      old_password = gtk_entry_get_text (GTK_ENTRY (dialog->password_entry));
+          g_error_free (error);
+        }
+      break;
 
-      if (!old_password || (old_password && strcmp (old_password, password)))
-	{
-	  gtk_entry_set_text (GTK_ENTRY (dialog->password_entry), password);
-	}
+    default:
+      gtk_widget_destroy (widget);
     }
-
-  g_free (password);
 }
 
 static void
-vino_preferences_dialog_password_changed (GtkEntry              *entry,
-					  VinoPreferencesDialog *dialog)
+vino_preferences_update_message (VinoPreferences *app)
 {
-  const char *password;
+  gchar *internal_host, *external_host, *avahi_host;
+  guint16 internal_port, external_port;
 
-  password = gtk_entry_get_text (entry);
-
-  if (vino_preferences_dialog_set_password_in_keyring (dialog, password))
-    return;
-
-  if (!password || !password [0])
+  if (!vino_connectivity_info_get (app->info,
+                                   &internal_host, &internal_port,
+                                   &external_host, &external_port,
+                                   &avahi_host))
     {
-      gconf_client_unset (dialog->client, VINO_PREFS_VNC_PASSWORD, NULL);
-    }
-  else
-    {
-      char *password_b64;
-
-      password_b64 = g_base64_encode ((guchar *) password, strlen (password));
-
-      gconf_client_set_string (dialog->client, VINO_PREFS_VNC_PASSWORD, password_b64, NULL);
+      vino_message_box_set_label (app->message_box,
+                                  _("Checking the connectivity of this machine..."));
+      vino_message_box_show_image (app->message_box);
 
-      g_free (password_b64);
+      return;
     }
-}
-
-static void
-vino_preferences_dialog_setup_password_entry (VinoPreferencesDialog *dialog)
-{
-  char     *password;
-  gboolean  password_in_keyring;
-
-  dialog->password_entry = GTK_WIDGET (gtk_builder_get_object (dialog->builder,
-                                                               "password_entry"));
-  g_assert (dialog->password_entry != NULL);
-  
-  password_in_keyring = TRUE;
 
-  if (!(password = vino_preferences_dialog_get_password_from_keyring (dialog)))
+  if (external_host || internal_host)
     {
-      guchar *blob;
-      gsize   blob_len;
-      char   *password_b64;
+      const gchar *host;
+      GString *message;
+      guint16 port;
+      GString *url;
 
-      password_b64 = gconf_client_get_string (dialog->client, VINO_PREFS_VNC_PASSWORD, NULL);
+      message = g_string_new (NULL);
+      url = g_string_new (NULL);
+      host = external_host;
+      port = external_port;
 
-      if (password_b64 && *password_b64)
+      if (host == NULL)
         {
-           blob_len = 0;
-           blob = g_base64_decode (password_b64, &blob_len);
+          g_string_append (message, _("Your desktop is only reachable over "
+                                      "the local network."));
+          g_string_append_c (message, ' ');
 
-           password = g_strndup ((char *) blob, blob_len);
-        
-           g_free (blob);
-           g_free (password_b64);
+          host = internal_host;
+          port = internal_port;
         }
 
-      password_in_keyring = FALSE;
-    }
-
-  if (password)
-    {
-      gtk_entry_set_text (GTK_ENTRY (dialog->password_entry), password);
-    }
-
-  g_free (password);
+      g_string_append_printf (message, "<a href=\"vnc://%s::%d\">%s</a>",
+                              host, (guint) port, host);
 
-  g_signal_connect (dialog->password_entry, "changed",
-		    G_CALLBACK (vino_preferences_dialog_password_changed), dialog);
-
-  gtk_widget_set_sensitive (dialog->password_entry, dialog->use_password);
-
-  if (!password_in_keyring)
-    {
-      if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_VNC_PASSWORD, NULL))
+      if (avahi_host)
         {
-          gtk_widget_set_sensitive (dialog->password_entry, FALSE);
-          gtk_widget_show (dialog->writability_warning);
+          g_string_append (url, _(" or "));
+          g_string_append_printf (url, "<a href=\"vnc://%s::%d\">%s</a>",
+                                  avahi_host, internal_port, avahi_host);
         }
 
-      dialog->listeners [dialog->n_listeners] = 
-        gconf_client_notify_add (dialog->client,
-                                 VINO_PREFS_VNC_PASSWORD,
-                                 (GConfClientNotifyFunc) vino_preferences_vnc_password_notify,
-                                 dialog, NULL, NULL);
-      dialog->n_listeners++;
-    }
-  else
-    {
-      dialog->expected_listeners--;
-    }
-}
-
-static void
-vino_preferences_dialog_use_upnp_toggled (GtkToggleButton       *toggle,
-					  VinoPreferencesDialog *dialog)
-{
-  gconf_client_set_bool (dialog->client,
-			 VINO_PREFS_USE_UPNP,
-			 gtk_toggle_button_get_active (toggle),
-			 NULL);
-
-  g_timeout_add_seconds (1, (GSourceFunc) delay_update_message, dialog);
-}
-
-static void
-vino_preferences_dialog_use_upnp_notify (GConfClient           *client,
-					 guint                  cnx_id,
-					 GConfEntry            *entry,
-					 VinoPreferencesDialog *dialog)
-{
-  gboolean use_upnp;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-    return;
-
-  use_upnp = gconf_value_get_bool (entry->value) != FALSE;
-
-  if (use_upnp != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->use_upnp_toggle)))
-    {
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->use_upnp_toggle), use_upnp);
-    }
-}
-
-static void
-vino_preferences_dialog_setup_use_upnp_toggle (VinoPreferencesDialog *dialog)
-{
-  gboolean use_upnp;
-
-  dialog->use_upnp_toggle = GTK_WIDGET (gtk_builder_get_object (dialog->builder,
-                                                                "use_upnp_toggle"));
-  g_assert (dialog->use_upnp_toggle != NULL);
-
-  use_upnp = gconf_client_get_bool (dialog->client, VINO_PREFS_USE_UPNP, NULL);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->use_upnp_toggle), use_upnp);
-
-  g_signal_connect (dialog->use_upnp_toggle, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_use_upnp_toggled), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_USE_UPNP, NULL))
-    {
-      gtk_widget_set_sensitive (dialog->use_upnp_toggle, FALSE);
-      gtk_widget_show (dialog->writability_warning);
-    }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_USE_UPNP,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_use_upnp_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
-}
-
-static void
-vino_preferences_dialog_response (GtkWidget             *widget,
-				  int                    response,
-				  VinoPreferencesDialog *dialog)
-{
-  GError    *error;
-  GdkScreen *screen;
-
-  if (response != GTK_RESPONSE_HELP)
-    {
-      if (dialog->session)
-        soup_session_abort (dialog->session);
-      gtk_widget_destroy (widget);
-      return;
-    }
-
-  screen = gtk_widget_get_screen (widget);
-  error = NULL;
-
-  gtk_show_uri (screen, "ghelp:user-guide?goscustdesk-90", GDK_CURRENT_TIME, &error);
-  if (error)
-    {
-      GtkWidget *message_dialog;
-
-      message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog->dialog),
-					       GTK_DIALOG_DESTROY_WITH_PARENT,
-					       GTK_MESSAGE_ERROR,
-					       GTK_BUTTONS_CLOSE,
-					       _("There was an error displaying help:\n%s"),
-					       error->message);
-      gtk_window_set_resizable (GTK_WINDOW (message_dialog), FALSE);
-
-      g_signal_connect (message_dialog, "response",
-			G_CALLBACK (gtk_widget_destroy),
-			NULL);
-
-      gtk_widget_show (message_dialog);
-
-      g_error_free (error);
-    }
-}
-
-static void
-vino_preferences_dialog_destroyed (GtkWidget             *widget,
-				   VinoPreferencesDialog *dialog)
-{
-  dialog->dialog = NULL;
-
-  gtk_main_quit ();
-}
-
-static void
-error_message (VinoPreferencesDialog *dialog)
-{
-  gchar   *host, *avahi_host;
-  GString *message, *url;
-
-  url = g_string_new (NULL);
-  message = g_string_new (_("Your desktop is only reachable over the local network."));
-
-  if (!dbus_g_proxy_call (dialog->proxy,
-                          "GetInternalData",
-                          NULL,
-                          G_TYPE_INVALID,
-                          G_TYPE_STRING, &host,
-                          G_TYPE_STRING, &avahi_host,
-                          G_TYPE_INT, &dialog->port,
-                          G_TYPE_INVALID))
-    {
-      dialog->port = 5900;
-      host = g_strdup ("localhost");
-      avahi_host = NULL;
-    }
-
-  g_string_append_printf (url, "<a href=\"vnc://%s::%d\">%s</a>", host, dialog->port, host);
-
-  if (avahi_host && avahi_host[0])
-    {
-      g_string_append (url, _(" or "));
-      g_string_append_printf (url, "<a href=\"vnc://%s::%d\">%s</a>", avahi_host, dialog->port, avahi_host);
-    }
-
-  g_string_append_c (message, ' ');
-  g_string_append_printf (message, _("Others can access your computer using the address %s."), url->str);
-  vino_message_box_hide_image (VINO_MESSAGE_BOX (dialog->message));
-  vino_message_box_set_label (VINO_MESSAGE_BOX (dialog->message), message->str);
+      g_string_append_printf (message, _("Others can access your computer "
+                                         "using the address %s."), url->str);
 
-  g_string_free (message, TRUE);
-  g_string_free (url, TRUE);
-  g_free (host);
-  g_free (avahi_host);
-}
-
-static void
-got_status (SoupSession *session, SoupMessage *msg, VinoPreferencesDialog *dialog)
-{
-  gboolean       status;
-  GError         *error;
-  GHashTable     *hash;
-  GHashTableIter iter;
-  gpointer       key, value;
-  gchar          *ip;
-
-  error = NULL;
-  ip = NULL;
-  status = FALSE;
-
-  if (soup_xmlrpc_extract_method_response (msg->response_body->data,
-					   msg->response_body->length,
-					   &error,
-					   G_TYPE_HASH_TABLE, &hash,
-					   G_TYPE_INVALID))
-    {
-      g_hash_table_iter_init (&iter, hash);
-      while (g_hash_table_iter_next (&iter, &key, &value))
-	{
-	  if (!strcmp (key, "status"))
-	    {
-	      status = g_value_get_boolean (value);
-	      continue;
-	    }
-	  if (!strcmp (key, "ip"))
-	    {
-	      ip = g_strdup (g_value_get_string (value));
-	      continue;
-	    }
-	}
-      g_hash_table_destroy (hash);
-
-      if (status)
-	{
-	  gchar   *avahi_host, *host, *message;
-	  gint     port;
-	  GString *url;
-
-	  if (!dbus_g_proxy_call (dialog->proxy,
-                             "GetInternalData",
-                             NULL,
-                             G_TYPE_INVALID,
-                             G_TYPE_STRING, &host,
-                             G_TYPE_STRING, &avahi_host,
-                             G_TYPE_INT, &port,
-                             G_TYPE_INVALID))
-	    {
-	      host = NULL;
-	      avahi_host = NULL;
-	    }
-
-	  url = g_string_new (NULL);
-	  g_string_append_printf (url, "<a href=\"vnc://%s::%d\">%s</a>", ip, dialog->port, ip);
-
-	  if (avahi_host && avahi_host[0])
-	    {
-	      g_string_append (url, _(" or "));
-	      g_string_append_printf (url, "<a href=\"vnc://%s::%d\">%s</a>", avahi_host, port, avahi_host);
-	    }
-
-	  message = g_strdup_printf (_("Others can access your computer using the address %s."), url->str);
-	  vino_message_box_hide_image (VINO_MESSAGE_BOX (dialog->message));
-	  vino_message_box_set_label (VINO_MESSAGE_BOX (dialog->message), message);
-
-	  g_free (message);
-	  g_string_free (url, TRUE);
-	  g_free (host);
-	  g_free (avahi_host);
-	}
-      else
-	error_message (dialog);
-
-      g_free (ip);
+      vino_message_box_set_label (app->message_box, message->str);
+      g_string_free (message, TRUE);
+      g_string_free (url, TRUE);
     }
   else
-    {
-      if (error)
-	{
-	  g_warning ("%s", error->message);
-	  g_error_free (error);
-	}
-      error_message (dialog);
-    }
-
-  dialog->retrieving_info = FALSE;
-}
+    vino_message_box_set_label (app->message_box,
+                                _("Nobody can access your desktop."));
 
-static gboolean
-request_timeout_cb (VinoPreferencesDialog *dialog)
-{
-  if (!dialog->retrieving_info)
-    return FALSE;
+  vino_message_box_hide_image (app->message_box);
 
-  soup_session_cancel_message (dialog->session, dialog->msg, 408);
-  return FALSE;
-}
-
-#define TIMEOUT 6
-static void
-vino_preferences_dialog_update_message_box (VinoPreferencesDialog *dialog)
-{
-  gboolean allowed;
-  gchar *url;
-
-  if (dialog->retrieving_info)
-    return;
-  dialog->retrieving_info = TRUE;
-
-  allowed = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->allowed_toggle));
-  if (!allowed)
-    {
-      vino_message_box_hide_image (VINO_MESSAGE_BOX (dialog->message));
-      vino_message_box_set_label (VINO_MESSAGE_BOX (dialog->message),
-				  _("Nobody can access your desktop."));
-      dialog->retrieving_info = FALSE;
-      return;
-    }
-
-  url = vino_url_webservice_get_random ();
-  if (!url)
-    {
-      error_message (dialog);
-      return;
-    }
-
-  vino_message_box_show_image (VINO_MESSAGE_BOX (dialog->message));
-  vino_message_box_set_label (VINO_MESSAGE_BOX (dialog->message),
-			      _("Checking the connectivity of this machine..."));
-
-  dbus_g_proxy_call (dialog->proxy,
-                     "GetExternalPort",
-                     NULL,
-                     G_TYPE_INVALID,
-                     G_TYPE_INT, &dialog->port,
-                     G_TYPE_INVALID);
-
-  if (!dialog->session)
-    dialog->session = soup_session_async_new ();
-
-  dialog->msg = soup_xmlrpc_request_new (url,
-					 "vino.check",
-					 G_TYPE_INT, dialog->port,
-					 G_TYPE_INT, TIMEOUT,
-					 G_TYPE_INVALID);
-  soup_session_queue_message (dialog->session,
-			      dialog->msg,
-			      (SoupSessionCallback)got_status,
-			      dialog);
-
-  g_timeout_add_seconds (TIMEOUT+1,
-			 (GSourceFunc) request_timeout_cb,
-			 dialog);
-  g_free (url);
+  g_free (internal_host);
+  g_free (external_host);
+  g_free (avahi_host);
 }
 
 static void
-vino_preferences_dialog_setup_message_box (VinoPreferencesDialog *dialog)
+vino_preferences_finalize (GObject *object)
 {
-  GtkWidget *event_box;
-
-  event_box = GTK_WIDGET (gtk_builder_get_object (dialog->builder, "event_box"));
-  g_assert (event_box != NULL);
+  VinoPreferences *app = (VinoPreferences *) object;
 
-  dialog->message = vino_message_box_new ();
-  gtk_container_add (GTK_CONTAINER (event_box), dialog->message);
-  gtk_widget_show (dialog->message);
+  g_object_unref (app->info);
 
-  vino_preferences_dialog_update_message_box (dialog);
+  G_OBJECT_CLASS (vino_preferences_parent_class)
+    ->finalize (object);
 }
 
-static void
-handle_server_info_message (DBusGProxy *proxy, VinoPreferencesDialog *dialog)
-{
-  vino_preferences_dialog_update_message_box (dialog);
-}
 
-static void
-vino_preferences_start_listening (VinoPreferencesDialog *dialog)
+static GtkWindow *
+vino_preferences_create_window (GtkApplication *gtk_app)
 {
-  gchar       *obj_path;
-  GdkScreen   *screen;
-
-  screen = gtk_window_get_screen (GTK_WINDOW (dialog->dialog));
-  obj_path = g_strdup_printf ("/org/gnome/vino/screens/%d",
-                              gdk_screen_get_number (screen));
-  dialog->proxy = dbus_g_proxy_new_for_name (dialog->connection,
-					     VINO_DBUS_BUS_NAME,
-					     obj_path,
-					     VINO_DBUS_INTERFACE);
-
-  g_free (obj_path);
-  dbus_g_proxy_add_signal (dialog->proxy, "ServerInfoChanged", G_TYPE_INVALID);
-  dbus_g_proxy_connect_signal (dialog->proxy,
-                               "ServerInfoChanged",
-                               G_CALLBACK (handle_server_info_message),
-                               dialog,
-                               NULL);
-}
-
-static gboolean
-vino_preferences_dialog_init (VinoPreferencesDialog *dialog)
-{
-#define VINO_UI_FILE "vino-preferences.ui"
-
-  const char *ui_file;
-  gboolean    allowed;
+  VinoPreferences *app = (VinoPreferences *) gtk_app;
   GError     *error = NULL;
+  GSettings  *settings;
+  GtkBuilder *builder;
+  const char *ui_file;
+  gpointer    window;
 
-  dialog->expected_listeners = N_LISTENERS;
-
+#define VINO_UI_FILE "vino-preferences.ui"
   if (g_file_test (VINO_UI_FILE, G_FILE_TEST_EXISTS))
     ui_file = VINO_UI_FILE;
   else
     ui_file = VINO_UIDIR "/" VINO_UI_FILE;
+#undef VINO_UI_FILE
 
-  dialog->builder = gtk_builder_new ();
-  if (!gtk_builder_add_from_file (dialog->builder, ui_file, &error))
+  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_error_free (error);
       return FALSE;
     }
 
-  dialog->dialog = GTK_WIDGET (gtk_builder_get_object (dialog->builder, "vino_dialog"));
-  g_assert (dialog->dialog != NULL);
+  settings = g_settings_new ("org.gnome.Vino");
 
-  g_signal_connect (dialog->dialog, "response",
-		    G_CALLBACK (vino_preferences_dialog_response), dialog);
-  g_signal_connect (dialog->dialog, "destroy",
-		    G_CALLBACK (vino_preferences_dialog_destroyed), dialog);
-  g_signal_connect (dialog->dialog, "delete_event", G_CALLBACK (gtk_true), NULL);
+  g_settings_bind (settings, "enabled",
+                   gtk_builder_get_object (builder, "control_settings"),
+                   "sensitive", G_SETTINGS_BIND_GET);
 
-  dialog->client = gconf_client_get_default ();
-  gconf_client_add_dir (dialog->client, VINO_PREFS_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+  g_settings_bind (settings, "enabled",
+                   gtk_builder_get_object (builder, "security_settings"),
+                   "sensitive", G_SETTINGS_BIND_GET);
 
-  dialog->writability_warning = GTK_WIDGET (gtk_builder_get_object (dialog->builder,
-                                                                    "writability_warning"));
-  g_assert (dialog->writability_warning != NULL);
-  gtk_widget_hide (dialog->writability_warning);
+  g_settings_bind (settings, "enabled",
+                   gtk_builder_get_object (builder, "notification_settings"),
+                   "sensitive", G_SETTINGS_BIND_GET);
 
-  allowed = vino_preferences_dialog_setup_allowed_toggle (dialog);
+  g_settings_bind (settings, "enabled",
+                   gtk_builder_get_object (builder, "allowed_toggle"),
+                   "active", 0);
 
-  vino_preferences_dialog_setup_view_only_toggle            (dialog);
-  vino_preferences_dialog_setup_prompt_enabled_toggle       (dialog);
-  vino_preferences_dialog_setup_password_toggle             (dialog);
-  vino_preferences_dialog_setup_password_entry              (dialog);
-  vino_preferences_dialog_setup_use_upnp_toggle             (dialog);
-  vino_preferences_dialog_setup_icon_visibility             (dialog);
+  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_assert (dialog->n_listeners == dialog->expected_listeners);
+  g_settings_bind_with_mapping (settings, "vnc-password",
+                                gtk_builder_get_object (builder,
+                                                        "password_entry"),
+                                "text", 0,
+                                get_password, set_password, NULL, NULL);
 
-  vino_preferences_dialog_update_for_allowed (dialog, allowed);
+  window = gtk_builder_get_object (builder, "vino_dialog");
+  g_signal_connect (window, "response",
+                    G_CALLBACK (vino_preferences_dialog_response), NULL);
 
-  error = NULL;
-  dialog->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-  if (!dialog->connection)
-    {
-      g_printerr (_("Failed to open connection to bus: %s\n"),
-                  error->message);
-      g_error_free (error);
-      return FALSE;
-    }
-  vino_preferences_start_listening (dialog);
-
-  vino_preferences_dialog_setup_message_box (dialog);
 
-  gtk_widget_show (dialog->dialog);
+  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);
 
-#ifdef VINO_ENABLE_LIBUNIQUE
-  unique_app_watch_window (dialog->app, GTK_WINDOW (dialog->dialog));
-#endif
-
-  return TRUE;
+  g_object_unref (builder);
 
-#undef VINO_UI_FILE  
+  return window;
 }
 
 static void
-vino_preferences_dialog_finalize (VinoPreferencesDialog *dialog)
+vino_preferences_init (VinoPreferences *app)
 {
-  if (dialog->dialog)
-    gtk_widget_destroy (dialog->dialog);
-  dialog->dialog = NULL;
-
-  if (dialog->client)
-    {
-      int i;
-
-      for (i = 0; i < dialog->n_listeners; i++)
-	{
-	  if (dialog->listeners [i])
-	    gconf_client_notify_remove (dialog->client, dialog->listeners [i]);
-	  dialog->listeners [i] = 0;
-	}
-      dialog->n_listeners = 0;
-
-      gconf_client_remove_dir (dialog->client, VINO_PREFS_DIR, NULL);
-
-      g_object_unref (dialog->client);
-      dialog->client = NULL;
-    }
-
-  if (dialog->builder)
-    g_object_unref (dialog->builder);
-  dialog->builder = NULL;
-
-#ifdef VINO_ENABLE_LIBUNIQUE
-  if (dialog->app)
-    g_object_unref (dialog->app);
-  dialog->app = NULL;
-#endif
-
-  if (dialog->session)
-    g_object_unref (dialog->session);
-  dialog->session = NULL;
+}
 
-  if (dialog->proxy)
-    g_object_unref (dialog->proxy);
-  dialog->proxy = NULL;
+static void
+vino_preferences_class_init (GtkApplicationClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
 
-  if (dialog->connection)
-    dbus_g_connection_unref (dialog->connection);
-  dialog->connection = NULL;
+  class->create_window = vino_preferences_create_window;
+  object_class->finalize = vino_preferences_finalize;
 }
 
-static gboolean
-vino_preferences_is_running (VinoPreferencesDialog *dialog)
+static GtkApplication *
+vino_preferences_new (void)
 {
-#ifdef VINO_ENABLE_LIBUNIQUE
-  dialog->app = unique_app_new ("org.gnome.Vino.Preferences", NULL);
+  GError *error = NULL;
+  GtkApplication *app;
 
-  if (unique_app_is_running (dialog->app))
-    {
-      UniqueResponse response;
-
-      response = unique_app_send_message (dialog->app, UNIQUE_ACTIVATE, NULL);
-        
-      g_object_unref (dialog->app);
-      dialog->app = NULL;
-       
-      return response == UNIQUE_RESPONSE_OK;
-    }
-  else
-    return FALSE;
-#else
-  return FALSE;
-#endif
+  app = g_initable_new (vino_preferences_get_type (), NULL, &error,
+                        "application-id", "org.gnome.Vino.Preferences",
+                        NULL);
+
+  if G_UNLIKELY (app == NULL)
+    g_error ("%s", error->message);
+
+  return app;
 }
 
 int
 main (int argc, char **argv)
 {
-  VinoPreferencesDialog dialog = { NULL, };
+  GtkApplication *app;
 
   bindtextdomain (GETTEXT_PACKAGE, VINO_LOCALEDIR);
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
   textdomain (GETTEXT_PACKAGE);
 
   gtk_init (&argc, &argv);
-
-  if (vino_preferences_is_running (&dialog))
-    return 0;
-  
-  if (!vino_preferences_dialog_init (&dialog))
-    {
-      vino_preferences_dialog_finalize (&dialog);
-      return 1;
-    }
-
-  gtk_main ();
-
-  vino_preferences_dialog_finalize (&dialog);
+  app = vino_preferences_new ();
+  gtk_application_get_window (app);
+  gtk_application_run (app);
+  g_object_unref (app);
 
   return 0;
 }
diff --git a/capplet/vino-preferences.ui b/capplet/vino-preferences.ui
index c9f4ca1..a16b56b 100644
--- a/capplet/vino-preferences.ui
+++ b/capplet/vino-preferences.ui
@@ -3,6 +3,7 @@
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkDialog" id="vino_dialog">
+    <property name="visible">True</property>
     <property name="border_width">5</property>
     <property name="title" translatable="yes">Remote Desktop Preferences</property>
     <property name="resizable">False</property>
@@ -102,7 +103,7 @@
                         <property name="can_focus">True</property>
                         <property name="receives_default">False</property>
                         <property name="has_tooltip">True</property>
-                        <property name="tooltip-text" translatable="yes">Your desktop will be shared</property>
+                        <property name="tooltip_text" translatable="yes">Your desktop will be shared</property>
                         <property name="use_underline">True</property>
                         <property name="draw_indicator">True</property>
                       </object>
@@ -116,7 +117,7 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkHBox" id="hbox2">
+                  <object class="GtkHBox" id="control_settings">
                     <property name="visible">True</property>
                     <child>
                       <object class="GtkLabel" id="label3">
@@ -136,7 +137,7 @@
                         <property name="can_focus">True</property>
                         <property name="receives_default">False</property>
                         <property name="has_tooltip">True</property>
-                        <property name="tooltip-text" translatable="yes">Remote users are able to control your mouse and keyboard</property>
+                        <property name="tooltip_text" translatable="yes">Remote users are able to control your mouse and keyboard</property>
                         <property name="use_underline">True</property>
                         <property name="draw_indicator">True</property>
                       </object>
@@ -205,15 +206,76 @@
                   <object class="GtkHBox" id="hbox3">
                     <property name="visible">True</property>
                     <child>
-                      <object class="GtkCheckButton" id="prompt_enabled_toggle">
-                        <property name="label" translatable="yes">_You must confirm each access to this machine</property>
+                      <object class="GtkVBox" id="security_settings">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="has_tooltip">True</property>
-                        <property name="tooltip-text" translatable="yes">You will be queried to allow or to refuse every incoming connection</property>
-                        <property name="use_underline">True</property>
-                        <property name="draw_indicator">True</property>
+                        <child>
+                          <object class="GtkCheckButton" id="prompt_enabled_toggle">
+                            <property name="label" translatable="yes">_You must confirm each access to this machine</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="use_underline">True</property>
+                            <property name="draw_indicator">True</property>
+                          </object>
+                          <packing>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkHBox" id="hbox4">
+                            <property name="visible">True</property>
+                            <child>
+                              <object class="GtkCheckButton" id="password_toggle">
+                                <property name="label" translatable="yes">_Require the user to enter this password:</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkHBox" id="password_box">
+                                <property name="visible">True</property>
+                                <child>
+                                  <object class="GtkEntry" id="password_entry">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="max_length">8</property>
+                                    <property name="visibility">False</property>
+                                    <property name="invisible_char">&#x25CF;</property>
+                                  </object>
+                                  <packing>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkCheckButton" id="use_upnp_toggle">
+                            <property name="label" translatable="yes">_Configure network automatically to accept connections</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="use_underline">True</property>
+                            <property name="draw_indicator">True</property>
+                          </object>
+                          <packing>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
                       </object>
                       <packing>
                         <property name="padding">12</property>
@@ -225,66 +287,6 @@
                     <property name="position">1</property>
                   </packing>
                 </child>
-                <child>
-                  <object class="GtkHBox" id="hbox4">
-                    <property name="visible">True</property>
-                    <child>
-                      <object class="GtkCheckButton" id="password_toggle">
-                        <property name="label" translatable="yes">_Require the user to enter this password:</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="draw_indicator">True</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="padding">12</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="password_entry">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="has_tooltip">True</property>
-                        <property name="tooltip-text" translatable="yes">Maximum size: 8 characters</property>
-                        <property name="max_length">8</property>
-                        <property name="visibility">False</property>
-                      </object>
-                      <packing>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkHBox" id="hbox7">
-                    <property name="visible">True</property>
-                    <child>
-                      <object class="GtkCheckButton" id="use_upnp_toggle">
-                        <property name="label" translatable="yes">_Configure network automatically to accept connections</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="has_tooltip">True</property>
-                        <property name="tooltip-text" translatable="yes">The router must have the UPnP feature enabled</property>
-                        <property name="use_underline">True</property>
-                        <property name="draw_indicator">True</property>
-                      </object>
-                      <packing>
-                        <property name="padding">12</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="position">3</property>
-                  </packing>
-                </child>
               </object>
               <packing>
                 <property name="position">1</property>
@@ -311,7 +313,7 @@
                   <object class="GtkHBox" id="hbox8">
                     <property name="visible">True</property>
                     <child>
-                      <object class="GtkVBox" id="vbox2">
+                      <object class="GtkVBox" id="notification_settings">
                         <property name="visible">True</property>
                         <property name="spacing">3</property>
                         <child>
@@ -391,6 +393,8 @@
                 <property name="use_stock">True</property>
               </object>
               <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
                 <property name="position">0</property>
               </packing>
             </child>
@@ -403,6 +407,8 @@
                 <property name="use_stock">True</property>
               </object>
               <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
                 <property name="position">1</property>
               </packing>
             </child>
diff --git a/common/.gitignore b/common/.gitignore
new file mode 100644
index 0000000..a7d9de3
--- /dev/null
+++ b/common/.gitignore
@@ -0,0 +1 @@
+*.valid
diff --git a/common/Makefile.am b/common/Makefile.am
new file mode 100644
index 0000000..0a272c1
--- /dev/null
+++ b/common/Makefile.am
@@ -0,0 +1,10 @@
+EXTRA_DIST = \
+	org.gnome.Vino.gschema.xml	\
+	vino-dbus.h			\
+	vino-dbus.c			\
+	vino-keyring.h			\
+	vino-keyring.c
+
+gsettings_SCHEMAS = org.gnome.Vino.gschema.xml
+
+ GSETTINGS_RULES@
diff --git a/common/org.gnome.Vino.gschema.xml b/common/org.gnome.Vino.gschema.xml
new file mode 100644
index 0000000..da1888c
--- /dev/null
+++ b/common/org.gnome.Vino.gschema.xml
@@ -0,0 +1,171 @@
+<schemalist>
+  <schema id='org.gnome.Vino' path='/desktop/gnome/remote-access/'>
+    <key name='enabled' type='b'>
+      <summary>Enable remote desktop access</summary>
+      <description>
+        If true, allows remote access to the desktop via the RFB
+        protocol. Users on remote machines may then connect to the
+        desktop using a vncviewer.  </description>
+      <default>false</default>
+    </key>
+
+    <key name='prompt-enabled' type='b'>
+      <summary>Prompt the user before completing a connection</summary>
+      <description>
+        If true, remote users accessing the desktop are not allowed
+        access until the user on the host machine approves the
+        connection.  Recommended especially when access is not password
+        protected.
+      </description>
+      <default>true</default>
+    </key>
+
+    <key name='view-only' type='b'>
+      <summary>Only allow remote users to view the desktop</summary>
+      <description>
+        If true, remote users accessing the desktop are only allowed to
+        view the desktop. Remote users will not be able to use the mouse
+        or keyboard.
+      </description>
+      <default>false</default>
+    </key>
+
+    <key name='network-interface' type='s'>
+      <summary>Network interface for listening</summary>
+      <description>
+        If not set, the server will listen on all network interfaces.
+
+        Set this if you want that accept connections only from some
+        specific network interface. eg: eth0, wifi0, lo, ...
+      </description>
+      <default>''</default>
+    </key>
+
+    <key name='use-alternative-port' type='b'>
+      <summary>Listen an alternative port</summary>
+      <description>
+        If true, the server will listen to another port, instead of the
+        default (5900). The port must be specified in the
+        'alternative-port' key.
+      </description>
+      <default>false</default>
+    </key>
+
+    <key name='alternative-port' type='q'>
+      <summary>Alternative port number</summary>
+      <description>
+        The port which the server will listen to if the
+        'use-alternative-port' key is set to true.  Valid values are in
+        the range from 5000 to 50000.
+      </description>
+      <default>5900</default>
+    </key>
+
+    <key name='require-encryption' type='b'>
+      <summary>Require encryption</summary>
+      <description>
+        If true, remote users accessing the desktop are required to
+        support encryption. It is highly recommended that you use a
+        client which supports encryption unless the intervening network
+        is trusted.
+      </description>
+      <default>false</default>
+    </key>
+
+    <key name='authentication-methods' type='as'>
+      <summary>Allowed authentication methods</summary>
+      <description>
+        Lists the authentication methods with which remote users may
+        access the desktop.
+
+        There are two possible authentication methods; "vnc" causes the
+        remote user to be prompted for a password (the password is
+        specified by the vnc-password key) before connecting and "none"
+        which allows any remote user to connect.
+      </description>
+      <choices>
+        <choice value='none'/>
+        <choice value='vnc'/>
+      </choices>
+      <default>['none']</default>
+    </key>
+
+    <key name='vnc-password' type='s'>
+      <summary>Password required for "vnc" authentication</summary>
+      <description>
+        The password which the remote user will be prompted for if the
+        "vnc" authentication method is used. The password specified by
+        the key is base64 encoded.
+
+        The special value of 'keyring' (which is not valid base64) means
+        that the password is stored in the GNOME keyring.
+      </description>
+      <default>'keyring'</default>
+    </key>
+
+    <key name='mailto' type='s'>
+      <summary>E-mail address to which the remote desktop URL should be sent</summary>
+      <description>
+        This key specifies the e-mail address to which the remote
+        desktop URL should be sent if the user clicks on the URL in the
+        Remote Desktop preferences dialog.
+      </description>
+      <default>''</default>
+    </key>
+
+    <key name='lock-screen-on-disconnect' type='b'>
+      <summary>Lock the screen when last user disconnect</summary>
+      <description>
+        If true, screen will be locked after the last remote client
+        disconnect.
+      </description>
+      <default>false</default>
+    </key>
+
+    <key name='icon-visibility' type='s'>
+      <summary>When the status icon should be shown</summary>
+      <description>
+        This key controls the behavior of the status icon. There are
+        three options: "always" - The icon will be always there;
+        "client" - You will see the icon only when there is someone
+        connected, this is the default behavior; "never" - Never shows
+        the icon.
+      </description>
+      <choices>
+        <choice value='never'/>
+        <choice value='always'/>
+        <choice value='client'/>
+      </choices>
+      <default>'client'</default>
+    </key>
+
+    <key name='disable-background' type='b'>
+      <summary>When true, disable the background on receive valid session</summary>
+      <description>
+        When true, disable the background on receive valid session
+      </description>
+      <default>false</default>
+    </key>
+
+    <key name='use-upnp' type='b'>
+      <summary>Whether we should use UPNP to forward the port in routers</summary>
+      <description>
+        If true, we will use UPNP protocol to automatically forward the
+        port used by vino in the router.
+      </description>
+      <default>false</default>
+    </key>
+
+    <key name='disable-xdamage' type='b'>
+      <summary>Whether we should disable the XDamage extension of X.org</summary>
+      <description>
+        If true, we will not use the XDamage extension of X.org. This
+        extension does not work properly on some video drivers when
+        using 3D effects.  Disabling it will make vino work on these
+        environments with a slower rendering as side effect.
+      </description>
+      <default>false</default>
+    </key>
+  </schema>
+</schemalist>
+
diff --git a/common/vino-dbus.c b/common/vino-dbus.c
new file mode 100644
index 0000000..c06275e
--- /dev/null
+++ b/common/vino-dbus.c
@@ -0,0 +1,90 @@
+/*
+ * 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
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#include "vino-dbus.h"
+
+static const GDBusArgInfo org_gnome_VinoScreen_ShareWithTube_connection = {
+  -1, "connection", "o", NULL
+};
+
+static const GDBusArgInfo org_gnome_VinoScreen_ShareWithTube_tube = {
+  -1, "tube", "o", NULL
+};
+
+static const GDBusArgInfo org_gnome_VinoScreen_ShareWithTube_properties = {
+  -1, "properties", "a{sv}", NULL
+};
+
+static const GDBusArgInfo* const org_gnome_VinoScreen_ShareWithTube_args[] = {
+  &org_gnome_VinoScreen_ShareWithTube_connection,
+  &org_gnome_VinoScreen_ShareWithTube_tube,
+  &org_gnome_VinoScreen_ShareWithTube_properties,
+  NULL
+};
+
+static const GDBusMethodInfo org_gnome_VinoScreen_ShareWithTube = {
+  -1, "ShareWithTube",
+  (GDBusArgInfo **) &org_gnome_VinoScreen_ShareWithTube_args
+};
+
+static const GDBusPropertyInfo org_gnome_VinoScreen_ExternalHost = {
+  -1, "ExternalHost", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE
+};
+
+static const GDBusPropertyInfo org_gnome_VinoScreen_ExternalPort = {
+  -1, "ExternalPort", "q", G_DBUS_PROPERTY_INFO_FLAGS_READABLE
+};
+
+static const GDBusPropertyInfo org_gnome_VinoScreen_Host = {
+  -1, "Host", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE
+};
+
+static const GDBusPropertyInfo org_gnome_VinoScreen_Port = {
+  -1, "Port", "q", G_DBUS_PROPERTY_INFO_FLAGS_READABLE
+};
+
+static const GDBusPropertyInfo org_gnome_VinoScreen_AvahiHost = {
+  -1, "AvahiHost", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE
+};
+
+
+static const GDBusPropertyInfo* const org_gnome_VinoScreen_properties[] = {
+  &org_gnome_VinoScreen_ExternalHost,
+  &org_gnome_VinoScreen_ExternalPort,
+  &org_gnome_VinoScreen_AvahiHost,
+  &org_gnome_VinoScreen_Host,
+  &org_gnome_VinoScreen_Port,
+  NULL
+};
+
+static const GDBusMethodInfo* const org_gnome_VinoScreen_methods[] = {
+  &org_gnome_VinoScreen_ShareWithTube,
+  NULL
+};
+
+const GDBusInterfaceInfo org_gnome_VinoScreen_interface = {
+  -1,
+  "org.gnome.VinoScreen",
+  (GDBusMethodInfo **)     org_gnome_VinoScreen_methods,
+  (GDBusSignalInfo **)     NULL,
+  (GDBusPropertyInfo **)   org_gnome_VinoScreen_properties,
+  (GDBusAnnotationInfo **) NULL
+};
diff --git a/common/vino-dbus.h b/common/vino-dbus.h
new file mode 100644
index 0000000..f6e3efc
--- /dev/null
+++ b/common/vino-dbus.h
@@ -0,0 +1,34 @@
+/*
+ * 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
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#ifndef __vino_dbus_h__
+#define __vino_dbus_h__
+
+#include <gio/gio.h>
+
+extern const GDBusInterfaceInfo org_gnome_VinoScreen_interface;
+#define ORG_GNOME_VINO_SCREEN_INTERFACE_NAME    "org.gnome.VinoScreen"
+#define ORG_GNOME_VINO_BUS_NAME                 "org.gnome.Vino"
+#define ORG_GNOME_VINO_SCREEN_PATH_PREFIX       "/org/gnome/vino/screens/"
+#define ORG_GNOME_VINO_SCREEN_INTERFACE \
+  ((GDBusInterfaceInfo *) &org_gnome_VinoScreen_interface)
+
+#endif /* __vino_dbus_h__ */
diff --git a/common/vino-keyring.c b/common/vino-keyring.c
new file mode 100644
index 0000000..27e829e
--- /dev/null
+++ b/common/vino-keyring.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2003 Sun Microsystems, Inc.
+ * Copyright (C) 2006 Jonh Wendell <wendell bani com br>
+ * 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
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ *      Mark McLoughlin <mark skynet ie>
+ *      Jonh Wendell <wendell bani com br>
+ *      Ryan Lortie <desrt desrt ca>
+ */
+
+#include "vino-keyring.h"
+
+#ifdef VINO_ENABLE_KEYRING
+
+/* TODO: canhas async? */
+
+#include <gnome-keyring.h>
+
+static char *
+vino_keyring_get_password (void)
+{
+  GnomeKeyringNetworkPasswordData *found_item;
+  GnomeKeyringResult               result;
+  GList                           *matches;
+  char                            *password;
+
+  matches = NULL;
+
+  result = gnome_keyring_find_network_password_sync (
+                NULL,           /* user     */
+                NULL,           /* domain   */
+                "vino.local",   /* server   */
+                NULL,           /* object   */
+                "rfb",          /* protocol */
+                "vnc-password", /* authtype */
+                5900,           /* port     */
+                &matches);
+
+  if (result != GNOME_KEYRING_RESULT_OK || matches == NULL || matches->data == NULL)
+    return NULL;
+
+  found_item = (GnomeKeyringNetworkPasswordData *) matches->data;
+
+  password = g_strdup (found_item->password);
+
+  gnome_keyring_network_password_list_free (matches);
+
+  return password;
+}
+
+static gboolean
+vino_keyring_set_password (const char *password)
+{
+  GnomeKeyringResult result;
+  guint32            item_id;
+
+  result = gnome_keyring_set_network_password_sync (
+                NULL,           /* default keyring */
+                NULL,           /* user            */
+                NULL,           /* domain          */
+                "vino.local",   /* server          */
+                NULL,           /* object          */
+                "rfb",          /* protocol        */
+                "vnc-password", /* authtype        */
+                5900,           /* port            */
+                password,       /* password        */
+                &item_id);
+
+  return result == GNOME_KEYRING_RESULT_OK;
+}
+
+#else
+
+gchar *
+vino_keyring_get_password (void)
+{
+  return NULL;
+}
+
+gboolean
+vino_keyring_set_password (const gchar *password)
+{
+  return FALSE;
+}
+
+#endif
diff --git a/common/vino-keyring.h b/common/vino-keyring.h
new file mode 100644
index 0000000..879979c
--- /dev/null
+++ b/common/vino-keyring.h
@@ -0,0 +1,30 @@
+/*
+ * 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
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#ifndef __vino_keyring_h__
+#define __vino_keyring_h__
+
+#include <glib.h>
+
+gchar *         vino_keyring_get_password       (void);
+gboolean        vino_keyring_set_password       (const gchar *password);
+
+#endif /* __vino_keyring_h__ */
diff --git a/configure.in b/configure.in
index 7e87ada..0ac63f3 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,6 @@ AC_CONFIG_HEADERS([config.h])
 
 AM_INIT_AUTOMAKE([1.10])
 m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
-AM_MAINTAINER_MODE
 
 dnl make sure we keep ACLOCAL_FLAGS around for maintainer builds to work
 AC_SUBST(ACLOCAL_AMFLAGS, "\${ACLOCAL_FLAGS}")
@@ -31,7 +30,6 @@ AC_SEARCH_LIBS([strerror],[cposix])
 AC_HEADER_STDC
 AC_C_BIGENDIAN
 
-AC_PATH_PROG(GCONFTOOL, gconftool-2)
 AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal)
 
 GTK_VERSION=2.20.0
@@ -41,21 +39,23 @@ SOUP_VERSION=2.24.0
 TELEPATHY_GLIB_VERSION=0.11.6
 NETWORKMANAGER_VERSION=0.7
 
-PKG_CHECK_MODULES(VINO_SERVER, glib-2.0 >= $GLIB_VERSION gtk+-x11-2.0 >= $GTK_VERSION gconf-2.0 dbus-1 >= $DBUS_VERSION dbus-glib-1)
+PKG_CHECK_MODULES(VINO_SERVER, glib-2.0 >= $GLIB_VERSION gtk+-x11-3.0 >= $GTK_VERSION dbus-1 >= $DBUS_VERSION dbus-glib-1)
 
-PKG_CHECK_MODULES(VINO_CAPPLET, glib-2.0 >= $GLIB_VERSION gtk+-2.0 >= $GTK_VERSION gconf-2.0 dbus-1 >= $DBUS_VERSION dbus-glib-1 libsoup-2.4 >= $SOUP_VERSION)
+PKG_CHECK_MODULES(VINO_CAPPLET, glib-2.0 >= $GLIB_VERSION gtk+-3.0 >= $GTK_VERSION dbus-1 >= $DBUS_VERSION dbus-glib-1 libsoup-2.4 >= $SOUP_VERSION)
 
-PKG_CHECK_MODULES(VINO_TOOLS, glib-2.0 >= $GLIB_VERSION gconf-2.0 gobject-2.0 >= $GLIB_VERSION gnome-keyring-1)
+PKG_CHECK_MODULES(VINO_TOOLS, glib-2.0 >= $GLIB_VERSION gobject-2.0 >= $GLIB_VERSION gnome-keyring-1)
 
 # EGG stuff
-PKG_CHECK_MODULES(EGG, gtk+-2.0 >= $GTK_VERSION)
+PKG_CHECK_MODULES(EGG, gtk+-3.0 >= $GTK_VERSION)
 AC_SUBST(EGG_LIBS)
 AC_SUBST(EGG_CFLAGS)
 
-PKG_CHECK_MODULES(EGG_SMCLIENT, gtk+-2.0)
+PKG_CHECK_MODULES(EGG_SMCLIENT, gtk+-3.0)
 AC_SUBST(EGG_SMCLIENT_LIBS)
 AC_SUBST(EGG_SMCLIENT_CFLAGS)
 
+GLIB_GSETTINGS
+
 
 # Check for telepathy-glib
 AC_ARG_ENABLE(telepathy,
@@ -367,31 +367,6 @@ else
 fi
 AC_MSG_RESULT($have_ipv6)
 
-dnl --enable-libunique=(yes|no)
-LIBUNIQUE_VERSION=1.0.0
-
-AC_ARG_ENABLE(libunique,
-         [  --enable-libunique=[no/yes] Use the library unique to allow only one instance running [default=auto]],,
-         enable_libunique=auto)
-if test "$enable_libunique" = "no"; then
-  have_libunique=no
-else
-  if test "$enable_libunique" = "yes"; then
-    PKG_CHECK_MODULES(VINO_LIBUNIQUE, unique-1.0 >= $LIBUNIQUE_VERSION)
-    have_libunique=yes
-  else
-    PKG_CHECK_MODULES(VINO_LIBUNIQUE,
-                      unique-1.0 >= $LIBUNIQUE_VERSION,
-                      have_libunique=yes, have_libunique=no)
-  fi;
-fi
-
-if test "x$have_libunique" = "xyes" ; then
-  AC_DEFINE(VINO_ENABLE_LIBUNIQUE, [], [Set if we should use libunique])
-fi
-
-AM_GCONF_SOURCE_2
-
 dnl define a MAINT-like variable REBUILD which is set
 dnl if Perl, so autogenerated sources can be rebuilt
 AC_PATH_PROGS(PERL, perl5 perl)
@@ -406,6 +381,7 @@ AC_SUBST(REBUILD)
 
 AC_CONFIG_FILES([
 Makefile
+common/Makefile
 server/Makefile
 server/libvncserver/Makefile
 server/libvncserver/ifaddr/Makefile
@@ -434,7 +410,6 @@ Configure summary:
 	Network Manager support ....:  ${have_networkmanager}
 	GNOME Keyring support.......:  ${enable_gnome_keyring}
 	HTTP server.................:  ${enable_http_server}
-	Libunique support...........:  ${have_libunique}
 	DEBUG messages..............:  ${enable_debug}
 	Telepathy support...........:  ${have_telepathy}
 "
diff --git a/server/Makefile.am b/server/Makefile.am
index 1342487..23de2cd 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -162,17 +162,6 @@ org.freedesktop.Telepathy.Client.Vino.service: org.freedesktop.Telepathy.Client.
 
 @INTLTOOL_DESKTOP_RULE@
 
-if GCONF_SCHEMAS_INSTALL
-install-data-local:
-	if test -z "$(DESTDIR)" ; then \
-		for p in $(schemas_DATA) ; do \
-			GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(top_builddir)/server/$$p ; \
-		done ; \
-        fi
-else
-install-data-local:
-endif
-
 uidir   = $(datadir)/vino
 ui_DATA = vino-prompt.ui
 
diff --git a/server/vino-fb.c b/server/vino-fb.c
index 8d3bf64..61adcd5 100644
--- a/server/vino-fb.c
+++ b/server/vino-fb.c
@@ -2,6 +2,7 @@
  * Copyright (C) 2003 Sun Microsystems, Inc.
  * Copyright (C) 2004 Red Hat, Inc.
  * Copyright (C) 2004 Novell, 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
@@ -21,6 +22,7 @@
  * Authors:
  *      Mark McLoughlin <mark skynet ie>
  *      Federico Mena Quintero <federico ximian com>
+ *      Ryan Lortie <desrt desrt ca>
  *
  *
  *   The screen polling code is based on XUpdateScanner from
@@ -74,12 +76,12 @@ struct _VinoFBPrivate
   XImage          *tile;
   XShmSegmentInfo  tile_x_shm_info;
 
-  GdkRegion       *damage_region;
+  cairo_region_t  *damage_region;
 
   guint            update_timeout;
 
 #ifdef HAVE_XDAMAGE
-  GdkRegion       *pending_damage;
+  cairo_region_t  *pending_damage;
   guint            damage_idle_handler;
 
   Damage           xdamage;
@@ -312,8 +314,8 @@ vino_fb_create_image (VinoFB           *vfb,
 }
 
 static gboolean
-vino_fb_copy_tile (VinoFB       *vfb,
-		   GdkRectangle *rect)
+vino_fb_copy_tile (VinoFB                      *vfb,
+		   const cairo_rectangle_int_t *rect)
 {
   XImage *fb_image;
   char   *src;
@@ -390,7 +392,7 @@ vino_fb_poll_scanline (VinoFB *vfb,
 
       if (memcmp (dest, src, width * bytes_per_pixel) != 0)
 	{
-	  GdkRectangle rect;
+	  cairo_rectangle_int_t rect;
 
 	  rect.x = x;
 	  rect.y = line - (line % TILE_HEIGHT);
@@ -402,9 +404,9 @@ vino_fb_poll_scanline (VinoFB *vfb,
 	  if (vino_fb_copy_tile (vfb, &rect))
 	    {
 	      if (!vfb->priv->damage_region)
-		vfb->priv->damage_region = gdk_region_rectangle (&rect);
+		vfb->priv->damage_region = cairo_region_create_rectangle (&rect);
 	      else
-		gdk_region_union_with_rect (vfb->priv->damage_region, &rect);
+                cairo_region_union_rectangle (vfb->priv->damage_region, &rect);
 	    }
 
 	  retval = TRUE;
@@ -461,7 +463,7 @@ vino_fb_finalize_xdamage (VinoFB *vfb)
   vfb->priv->damage_idle_handler = 0;
 
   if (vfb->priv->pending_damage)
-    gdk_region_destroy (vfb->priv->pending_damage);
+    cairo_region_destroy (vfb->priv->pending_damage);
   vfb->priv->pending_damage = NULL;
 
   if (vfb->priv->fb_pixmap)
@@ -515,7 +517,7 @@ static void
 vino_fb_finalize_screen_data (VinoFB *vfb)
 {
   if (vfb->priv->damage_region)
-    gdk_region_destroy (vfb->priv->damage_region);
+    cairo_region_destroy (vfb->priv->damage_region);
   vfb->priv->damage_region = NULL;
 
   if (vfb->priv->use_xdamage)
@@ -554,19 +556,18 @@ vino_fb_screen_size_changed (VinoFB    *vfb,
 static gboolean
 vino_fb_xdamage_idle_handler (VinoFB *vfb)
 {
-  GdkRectangle *damage = NULL;
-  XRectangle    xdamage;
-  int           n_rects;
-  int           error;
+  cairo_rectangle_int_t damage;
+  XRectangle            xdamage;
+  int                   error;
 
-  g_assert (!gdk_region_empty (vfb->priv->pending_damage));
+  g_assert (!cairo_region_is_empty (vfb->priv->pending_damage));
 
-  gdk_region_get_rectangles (vfb->priv->pending_damage, &damage, &n_rects);
+  cairo_region_get_rectangle (vfb->priv->pending_damage, 0, &damage);
 
-  xdamage.x      = damage->x;
-  xdamage.y      = damage->y;
-  xdamage.width  = damage->width;
-  xdamage.height = damage->height;
+  xdamage.x      = damage.x;
+  xdamage.y      = damage.y;
+  xdamage.width  = damage.width;
+  xdamage.height = damage.height;
 
   dprintf (POLLING, "Updating damaged region in idle: %d %d %dx%d\n",
 	   damage->x, damage->y, damage->width, damage->height);
@@ -587,27 +588,27 @@ vino_fb_xdamage_idle_handler (VinoFB *vfb)
 		 GDK_WINDOW_XWINDOW (vfb->priv->root_window),
 		 vfb->priv->fb_pixmap,
 		 vfb->priv->xdamage_copy_gc,
-		 damage->x,
-		 damage->y,
-		 damage->width,
-		 damage->height,
-		 damage->x,
-		 damage->y);
+		 damage.x,
+		 damage.y,
+		 damage.width,
+		 damage.height,
+		 damage.x,
+		 damage.y);
       XSync (vfb->priv->xdisplay, False);
     }
   else
     {
       XGetSubImage (vfb->priv->xdisplay,
 		    GDK_WINDOW_XWINDOW (vfb->priv->root_window),
-		    damage->x,
-		    damage->y,
-		    damage->width,
-		    damage->height,
+		    damage.x,
+		    damage.y,
+		    damage.width,
+		    damage.height,
 		    AllPlanes,
 		    ZPixmap,
 		    vfb->priv->fb_image,
-		    damage->x,
-		    damage->y);
+		    damage.x,
+		    damage.y);
     }
 
   if ((error = gdk_error_trap_pop ()))
@@ -632,24 +633,22 @@ vino_fb_xdamage_idle_handler (VinoFB *vfb)
 
   /* add damage to our region */
   if (vfb->priv->damage_region)
-    gdk_region_union_with_rect (vfb->priv->damage_region, damage);
+    cairo_region_union_rectangle (vfb->priv->damage_region, &damage);
   else
-    vfb->priv->damage_region = gdk_region_rectangle (damage);
+    vfb->priv->damage_region = cairo_region_create_rectangle (&damage);
 
   emit_damage_notify (vfb);
 
  out:
   {
-    GdkRegion *tmp;
+    cairo_region_t *tmp;
 
-    tmp = gdk_region_rectangle (damage);
-    gdk_region_subtract (vfb->priv->pending_damage, tmp);
-    gdk_region_destroy (tmp);
+    tmp = cairo_region_create_rectangle (&damage);
+    cairo_region_subtract (vfb->priv->pending_damage, tmp);
+    cairo_region_destroy (tmp);
   }
 
-  g_free (damage);
-
-  if (gdk_region_empty (vfb->priv->pending_damage))
+  if (cairo_region_is_empty (vfb->priv->pending_damage))
     {
       vfb->priv->damage_idle_handler = 0;
       return FALSE;
@@ -663,9 +662,9 @@ vino_fb_xdamage_event_filter (GdkXEvent *xevent,
 			      GdkEvent  *event,
 			      VinoFB    *vfb)
 {
-  XEvent             *xev = (XEvent *) xevent;
-  XDamageNotifyEvent *notify;
-  GdkRectangle        damage;
+  XEvent                *xev = (XEvent *) xevent;
+  XDamageNotifyEvent    *notify;
+  cairo_rectangle_int_t  damage;
 
   if (xev->type != vfb->priv->xdamage_notify_event)
     return GDK_FILTER_CONTINUE;
@@ -681,7 +680,7 @@ vino_fb_xdamage_event_filter (GdkXEvent *xevent,
 	   damage.x, damage.y, damage.width, damage.height,
 	   notify->more ? "(true)" : "(false)", notify->level);
 
-  gdk_region_union_with_rect (vfb->priv->pending_damage, &damage);
+  cairo_region_union_rectangle (vfb->priv->pending_damage, &damage);
 
   if (!vfb->priv->damage_idle_handler)
     vfb->priv->damage_idle_handler =
@@ -740,7 +739,7 @@ vino_fb_init_xdamage (VinoFB *vfb)
 			 (GdkFilterFunc) vino_fb_xdamage_event_filter,
 			 vfb);
 
-  vfb->priv->pending_damage = gdk_region_new ();
+  vfb->priv->pending_damage = cairo_region_create ();
 
   vfb->priv->use_xdamage = TRUE;
 #endif
@@ -1176,65 +1175,53 @@ vino_fb_get_color_masks (VinoFB *vfb,
 }
 
 static inline void
-vino_fb_debug_dump_damage (VinoFB       *vfb,
-			   GdkRectangle *rects,
-			   int           n_rects)
+vino_fb_debug_dump_damage (VinoFB         *vfb,
+			   cairo_region_t *region)
 {
 #ifdef GNOME_ENABLE_DEBUG
   if (_vino_debug_flags & VINO_DEBUG_POLLING)
     {
-      GdkRectangle clipbox;
-      int          area;
-      int          i;
+      cairo_rectangle_int_t extents;
+      int                   n_rects;
+      int                   area;
+      int                   i;
 
-      gdk_region_get_clipbox (vfb->priv->damage_region, &clipbox);
+      cairo_region_get_extents (vfb->priv->damage_region, &extents);
 
-      fprintf (stderr, "Dump of damage region: clipbox (%d, %d) (%d x %d)\n",
-	       clipbox.x, clipbox.y, clipbox.width, clipbox.height);
+      fprintf (stderr, "Dump of damage region: extents (%d, %d) (%d x %d)\n",
+               extents.x, extents.y, extents.width, extents.height);
 
       area = 0;
+      n_rects = cairo_region_num_rectangles (region);
       for (i = 0; i < n_rects; i++)
-	{
-	  fprintf (stderr, "\t(%d, %d) (%d x %d)\n",
-		   rects [i].x, rects [i].y, rects [i].width, rects [i].height);
-	  area += rects [i].width * rects [i].height;
-	}
+        {
+          cairo_rectangle_int_t rect;
+
+          cairo_region_get_rectangle (region, i, &rect);
+
+          fprintf (stderr, "\t(%d, %d) (%d x %d)\n",
+                   rect.x, rect.y, rect.width, rect.height);
+          area += rect.width * rect.height;
+        }
 
       fprintf (stderr, "Bounding area %d, damaged area %d ... (%d%%)\n",
-	       clipbox.width * clipbox.height, area,
-	       (area * 100) / (clipbox.width * clipbox.height));
+               extents.width * extents.height, area,
+               (area * 100) / (extents.width * extents.height));
     }
 #endif
 }
 
-GdkRectangle *
-vino_fb_get_damage (VinoFB   *vfb,
-		    int      *n_rects,
-		    gboolean  clear_damage)
-
+cairo_region_t *
+vino_fb_steal_damage (VinoFB *vfb)
 {
-  GdkRectangle *retval;
+  cairo_region_t *retval;
 
   g_return_val_if_fail (VINO_IS_FB (vfb), NULL);
-  g_return_val_if_fail (n_rects != NULL, NULL);
-
-  if (!vfb->priv->damage_region)
-    {
-      *n_rects = 0;
-      return NULL;
-    }
 
-  retval = NULL;
-  *n_rects = 0;
-  gdk_region_get_rectangles (vfb->priv->damage_region, &retval, n_rects);
+  retval = vfb->priv->damage_region;
+  vino_fb_debug_dump_damage (vfb, retval);
 
-  vino_fb_debug_dump_damage (vfb, retval, *n_rects);
- 
-  if (clear_damage)
-    {
-      gdk_region_destroy (vfb->priv->damage_region);
-      vfb->priv->damage_region = NULL;
-    }
+  vfb->priv->damage_region = NULL;
 
   return retval;
 }
diff --git a/server/vino-fb.h b/server/vino-fb.h
index 149ebee..40fd404 100644
--- a/server/vino-fb.h
+++ b/server/vino-fb.h
@@ -71,9 +71,7 @@ void          vino_fb_get_color_masks    (VinoFB    *vfb,
 					  gulong    *green_mask,
 					  gulong    *blue_mask);
 
-GdkRectangle *vino_fb_get_damage         (VinoFB    *vfb,
-					  int       *n_rects,
-					  gboolean   clear_damage);
+cairo_region_t *   vino_fb_steal_damage  (VinoFB    *vfb);
 
 G_END_DECLS
 
diff --git a/server/vino-prefs.c b/server/vino-prefs.c
index fb9645b..0304154 100644
--- a/server/vino-prefs.c
+++ b/server/vino-prefs.c
@@ -22,7 +22,6 @@
 
 #include <config.h>
 #include <string.h>
-#include <gconf/gconf-client.h>
 #include <glib/gstdio.h>
 #include <signal.h>
 #include <fcntl.h>
diff --git a/server/vino-server.c b/server/vino-server.c
index 04ebb05..3c10d1c 100644
--- a/server/vino-server.c
+++ b/server/vino-server.c
@@ -801,21 +801,31 @@ vino_server_check_vnc_password (rfbClientPtr  rfb_client,
 static void
 vino_server_handle_damage_notify (VinoServer *server)
 {
-  GdkRectangle *rects;
-  int           i, n_rects;
+  cairo_region_t *region;
 
   g_return_if_fail (VINO_IS_SERVER (server));
-  
-  rects = vino_fb_get_damage (server->priv->fb, &n_rects, TRUE);
 
-  for (i = 0; i < n_rects; i++)
-    rfbMarkRectAsModified (server->priv->rfb_screen,
-			   rects [i].x,
-			   rects [i].y,
-			   rects [i].x + rects [i].width,
-			   rects [i].y + rects [i].height);
+  if ((region = vino_fb_steal_damage (server->priv->fb)))
+    {
+      int i, n_rects;
+
+      n_rects = cairo_region_num_rectangles (region);
+
+      for (i = 0; i < n_rects; i++)
+        {
+          cairo_rectangle_int_t rect;
 
-  g_free (rects);
+          cairo_region_get_rectangle (region, i, &rect);
+
+          rfbMarkRectAsModified (server->priv->rfb_screen,
+                                 rect.x,
+                                 rect.y,
+                                 rect.x + rect.width,
+                                 rect.y + rect.height);
+        }
+
+      cairo_region_destroy (region);
+    }
 }
 
 static void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]