vino r1049 - in trunk: . capplet po server



Author: jwendell
Date: Wed Jan 21 16:02:03 2009
New Revision: 1049
URL: http://svn.gnome.org/viewvc/vino?rev=1049&view=rev

Log:
2009-01-21  Jonh Wendell  <jwendell gnome org>

	* lots of files: Rewrite of capplet, hiding some advanced features.
	Also, we check now if the machine can be accessed through the Internet.



Added:
   trunk/capplet/gedit-spinner.c
   trunk/capplet/gedit-spinner.h
   trunk/capplet/sexy-url-label.c
   trunk/capplet/sexy-url-label.h
   trunk/capplet/vino-message-box.c
   trunk/capplet/vino-message-box.h
Modified:
   trunk/ChangeLog
   trunk/capplet/Makefile.am
   trunk/capplet/vino-preferences.c
   trunk/capplet/vino-preferences.glade
   trunk/configure.in
   trunk/po/POTFILES.in
   trunk/server/vino-dbus-listener.c
   trunk/server/vino-server.c
   trunk/server/vino-server.h

Modified: trunk/capplet/Makefile.am
==============================================================================
--- trunk/capplet/Makefile.am	(original)
+++ trunk/capplet/Makefile.am	Wed Jan 21 16:02:03 2009
@@ -15,6 +15,9 @@
 
 vino_preferences_SOURCES = \
 	vino-preferences.c \
+	gedit-spinner.h gedit-spinner.c \
+	vino-message-box.h vino-message-box.c \
+	sexy-url-label.h sexy-url-label.c \
 	$(NULL)
 vino_preferences_LDADD = \
 	$(VINO_CAPPLET_LIBS) \
@@ -23,11 +26,6 @@
 	$(X_LIBS) \
 	$(NULL)
 
-if !HAVE_GETIFADDRS
-INCLUDES += -I../server/libvncserver
-vino_preferences_LDADD += ../server/libvncserver/libifaddrs.la
-endif
-
 gladedir   = $(datadir)/vino
 glade_DATA = vino-preferences.glade
 

Added: trunk/capplet/gedit-spinner.c
==============================================================================
--- (empty file)
+++ trunk/capplet/gedit-spinner.c	Wed Jan 21 16:02:03 2009
@@ -0,0 +1,989 @@
+/*
+ * gedit-spinner.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2005 - Paolo Maggi 
+ * Copyright (C) 2002-2004 Marco Pesenti Gritti
+ * Copyright (C) 2004 Christian Persch
+ * Copyright (C) 2000 - Eazel, Inc. 
+ *
+ * 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.
+ */
+ 
+/*
+ * This widget was originally written by Andy Hertzfeld <andy eazel com> for
+ * Nautilus. It was then modified by Marco Pesenti Gritti and Christian Persch
+ * for Epiphany.
+ *
+ * Modified by the gedit Team, 2005. See the AUTHORS file for a 
+ * list of people on the gedit Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: gedit-spinner.c 6631 2008-11-29 11:06:49Z pborelli $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gedit-spinner.h"
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gtk/gtk.h>
+
+/* Spinner cache implementation */
+
+#define GEDIT_TYPE_SPINNER_CACHE		(gedit_spinner_cache_get_type())
+#define GEDIT_SPINNER_CACHE(object)		(G_TYPE_CHECK_INSTANCE_CAST((object), GEDIT_TYPE_SPINNER_CACHE, GeditSpinnerCache))
+#define GEDIT_SPINNER_CACHE_CLASS(klass) 	(G_TYPE_CHECK_CLASS_CAST((klass), GEDIT_TYPE_SPINNER_CACHE, GeditSpinnerCacheClass))
+#define GEDIT_IS_SPINNER_CACHE(object)		(G_TYPE_CHECK_INSTANCE_TYPE((object), GEDIT_TYPE_SPINNER_CACHE))
+#define GEDIT_IS_SPINNER_CACHE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GEDIT_TYPE_SPINNER_CACHE))
+#define GEDIT_SPINNER_CACHE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GEDIT_TYPE_SPINNER_CACHE, GeditSpinnerCacheClass))
+
+typedef struct _GeditSpinnerCache		GeditSpinnerCache;
+typedef struct _GeditSpinnerCacheClass		GeditSpinnerCacheClass;
+typedef struct _GeditSpinnerCachePrivate	GeditSpinnerCachePrivate;
+
+struct _GeditSpinnerCacheClass
+{
+	GObjectClass parent_class;
+};
+
+struct _GeditSpinnerCache
+{
+	GObject parent_object;
+
+	/*< private >*/
+	GeditSpinnerCachePrivate *priv;
+};
+
+#define GEDIT_SPINNER_CACHE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GEDIT_TYPE_SPINNER_CACHE, GeditSpinnerCachePrivate))
+
+struct _GeditSpinnerCachePrivate
+{
+	/* Hash table of GdkScreen -> GeditSpinnerCacheData */
+	GHashTable *hash;
+};
+
+typedef struct
+{
+	guint        ref_count;
+	GtkIconSize  size;
+	gint         width;
+	gint         height;
+	GdkPixbuf  **animation_pixbufs;
+	guint        n_animation_pixbufs;
+} GeditSpinnerImages;
+
+#define LAST_ICON_SIZE			GTK_ICON_SIZE_DIALOG + 1
+#define SPINNER_ICON_NAME		"process-working"
+#define SPINNER_FALLBACK_ICON_NAME	"gnome-spinner"
+#define GEDIT_SPINNER_IMAGES_INVALID	((GeditSpinnerImages *) 0x1)
+
+typedef struct
+{
+	GdkScreen          *screen;
+	GtkIconTheme       *icon_theme;
+	GeditSpinnerImages *images[LAST_ICON_SIZE];
+} GeditSpinnerCacheData;
+
+static void gedit_spinner_cache_class_init	(GeditSpinnerCacheClass *klass);
+static void gedit_spinner_cache_init		(GeditSpinnerCache      *cache);
+
+static GObjectClass *gedit_spinner_cache_parent_class;
+
+static GType
+gedit_spinner_cache_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0))
+	{
+		const GTypeInfo our_info =
+		{
+			sizeof (GeditSpinnerCacheClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) gedit_spinner_cache_class_init,
+			NULL,
+			NULL,
+			sizeof (GeditSpinnerCache),
+			0,
+			(GInstanceInitFunc) gedit_spinner_cache_init
+		};
+
+		type = g_type_register_static (G_TYPE_OBJECT,
+					       "GeditSpinnerCache",
+					       &our_info, 0);
+	}
+
+	return type;
+}
+
+static GeditSpinnerImages *
+gedit_spinner_images_ref (GeditSpinnerImages *images)
+{
+	g_return_val_if_fail (images != NULL, NULL);
+
+	images->ref_count++;
+
+	return images;
+}
+
+static void
+gedit_spinner_images_unref (GeditSpinnerImages *images)
+{
+	g_return_if_fail (images != NULL);
+
+	images->ref_count--;
+	if (images->ref_count == 0)
+	{
+		guint i;
+
+		/* LOG ("Freeing spinner images %p for size %d", images, images->size); */
+
+		for (i = 0; i < images->n_animation_pixbufs; ++i)
+		{
+			g_object_unref (images->animation_pixbufs[i]);
+		}
+		g_free (images->animation_pixbufs);
+
+		g_free (images);
+	}
+}
+
+static void
+gedit_spinner_cache_data_unload (GeditSpinnerCacheData *data)
+{
+	GtkIconSize size;
+	GeditSpinnerImages *images;
+
+	g_return_if_fail (data != NULL);
+
+	/* LOG ("GeditSpinnerDataCache unload for screen %p", data->screen); */
+
+	for (size = GTK_ICON_SIZE_INVALID; size < LAST_ICON_SIZE; ++size)
+	{
+		images = data->images[size];
+		data->images[size] = NULL;
+
+		if (images != NULL && images != GEDIT_SPINNER_IMAGES_INVALID)
+		{
+			gedit_spinner_images_unref (images);
+		}
+	}
+}
+
+static GdkPixbuf *
+extract_frame (GdkPixbuf *grid_pixbuf,
+	       int x,
+	       int y,
+	       int size)
+{
+	GdkPixbuf *pixbuf;
+
+	if (x + size > gdk_pixbuf_get_width (grid_pixbuf) ||
+	    y + size > gdk_pixbuf_get_height (grid_pixbuf))
+	{
+		return NULL;
+	}
+
+	pixbuf = gdk_pixbuf_new_subpixbuf (grid_pixbuf,
+					   x, y,
+					   size, size);
+	g_return_val_if_fail (pixbuf != NULL, NULL);
+
+	return pixbuf;
+}
+
+static GdkPixbuf *
+scale_to_size (GdkPixbuf *pixbuf,
+	       int dw,
+	       int dh)
+{
+	GdkPixbuf *result;
+	int pw, ph;
+
+	g_return_val_if_fail (pixbuf != NULL, NULL);
+
+	pw = gdk_pixbuf_get_width (pixbuf);
+	ph = gdk_pixbuf_get_height (pixbuf);
+
+	if (pw != dw || ph != dh)
+	{
+		result = gdk_pixbuf_scale_simple (pixbuf, dw, dh,
+						  GDK_INTERP_BILINEAR);
+		g_object_unref (pixbuf);
+		return result;
+	}
+
+	return pixbuf;
+}
+
+static GeditSpinnerImages *
+gedit_spinner_images_load (GdkScreen *screen,
+			   GtkIconTheme *icon_theme,
+			   GtkIconSize icon_size)
+{
+	GeditSpinnerImages *images;
+	GdkPixbuf *icon_pixbuf, *pixbuf;
+	GtkIconInfo *icon_info = NULL;
+	int grid_width, grid_height, x, y, requested_size, size, isw, ish, n;
+	const char *icon;
+	GSList *list = NULL, *l;
+
+	/* LOG ("GeditSpinnerCacheData loading for screen %p at size %d", screen, icon_size); */
+
+	/* START_PROFILER ("loading spinner animation") */
+
+	if (!gtk_icon_size_lookup_for_settings (gtk_settings_get_for_screen (screen),
+						icon_size, &isw, &ish))
+		goto loser;
+ 
+	requested_size = MAX (ish, isw);
+
+	/* Load the animation. The 'rest icon' is the 0th frame */
+	icon_info = gtk_icon_theme_lookup_icon (icon_theme,
+						SPINNER_ICON_NAME,
+						requested_size, 0);
+	if (icon_info == NULL)
+	{
+		g_warning ("Throbber animation not found");
+
+		/* If the icon naming spec compliant name wasn't found, try the old name */
+		icon_info = gtk_icon_theme_lookup_icon (icon_theme,
+							SPINNER_FALLBACK_ICON_NAME,
+						        requested_size, 0);
+		if (icon_info == NULL)
+		{
+			g_warning ("Throbber fallback animation not found either");
+			goto loser;
+	 	}
+	}
+
+	g_assert (icon_info != NULL);
+
+	size = gtk_icon_info_get_base_size (icon_info);
+	icon = gtk_icon_info_get_filename (icon_info);
+
+	if (icon == NULL)
+		goto loser;
+
+	icon_pixbuf = gdk_pixbuf_new_from_file (icon, NULL);
+	gtk_icon_info_free (icon_info);
+	icon_info = NULL;
+
+	if (icon_pixbuf == NULL)
+	{
+		g_warning ("Could not load the spinner file");
+		goto loser;
+	}
+
+	grid_width = gdk_pixbuf_get_width (icon_pixbuf);
+	grid_height = gdk_pixbuf_get_height (icon_pixbuf);
+
+	n = 0;
+	for (y = 0; y < grid_height; y += size)
+	{
+		for (x = 0; x < grid_width ; x += size)
+		{
+			pixbuf = extract_frame (icon_pixbuf, x, y, size);
+
+			if (pixbuf)
+			{
+				list = g_slist_prepend (list, pixbuf);
+				++n;
+			}
+			else
+			{
+				g_warning ("Cannot extract frame (%d, %d) from the grid\n", x, y);
+			}
+		}
+	}
+
+	g_object_unref (icon_pixbuf);
+
+	if (list == NULL)
+		goto loser;
+
+	/* g_assert (n > 0); */
+
+	if (size > requested_size)
+	{
+		for (l = list; l != NULL; l = l->next)
+		{
+			l->data = scale_to_size (l->data, isw, ish);
+		}
+ 	}
+
+	/* Now we've successfully got all the data */
+	images = g_new (GeditSpinnerImages, 1);
+	images->ref_count = 1;
+ 
+	images->size = icon_size;
+	images->width = images->height = requested_size;
+
+	images->n_animation_pixbufs = n;
+	images->animation_pixbufs = g_new (GdkPixbuf *, n);
+
+	for (l = list; l != NULL; l = l->next)
+	{
+		g_assert (l->data != NULL);
+		images->animation_pixbufs[--n] = l->data;
+	}
+	g_assert (n == 0);
+
+	g_slist_free (list);
+
+	/* STOP_PROFILER ("loading spinner animation") */
+	return images;
+ 
+loser:
+	if (icon_info)
+	{
+		gtk_icon_info_free (icon_info);
+ 	}
+
+	g_slist_foreach (list, (GFunc) g_object_unref, NULL);
+
+	/* STOP_PROFILER ("loading spinner animation") */
+
+	return NULL;
+}
+
+static GeditSpinnerCacheData *
+gedit_spinner_cache_data_new (GdkScreen *screen)
+{
+	GeditSpinnerCacheData *data;
+
+	data = g_new0 (GeditSpinnerCacheData, 1);
+
+	data->screen = screen;
+	data->icon_theme = gtk_icon_theme_get_for_screen (screen);
+	g_signal_connect_swapped (data->icon_theme,
+				  "changed",
+				  G_CALLBACK (gedit_spinner_cache_data_unload),
+				  data);
+
+	return data;
+}
+
+static void
+gedit_spinner_cache_data_free (GeditSpinnerCacheData *data)
+{
+	g_return_if_fail (data != NULL);
+	g_return_if_fail (data->icon_theme != NULL);
+
+	g_signal_handlers_disconnect_by_func (data->icon_theme,
+					      G_CALLBACK (gedit_spinner_cache_data_unload),
+					      data);
+
+	gedit_spinner_cache_data_unload (data);
+
+	g_free (data);
+}
+
+static GeditSpinnerImages *
+gedit_spinner_cache_get_images (GeditSpinnerCache *cache,
+				GdkScreen         *screen,
+				GtkIconSize        icon_size)
+{
+	GeditSpinnerCachePrivate *priv = cache->priv;
+	GeditSpinnerCacheData *data;
+	GeditSpinnerImages *images;
+
+	/* LOG ("Getting animation images for screen %p at size %d", screen, icon_size); */
+
+	g_return_val_if_fail (icon_size >= 0 && icon_size < LAST_ICON_SIZE, NULL);
+
+	/* Backward compat: "invalid" meant "native" size which doesn't exist anymore */
+	if (icon_size == GTK_ICON_SIZE_INVALID)
+	{
+		icon_size = GTK_ICON_SIZE_DIALOG;
+	}
+
+	data = g_hash_table_lookup (priv->hash, screen);
+	if (data == NULL)
+	{
+		data = gedit_spinner_cache_data_new (screen);
+		/* FIXME: think about what happens when the screen's display is closed later on */
+		g_hash_table_insert (priv->hash, screen, data);
+	}
+
+	images = data->images[icon_size];
+	if (images == GEDIT_SPINNER_IMAGES_INVALID)
+	{
+		/* Load failed, but don't try endlessly again! */
+		return NULL;
+	}
+
+	if (images != NULL)
+	{
+		/* Return cached data */
+		return gedit_spinner_images_ref (images);
+	}
+
+	images = gedit_spinner_images_load (screen, data->icon_theme, icon_size);
+
+	if (images == NULL)
+ 	{
+		/* Mark as failed-to-load */
+		data->images[icon_size] = GEDIT_SPINNER_IMAGES_INVALID;
+ 
+		return NULL;
+ 	}
+
+	data->images[icon_size] = images;
+
+	return gedit_spinner_images_ref (images);
+}
+
+static void
+gedit_spinner_cache_init (GeditSpinnerCache *cache)
+{
+	GeditSpinnerCachePrivate *priv;
+
+	priv = cache->priv = GEDIT_SPINNER_CACHE_GET_PRIVATE (cache);
+
+	/* LOG ("GeditSpinnerCache initialising"); */
+
+	priv->hash = g_hash_table_new_full (g_direct_hash,
+					    g_direct_equal,
+					    NULL,
+					    (GDestroyNotify) gedit_spinner_cache_data_free);
+}
+
+static void
+gedit_spinner_cache_finalize (GObject *object)
+{
+	GeditSpinnerCache *cache = GEDIT_SPINNER_CACHE (object); 
+	GeditSpinnerCachePrivate *priv = cache->priv;
+
+	g_hash_table_destroy (priv->hash);
+
+	/* LOG ("GeditSpinnerCache finalised"); */
+
+	G_OBJECT_CLASS (gedit_spinner_cache_parent_class)->finalize (object);
+}
+
+static void
+gedit_spinner_cache_class_init (GeditSpinnerCacheClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	gedit_spinner_cache_parent_class = g_type_class_peek_parent (klass);
+
+	object_class->finalize = gedit_spinner_cache_finalize;
+
+	g_type_class_add_private (object_class, sizeof (GeditSpinnerCachePrivate));
+}
+
+static GeditSpinnerCache *spinner_cache = NULL;
+
+static GeditSpinnerCache *
+gedit_spinner_cache_ref (void)
+{
+	if (spinner_cache == NULL)
+	{
+		GeditSpinnerCache **cache_ptr;
+
+		spinner_cache = g_object_new (GEDIT_TYPE_SPINNER_CACHE, NULL);
+		cache_ptr = &spinner_cache;
+		g_object_add_weak_pointer (G_OBJECT (spinner_cache),
+					   (gpointer *) cache_ptr);
+
+		return spinner_cache;
+	}
+
+	return g_object_ref (spinner_cache);
+}
+
+/* Spinner implementation */
+
+#define SPINNER_TIMEOUT 125 /* ms */
+
+#define GEDIT_SPINNER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GEDIT_TYPE_SPINNER, GeditSpinnerPrivate))
+
+struct _GeditSpinnerPrivate
+{
+	GtkIconTheme       *icon_theme;
+	GeditSpinnerCache  *cache;
+	GtkIconSize         size;
+	GeditSpinnerImages *images;
+	guint               current_image;
+	guint               timeout;
+	guint               timer_task;
+	guint               spinning : 1;
+	guint               need_load : 1;
+};
+
+static void gedit_spinner_class_init	(GeditSpinnerClass *class);
+static void gedit_spinner_init		(GeditSpinner      *spinner);
+
+static GObjectClass *parent_class;
+
+GType
+gedit_spinner_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0))
+	{
+		const GTypeInfo our_info =
+		{
+			sizeof (GeditSpinnerClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc) gedit_spinner_class_init,
+			NULL,
+			NULL, /* class_data */
+			sizeof (GeditSpinner),
+			0, /* n_preallocs */
+			(GInstanceInitFunc) gedit_spinner_init
+		};
+
+		type = g_type_register_static (GTK_TYPE_WIDGET,
+					       "GeditSpinner",
+					       &our_info, 0);
+	}
+
+	return type;
+}
+
+static gboolean
+gedit_spinner_load_images (GeditSpinner *spinner)
+{
+	GeditSpinnerPrivate *priv = spinner->priv;
+
+	if (priv->need_load)
+	{
+		/* START_PROFILER ("gedit_spinner_load_images") */
+
+		priv->images =
+			gedit_spinner_cache_get_images (priv->cache,
+							gtk_widget_get_screen (GTK_WIDGET (spinner)),
+							priv->size);
+
+		/* STOP_PROFILER ("gedit_spinner_load_images") */
+
+		priv->current_image = 0; /* 'rest' icon */
+		priv->need_load = FALSE;
+	}
+
+	return priv->images != NULL;
+}
+
+static void
+gedit_spinner_unload_images (GeditSpinner *spinner)
+{
+	GeditSpinnerPrivate *priv = spinner->priv;
+
+	if (priv->images != NULL)
+	{
+		gedit_spinner_images_unref (priv->images);
+		priv->images = NULL;
+	}
+
+	priv->current_image = 0;
+	priv->need_load = TRUE;
+}
+
+static void
+icon_theme_changed_cb (GtkIconTheme *icon_theme,
+		       GeditSpinner *spinner)
+{
+	gedit_spinner_unload_images (spinner);
+	gtk_widget_queue_resize (GTK_WIDGET (spinner));
+}
+
+static void
+gedit_spinner_init (GeditSpinner *spinner)
+{
+	GeditSpinnerPrivate *priv;
+
+	priv = spinner->priv = GEDIT_SPINNER_GET_PRIVATE (spinner);
+
+	GTK_WIDGET_SET_FLAGS (GTK_WIDGET (spinner), GTK_NO_WINDOW);
+
+	priv->cache = gedit_spinner_cache_ref ();
+	priv->size = GTK_ICON_SIZE_DIALOG;
+	priv->spinning = FALSE;
+	priv->timeout = SPINNER_TIMEOUT;
+	priv->need_load = TRUE;
+}
+
+static int
+gedit_spinner_expose (GtkWidget      *widget,
+		      GdkEventExpose *event)
+{
+	GeditSpinner *spinner = GEDIT_SPINNER (widget);
+	GeditSpinnerPrivate *priv = spinner->priv;
+	GeditSpinnerImages *images;
+	GdkPixbuf *pixbuf;
+	GdkGC *gc;
+	int x_offset, y_offset, width, height;
+	GdkRectangle pix_area, dest;
+
+	if (!GTK_WIDGET_DRAWABLE (spinner))
+	{
+		return FALSE;
+	}
+
+	if (priv->need_load &&
+	    !gedit_spinner_load_images (spinner))
+	{
+		return FALSE;
+	}
+
+	images = priv->images;
+	if (images == NULL)
+	{
+		return FALSE;
+	}
+
+	/* Otherwise |images| will be NULL anyway */
+	g_assert (images->n_animation_pixbufs > 0);
+
+	g_assert (priv->current_image >= 0 &&
+		  priv->current_image < images->n_animation_pixbufs);
+
+	pixbuf = images->animation_pixbufs[priv->current_image];
+
+	g_assert (pixbuf != NULL);
+
+	width = gdk_pixbuf_get_width (pixbuf);
+	height = gdk_pixbuf_get_height (pixbuf);
+
+	/* Compute the offsets for the image centered on our allocation */
+	x_offset = (widget->allocation.width - width) / 2;
+	y_offset = (widget->allocation.height - height) / 2;
+
+	pix_area.x = x_offset + widget->allocation.x;
+	pix_area.y = y_offset + widget->allocation.y;
+	pix_area.width = width;
+	pix_area.height = height;
+
+	if (!gdk_rectangle_intersect (&event->area, &pix_area, &dest))
+	{
+		return FALSE;
+	}
+
+	gc = gdk_gc_new (widget->window);
+	gdk_draw_pixbuf (widget->window, gc, pixbuf,
+			 dest.x - x_offset - widget->allocation.x,
+			 dest.y - y_offset - widget->allocation.y,
+			 dest.x, dest.y,
+			 dest.width, dest.height,
+			 GDK_RGB_DITHER_MAX, 0, 0);
+	g_object_unref (gc);
+
+	return FALSE;
+}
+
+static gboolean
+bump_spinner_frame_cb (GeditSpinner *spinner)
+{
+	GeditSpinnerPrivate *priv = spinner->priv;
+
+	/* This can happen when we've unloaded the images on a theme
+	 * change, but haven't been in the queued size request yet.
+	 * Just skip this update.
+	 */
+	if (priv->images == NULL)
+		return TRUE;
+
+	priv->current_image++;
+	if (priv->current_image >= priv->images->n_animation_pixbufs)
+	{
+		/* the 0th frame is the 'rest' icon */
+		priv->current_image = MIN (1, priv->images->n_animation_pixbufs);
+	}
+
+	gtk_widget_queue_draw (GTK_WIDGET (spinner));
+
+	/* run again */
+	return TRUE;
+}
+
+/**
+ * gedit_spinner_start:
+ * @spinner: a #GeditSpinner
+ *
+ * Start the spinner animation.
+ **/
+void
+gedit_spinner_start (GeditSpinner *spinner)
+{
+	GeditSpinnerPrivate *priv = spinner->priv;
+
+	priv->spinning = TRUE;
+
+	if (GTK_WIDGET_MAPPED (GTK_WIDGET (spinner)) &&
+			       priv->timer_task == 0 &&
+			       gedit_spinner_load_images (spinner))
+	{
+		/* the 0th frame is the 'rest' icon */
+		priv->current_image = MIN (1, priv->images->n_animation_pixbufs);
+
+		priv->timer_task = g_timeout_add_full (G_PRIORITY_LOW,
+						       priv->timeout,
+						       (GSourceFunc) bump_spinner_frame_cb,
+						       spinner,
+						       NULL);
+	}
+}
+
+static void
+gedit_spinner_remove_update_callback (GeditSpinner *spinner)
+{
+	GeditSpinnerPrivate *priv = spinner->priv;
+
+	if (priv->timer_task != 0)
+	{
+		g_source_remove (priv->timer_task);
+		priv->timer_task = 0;
+	}
+}
+
+/**
+ * gedit_spinner_stop:
+ * @spinner: a #GeditSpinner
+ *
+ * Stop the spinner animation.
+ **/
+void
+gedit_spinner_stop (GeditSpinner *spinner)
+{
+	GeditSpinnerPrivate *priv = spinner->priv;
+
+	priv->spinning = FALSE;
+	priv->current_image = 0;
+
+	if (priv->timer_task != 0)
+	{
+		gedit_spinner_remove_update_callback (spinner);
+
+		if (GTK_WIDGET_MAPPED (GTK_WIDGET (spinner)))
+			gtk_widget_queue_draw (GTK_WIDGET (spinner));
+	}
+}
+
+/*
+ * gedit_spinner_set_size:
+ * @spinner: a #GeditSpinner
+ * @size: the size of type %GtkIconSize
+ *
+ * Set the size of the spinner.
+ **/
+void
+gedit_spinner_set_size (GeditSpinner *spinner,
+			GtkIconSize size)
+{
+	if (size == GTK_ICON_SIZE_INVALID)
+	{
+		size = GTK_ICON_SIZE_DIALOG;
+	}
+
+	if (size != spinner->priv->size)
+	{
+		gedit_spinner_unload_images (spinner);
+
+		spinner->priv->size = size;
+
+		gtk_widget_queue_resize (GTK_WIDGET (spinner));
+	}
+}
+
+#if 0
+/*
+* gedit_spinner_set_timeout:
+* @spinner: a #GeditSpinner
+* @timeout: time delay between updates to the spinner.
+*
+* Sets the timeout delay for spinner updates.
+**/
+void
+gedit_spinner_set_timeout (GeditSpinner *spinner,
+			   guint         timeout)
+{
+	GeditSpinnerPrivate *priv = spinner->priv;
+
+	if (timeout != priv->timeout)
+	{
+		gedit_spinner_stop (spinner);
+
+		priv->timeout = timeout;
+
+		if (priv->spinning)
+		{
+			gedit_spinner_start (spinner);
+		}
+	}
+}
+#endif
+
+static void
+gedit_spinner_size_request (GtkWidget *widget,
+			   GtkRequisition *requisition)
+{
+	GeditSpinner *spinner = GEDIT_SPINNER (widget);
+	GeditSpinnerPrivate *priv = spinner->priv;
+
+	if ((priv->need_load &&
+	     !gedit_spinner_load_images (spinner)) ||
+            priv->images == NULL)
+	{
+		requisition->width = requisition->height = 0;
+		gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
+						   priv->size,
+						   &requisition->width,
+					           &requisition->height);
+		return;
+	}
+
+	requisition->width = priv->images->width;
+	requisition->height = priv->images->height;
+
+	/* FIXME fix this hack */
+	/* allocate some extra margin so we don't butt up against toolbar edges */
+	if (priv->size != GTK_ICON_SIZE_MENU)
+	{
+		requisition->width += 2;
+		requisition->height += 2;
+	}
+}
+
+static void
+gedit_spinner_map (GtkWidget *widget)
+{
+	GeditSpinner *spinner = GEDIT_SPINNER (widget);
+	GeditSpinnerPrivate *priv = spinner->priv;
+
+	GTK_WIDGET_CLASS (parent_class)->map (widget);
+
+	if (priv->spinning)
+	{
+		gedit_spinner_start (spinner);
+	}
+}
+
+static void
+gedit_spinner_unmap (GtkWidget *widget)
+{
+	GeditSpinner *spinner = GEDIT_SPINNER (widget);
+
+	gedit_spinner_remove_update_callback (spinner);
+
+	GTK_WIDGET_CLASS (parent_class)->unmap (widget);
+}
+
+static void
+gedit_spinner_dispose (GObject *object)
+{
+	GeditSpinner *spinner = GEDIT_SPINNER (object);
+
+	g_signal_handlers_disconnect_by_func
+			(spinner->priv->icon_theme,
+			 G_CALLBACK (icon_theme_changed_cb), spinner);
+
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gedit_spinner_finalize (GObject *object)
+{
+	GeditSpinner *spinner = GEDIT_SPINNER (object);
+
+	gedit_spinner_remove_update_callback (spinner);
+	gedit_spinner_unload_images (spinner);
+
+	g_object_unref (spinner->priv->cache);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gedit_spinner_screen_changed (GtkWidget *widget,
+			      GdkScreen *old_screen)
+{
+	GeditSpinner *spinner = GEDIT_SPINNER (widget);
+	GeditSpinnerPrivate *priv = spinner->priv;
+	GdkScreen *screen;
+
+	if (GTK_WIDGET_CLASS (parent_class)->screen_changed)
+	{
+		GTK_WIDGET_CLASS (parent_class)->screen_changed (widget, old_screen);
+	}
+
+	screen = gtk_widget_get_screen (widget);
+
+	/* FIXME: this seems to be happening when then spinner is destroyed!? */
+	if (old_screen == screen)
+		return;
+
+	/* We'll get mapped again on the new screen, but not unmapped from
+	 * the old screen, so remove timeout here.
+	 */
+	gedit_spinner_remove_update_callback (spinner);
+
+	gedit_spinner_unload_images (spinner);
+
+	if (old_screen != NULL)
+	{
+		g_signal_handlers_disconnect_by_func
+			(gtk_icon_theme_get_for_screen (old_screen),
+			 G_CALLBACK (icon_theme_changed_cb), spinner);
+	}
+
+	priv->icon_theme = gtk_icon_theme_get_for_screen (screen);
+	g_signal_connect (priv->icon_theme, "changed",
+			  G_CALLBACK (icon_theme_changed_cb), spinner);
+}
+
+static void
+gedit_spinner_class_init (GeditSpinnerClass *class)
+{
+	GObjectClass *object_class =  G_OBJECT_CLASS (class);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+	parent_class = g_type_class_peek_parent (class);
+
+	object_class->dispose = gedit_spinner_dispose;
+	object_class->finalize = gedit_spinner_finalize;
+
+	widget_class->expose_event = gedit_spinner_expose;
+	widget_class->size_request = gedit_spinner_size_request;
+	widget_class->map = gedit_spinner_map;
+	widget_class->unmap = gedit_spinner_unmap;
+	widget_class->screen_changed = gedit_spinner_screen_changed;
+
+	g_type_class_add_private (object_class, sizeof (GeditSpinnerPrivate));
+}
+
+/*
+ * gedit_spinner_new:
+ *
+ * Create a new #GeditSpinner. The spinner is a widget
+ * that gives the user feedback about network status with
+ * an animated image.
+ *
+ * Return Value: the spinner #GtkWidget
+ **/
+GtkWidget *
+gedit_spinner_new (void)
+{
+	return GTK_WIDGET (g_object_new (GEDIT_TYPE_SPINNER, NULL));
+}

Added: trunk/capplet/gedit-spinner.h
==============================================================================
--- (empty file)
+++ trunk/capplet/gedit-spinner.h	Wed Jan 21 16:02:03 2009
@@ -0,0 +1,95 @@
+/*
+ * gedit-spinner.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2005 - Paolo Maggi 
+ * Copyright (C) 2000 - Eazel, Inc. 
+ *
+ * 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.
+ */
+ 
+/*
+ * This widget was originally written by Andy Hertzfeld <andy eazel com> for
+ * Nautilus.
+ *
+ * Modified by the gedit Team, 2005. See the AUTHORS file for a 
+ * list of people on the gedit Team.  
+ * See the ChangeLog files for a list of changes. 
+ *
+ * $Id: gedit-spinner.h 6631 2008-11-29 11:06:49Z pborelli $
+ */
+
+#ifndef __GEDIT_SPINNER_H__
+#define __GEDIT_SPINNER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GEDIT_TYPE_SPINNER		(gedit_spinner_get_type ())
+#define GEDIT_SPINNER(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GEDIT_TYPE_SPINNER, GeditSpinner))
+#define GEDIT_SPINNER_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), GEDIT_TYPE_SPINNER, GeditSpinnerClass))
+#define GEDIT_IS_SPINNER(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GEDIT_TYPE_SPINNER))
+#define GEDIT_IS_SPINNER_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GEDIT_TYPE_SPINNER))
+#define GEDIT_SPINNER_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GEDIT_TYPE_SPINNER, GeditSpinnerClass))
+
+
+/* Private structure type */
+typedef struct _GeditSpinnerPrivate	GeditSpinnerPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GeditSpinner		GeditSpinner;
+
+struct _GeditSpinner
+{
+	GtkWidget parent;
+
+	/*< private >*/
+	GeditSpinnerPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GeditSpinnerClass	GeditSpinnerClass;
+
+struct _GeditSpinnerClass
+{
+	GtkWidgetClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType		gedit_spinner_get_type	(void) G_GNUC_CONST;
+
+GtkWidget      *gedit_spinner_new	(void);
+
+void		gedit_spinner_start	(GeditSpinner *throbber);
+
+void		gedit_spinner_stop	(GeditSpinner *throbber);
+
+void		gedit_spinner_set_size	(GeditSpinner *spinner,
+					 GtkIconSize   size);
+
+G_END_DECLS
+
+#endif /* __GEDIT_SPINNER_H__ */

Added: trunk/capplet/sexy-url-label.c
==============================================================================
--- (empty file)
+++ trunk/capplet/sexy-url-label.c	Wed Jan 21 16:02:03 2009
@@ -0,0 +1,869 @@
+/*
+ * @file libsexy/sexy-url-label.c URL Label
+ *
+ * @Copyright (C) 2005-2006 Christian Hammond
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA  02111-1307, USA.
+ */
+#include <sexy-url-label.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include <stdio.h>
+#include <glib/gi18n.h>
+
+#define SEXY_URL_LABEL_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), SEXY_TYPE_URL_LABEL, \
+								 SexyUrlLabelPrivate))
+
+typedef struct
+{
+	int start;
+	int end;
+	const gchar *url;
+
+} SexyUrlLabelLink;
+
+typedef struct
+{
+	GList *links;
+	GList *urls;
+	SexyUrlLabelLink *active_link;
+	GtkWidget *popup_menu;
+	GdkWindow *event_window;
+
+	int layout_x;
+	int layout_y;
+
+	size_t wrap_width;
+
+	GString *temp_markup_result;
+
+} SexyUrlLabelPrivate;
+
+/*
+ * NOTE: This *MUST* match the LabelWrapWidth struct in gtklabel.c.
+ */
+typedef struct
+{
+	gint width;
+	PangoFontDescription *font_desc;
+
+} LabelWrapWidth;
+
+enum
+{
+	URL_ACTIVATED,
+	LAST_SIGNAL
+};
+
+static void sexy_url_label_finalize(GObject *obj);
+static void sexy_url_label_realize(GtkWidget *widget);
+static void sexy_url_label_unrealize(GtkWidget *widget);
+static void sexy_url_label_map(GtkWidget *widget);
+static void sexy_url_label_unmap(GtkWidget *widget);
+static void sexy_url_label_size_allocate(GtkWidget *widget,
+										 GtkAllocation *allocation);
+static gboolean sexy_url_label_motion_notify_event(GtkWidget *widget,
+												   GdkEventMotion *event);
+static gboolean sexy_url_label_leave_notify_event(GtkWidget *widget,
+												  GdkEventCrossing *event);
+static gboolean sexy_url_label_button_press_event(GtkWidget *widget,
+												  GdkEventButton *event);
+
+static void open_link_activate_cb(GtkMenuItem *menu_item,
+								  SexyUrlLabel *url_label);
+static void copy_link_activate_cb(GtkMenuItem *menu_item,
+								  SexyUrlLabel *url_label);
+
+static void sexy_url_label_clear_links(SexyUrlLabel *url_label);
+static void sexy_url_label_clear_urls(SexyUrlLabel *url_label);
+static void sexy_url_label_rescan_label(SexyUrlLabel *url_label);
+
+static GtkLabelClass *parent_class = NULL;
+static guint signals[LAST_SIGNAL] = {0};
+
+G_DEFINE_TYPE(SexyUrlLabel, sexy_url_label, GTK_TYPE_LABEL);
+
+static void
+sexy_url_label_class_init(SexyUrlLabelClass *klass)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS(klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+	parent_class = g_type_class_peek_parent(klass);
+
+	object_class->finalize = sexy_url_label_finalize;
+
+	widget_class->realize             = sexy_url_label_realize;
+	widget_class->unrealize           = sexy_url_label_unrealize;
+	widget_class->map                 = sexy_url_label_map;
+	widget_class->unmap               = sexy_url_label_unmap;
+	widget_class->size_allocate       = sexy_url_label_size_allocate;
+	widget_class->motion_notify_event = sexy_url_label_motion_notify_event;
+	widget_class->leave_notify_event  = sexy_url_label_leave_notify_event;
+	widget_class->button_press_event  = sexy_url_label_button_press_event;
+
+	g_type_class_add_private(klass, sizeof(SexyUrlLabelPrivate));
+
+	/**
+	 * SexyUrlLabel::url-activated:
+	 * @url_label: The label on which the signal was emitted.
+	 * @url: The URL which was activated.
+	 *
+	 * The ::url-activated signal is emitted when a URL in the label was
+	 * clicked.
+	 */
+	signals[URL_ACTIVATED] =
+		g_signal_new("url_activated",
+					 G_TYPE_FROM_CLASS(object_class),
+					 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+					 G_STRUCT_OFFSET(SexyUrlLabelClass, url_activated),
+					 NULL, NULL,
+					 g_cclosure_marshal_VOID__STRING,
+					 G_TYPE_NONE, 1,
+					 G_TYPE_STRING);
+}
+
+static void
+selectable_changed_cb(SexyUrlLabel *url_label)
+{
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	if (priv->event_window != NULL)
+	{
+		GdkCursor *cursor = NULL;
+
+		if (gtk_label_get_selectable(GTK_LABEL(url_label)) &&
+			priv->active_link == NULL)
+			cursor = gdk_cursor_new_for_display(
+				gtk_widget_get_display(GTK_WIDGET(url_label)), GDK_XTERM);
+		gdk_window_set_cursor(priv->event_window, cursor);
+
+		if (cursor)
+			gdk_cursor_unref(cursor);
+
+		/*
+		 * GtkLabel recreates its event window when the selectable property
+		 * changes, which will cover ours.
+		 */
+		gdk_window_raise(priv->event_window);
+	}
+}
+
+static void
+sexy_url_label_init(SexyUrlLabel *url_label)
+{
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+	GtkWidget *item;
+	GtkWidget *image;
+
+	priv->links        = NULL;
+	priv->active_link  = NULL;
+	priv->event_window = NULL;
+
+	g_signal_connect(G_OBJECT(url_label), "notify::selectable",
+					 G_CALLBACK(selectable_changed_cb), NULL);
+
+	priv->popup_menu = gtk_menu_new();
+
+	/* Open Link */
+	item = gtk_image_menu_item_new_with_mnemonic(_("_Send address by email"));
+	gtk_widget_show(item);
+	gtk_menu_shell_append(GTK_MENU_SHELL(priv->popup_menu), item);
+
+	g_signal_connect(G_OBJECT(item), "activate",
+					 G_CALLBACK(open_link_activate_cb), url_label);
+
+	image = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU);
+	gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
+	gtk_widget_show(image);
+
+	/* Copy Link Address */
+	item = gtk_image_menu_item_new_with_mnemonic(_("_Copy address to clipboard"));
+	gtk_widget_show(item);
+	gtk_menu_shell_append(GTK_MENU_SHELL(priv->popup_menu), item);
+
+	g_signal_connect(G_OBJECT(item), "activate",
+					 G_CALLBACK(copy_link_activate_cb), url_label);
+
+	image = gtk_image_new_from_stock(GTK_STOCK_COPY, GTK_ICON_SIZE_MENU);
+	gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
+	gtk_widget_show(image);
+}
+
+static void
+sexy_url_label_finalize(GObject *obj)
+{
+	SexyUrlLabel *url_label = SEXY_URL_LABEL(obj);
+
+	sexy_url_label_clear_links(url_label);
+	sexy_url_label_clear_urls(url_label);
+
+	if (G_OBJECT_CLASS(parent_class)->finalize != NULL)
+		G_OBJECT_CLASS(parent_class)->finalize(obj);
+}
+
+static gboolean
+sexy_url_label_motion_notify_event(GtkWidget *widget, GdkEventMotion *event)
+{
+	SexyUrlLabel *url_label = (SexyUrlLabel *)widget;
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+	PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(url_label));
+	GdkModifierType state;
+	gboolean found = FALSE;
+	GList *l;
+	int index, trailing;
+	int x, y;
+	SexyUrlLabelLink *link = NULL;
+
+	if (event->is_hint)
+		gdk_window_get_pointer(event->window, &x, &y, &state);
+	else
+	{
+		x = event->x;
+		y = event->y;
+		state = event->state;
+	}
+
+	if (pango_layout_xy_to_index(layout,
+								 (x - priv->layout_x) * PANGO_SCALE,
+								 (y - priv->layout_y) * PANGO_SCALE,
+								 &index, &trailing))
+	{
+		for (l = priv->links; l != NULL; l = l->next)
+		{
+			link = (SexyUrlLabelLink *)l->data;
+
+			if (index >= link->start && index <= link->end)
+			{
+				found = TRUE;
+				break;
+			}
+		}
+	}
+
+	if (found)
+	{
+		if (priv->active_link == NULL)
+		{
+			GdkCursor *cursor;
+
+			cursor = gdk_cursor_new_for_display(
+				gtk_widget_get_display(widget), GDK_HAND2);
+			gdk_window_set_cursor(priv->event_window, cursor);
+			gdk_cursor_unref(cursor);
+
+			priv->active_link = link;
+		}
+	}
+	else
+	{
+		if (priv->active_link != NULL)
+		{
+			if (gtk_label_get_selectable(GTK_LABEL(url_label)))
+			{
+				GdkCursor *cursor;
+
+				cursor = gdk_cursor_new_for_display(
+					gtk_widget_get_display(widget), GDK_XTERM);
+				gdk_window_set_cursor(priv->event_window, cursor);
+				gdk_cursor_unref(cursor);
+			}
+			else
+				gdk_window_set_cursor(priv->event_window, NULL);
+
+			priv->active_link = NULL;
+		}
+	}
+
+	/*
+	 * Another beautiful libsexy hack. This one prevents the callback
+	 * from going "Oh boy, they clicked and dragged! Let's select more of
+	 * the text!"
+	 */
+	if (priv->active_link != NULL)
+		event->state = 0;
+
+	GTK_WIDGET_CLASS(parent_class)->motion_notify_event(widget, event);
+
+	return FALSE;
+}
+
+static gboolean
+sexy_url_label_leave_notify_event(GtkWidget *widget, GdkEventCrossing *event)
+{
+	SexyUrlLabel *url_label = (SexyUrlLabel *)widget;
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	if (GTK_WIDGET_CLASS(parent_class)->leave_notify_event != NULL)
+		GTK_WIDGET_CLASS(parent_class)->leave_notify_event(widget, event);
+
+	if (event->mode == GDK_CROSSING_NORMAL)
+	{
+		GdkCursor *cursor = NULL;
+		if (gtk_label_get_selectable(GTK_LABEL(widget)))
+			cursor = gdk_cursor_new_for_display(
+				gtk_widget_get_display(widget), GDK_XTERM);
+		gdk_window_set_cursor(priv->event_window, cursor);
+		if (cursor)
+			gdk_cursor_unref(cursor);
+		priv->active_link = NULL;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+sexy_url_label_button_press_event(GtkWidget *widget, GdkEventButton *event)
+{
+	SexyUrlLabel *url_label = (SexyUrlLabel *)widget;
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	if (priv->active_link == NULL)
+	{
+		return GTK_WIDGET_CLASS(parent_class)->button_press_event(widget,
+																  event);
+	}
+
+	if (event->button == 1)
+	{
+		g_signal_emit(url_label, signals[URL_ACTIVATED], 0,
+					  priv->active_link->url);
+	}
+	else if (event->button == 3)
+	{
+		gtk_menu_popup(GTK_MENU(priv->popup_menu), NULL, NULL, NULL, NULL,
+					   event->button, event->time);
+	}
+
+	return TRUE;
+}
+
+static void
+update_wrap_width(SexyUrlLabel *url_label, size_t wrap_width)
+{
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+	LabelWrapWidth *wrap_width_data;
+	GtkStyle *style;
+
+	if (wrap_width == 0 || !gtk_label_get_line_wrap(GTK_LABEL(url_label)))
+		return;
+
+#if 0
+	pango_layout_set_width(gtk_label_get_layout(GTK_LABEL(url_label)),
+						   wrap_width * PANGO_SCALE);
+#endif
+	style = GTK_WIDGET(url_label)->style;
+	wrap_width_data = g_object_get_data(G_OBJECT(style),
+										"gtk-label-wrap-width");
+
+	if (wrap_width_data != NULL &&
+		wrap_width_data->width != wrap_width * PANGO_SCALE)
+	{
+		wrap_width_data->width = wrap_width * PANGO_SCALE;
+		priv->wrap_width = wrap_width;
+		g_object_unref(GTK_LABEL(url_label)->layout);
+		GTK_LABEL(url_label)->layout = NULL;
+		gtk_label_get_layout(GTK_LABEL(url_label));
+		gtk_widget_queue_resize(GTK_WIDGET(url_label));
+	}
+}
+
+static void
+sexy_url_label_realize(GtkWidget *widget)
+{
+	SexyUrlLabel *url_label = (SexyUrlLabel *)widget;
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+	GdkWindowAttr attributes;
+	gint attributes_mask;
+
+	GTK_WIDGET_CLASS(parent_class)->realize(widget);
+
+	attributes.window_type = GDK_WINDOW_CHILD;
+	attributes.x = widget->allocation.x;
+	attributes.y = widget->allocation.y;
+	attributes.width = widget->allocation.width;
+	attributes.height = widget->allocation.height;
+	attributes.window_type = GDK_WINDOW_CHILD;
+	attributes.wclass = GDK_INPUT_ONLY;
+	attributes.event_mask = gtk_widget_get_events(widget);
+	attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
+							  GDK_BUTTON_RELEASE_MASK |
+							  GDK_POINTER_MOTION_MASK |
+							  GDK_POINTER_MOTION_HINT_MASK |
+							  GDK_LEAVE_NOTIFY_MASK |
+							  GDK_LEAVE_NOTIFY_MASK);
+	attributes_mask = GDK_WA_X | GDK_WA_Y;
+
+	if (gtk_label_get_selectable(GTK_LABEL(widget))) {
+		attributes.cursor = gdk_cursor_new_for_display(
+			gtk_widget_get_display(widget), GDK_XTERM);
+		attributes_mask |= GDK_WA_CURSOR;
+	}
+
+	priv->event_window =
+		gdk_window_new(gtk_widget_get_parent_window(widget), &attributes,
+					   attributes_mask);
+	gdk_window_set_user_data(priv->event_window, widget);
+
+	if (attributes_mask & GDK_WA_CURSOR)
+		gdk_cursor_unref (attributes.cursor);
+}
+
+static void
+sexy_url_label_unrealize(GtkWidget *widget)
+{
+	SexyUrlLabel *url_label = (SexyUrlLabel *)widget;
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	if (priv->event_window != NULL)
+	{
+		gdk_window_set_user_data(priv->event_window, NULL);
+		gdk_window_destroy(priv->event_window);
+		priv->event_window = NULL;
+	}
+
+	GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
+}
+
+static void
+sexy_url_label_map(GtkWidget *widget)
+{
+	SexyUrlLabel *url_label = (SexyUrlLabel *)widget;
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	GTK_WIDGET_CLASS(parent_class)->map(widget);
+
+	if (priv->event_window != NULL)
+		gdk_window_show(priv->event_window);
+}
+
+static void
+sexy_url_label_unmap(GtkWidget *widget)
+{
+	SexyUrlLabel *url_label = (SexyUrlLabel *)widget;
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	if (priv->event_window != NULL)
+		gdk_window_hide(priv->event_window);
+
+	GTK_WIDGET_CLASS(parent_class)->unmap(widget);
+}
+
+static void
+sexy_url_label_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+{
+	SexyUrlLabel *url_label = (SexyUrlLabel *)widget;
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+#if 0
+	{
+		LabelWrapWidth *wrap_width_data;
+		GtkStyle *style;
+		style = GTK_WIDGET(url_label)->style;
+		wrap_width_data = g_object_get_data(G_OBJECT(style),
+											"gtk-label-wrap-width");
+		if (wrap_width_data != NULL)
+			printf("wrap width = %d\n", wrap_width_data->width / PANGO_SCALE);
+	}
+#endif
+	update_wrap_width(url_label, allocation->width);
+	GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
+	pango_layout_set_width(gtk_label_get_layout(GTK_LABEL(url_label)),
+						   allocation->width * PANGO_SCALE);
+
+	if (GTK_WIDGET_REALIZED(widget))
+	{
+		gdk_window_move_resize(priv->event_window,
+							   allocation->x, allocation->y,
+							   allocation->width, allocation->height);
+	}
+
+	sexy_url_label_rescan_label(url_label);
+}
+
+static void
+open_link_activate_cb(GtkMenuItem *menu_item, SexyUrlLabel *url_label)
+{
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	if (priv->active_link == NULL)
+		return;
+
+	g_signal_emit(url_label, signals[URL_ACTIVATED], 0, priv->active_link->url);
+}
+
+static void
+copy_link_activate_cb(GtkMenuItem *menu_item, SexyUrlLabel *url_label)
+{
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+	GtkClipboard *clipboard;
+
+	if (priv->active_link == NULL)
+		return;
+
+	clipboard = gtk_widget_get_clipboard(GTK_WIDGET(url_label),
+										 GDK_SELECTION_CLIPBOARD);
+
+	gtk_clipboard_set_text(clipboard, priv->active_link->url,
+						   strlen(priv->active_link->url));
+}
+
+/**
+ * sexy_url_label_new
+ *
+ * Creates a new SexyUrlLabel widget.
+ *
+ * Returns: a new #SexyUrlLabel.
+ */
+GtkWidget *
+sexy_url_label_new(void)
+{
+	return g_object_new(SEXY_TYPE_URL_LABEL, NULL);
+}
+
+static void
+sexy_url_label_clear_links(SexyUrlLabel *url_label)
+{
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	if (priv->links == NULL)
+		return;
+
+	g_list_foreach(priv->links, (GFunc)g_free, NULL);
+	g_list_free(priv->links);
+	priv->links = NULL;
+}
+
+static void
+sexy_url_label_clear_urls(SexyUrlLabel *url_label)
+{
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	if (priv->urls == NULL)
+		return;
+
+	g_list_foreach(priv->urls, (GFunc)g_free, NULL);
+	g_list_free(priv->urls);
+	priv->urls = NULL;
+}
+
+static void
+sexy_url_label_rescan_label(SexyUrlLabel *url_label)
+{
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+	PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(url_label));
+	PangoAttrList *list = pango_layout_get_attributes(layout);
+	PangoAttrIterator *iter;
+	GList *url_list;
+
+	sexy_url_label_clear_links(url_label);
+
+	if (list == NULL)
+		return;
+
+	iter = pango_attr_list_get_iterator(list);
+
+	gtk_label_get_layout_offsets(GTK_LABEL(url_label),
+								 &priv->layout_x, &priv->layout_y);
+
+	priv->layout_x -= GTK_WIDGET(url_label)->allocation.x;
+	priv->layout_y -= GTK_WIDGET(url_label)->allocation.y;
+
+	url_list = priv->urls;
+
+	do
+	{
+		PangoAttribute *underline;
+		PangoAttribute *color;
+
+		underline = pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE);
+		color     = pango_attr_iterator_get(iter, PANGO_ATTR_FOREGROUND);
+
+		if (underline != NULL && color != NULL)
+		{
+			gint start, end;
+			PangoRectangle start_pos;
+			PangoRectangle end_pos;
+			SexyUrlLabelLink *link;
+
+			pango_attr_iterator_range(iter, &start, &end);
+			pango_layout_index_to_pos(layout, start, &start_pos);
+			pango_layout_index_to_pos(layout, end,   &end_pos);
+
+			link = g_new0(SexyUrlLabelLink, 1);
+			link->start = start;
+			link->end   = end;
+			link->url   = (const gchar *)url_list->data;
+			priv->links = g_list_append(priv->links, link);
+
+			url_list = url_list->next;
+		}
+
+	} while (pango_attr_iterator_next(iter));
+
+	pango_attr_iterator_destroy (iter);
+}
+
+static void
+start_element_handler(GMarkupParseContext *context,
+					  const gchar *element_name,
+					  const gchar **attribute_names,
+					  const gchar **attribute_values,
+					  gpointer user_data,
+					  GError **error)
+{
+	SexyUrlLabel *url_label   = SEXY_URL_LABEL(user_data);
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	if (!strcmp(element_name, "a"))
+	{
+		const gchar *url = NULL;
+		int line_number;
+		int char_number;
+		int i;
+
+		g_markup_parse_context_get_position(context, &line_number,
+											&char_number);
+
+		for (i = 0; attribute_names[i] != NULL; i++)
+		{
+			const gchar *attr = attribute_names[i];
+
+			if (!strcmp(attr, "href"))
+			{
+				if (url != NULL)
+				{
+					g_set_error(error, G_MARKUP_ERROR,
+								G_MARKUP_ERROR_INVALID_CONTENT,
+								"Attribute '%s' occurs twice on <a> tag "
+								"on line %d char %d, may only occur once",
+								attribute_names[i], line_number, char_number);
+					return;
+				}
+
+				url = attribute_values[i];
+			}
+			else
+			{
+				g_set_error(error, G_MARKUP_ERROR,
+							G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
+							"Attribute '%s' is not allowed on the <a> tag "
+							"on line %d char %d",
+							attribute_names[i], line_number, char_number);
+				return;
+			}
+		}
+
+		if (url == NULL)
+		{
+			g_set_error(error, G_MARKUP_ERROR,
+						G_MARKUP_ERROR_INVALID_CONTENT,
+						"Attribute 'href' was missing on the <a> tag "
+						"on line %d char %d",
+						line_number, char_number);
+			return;
+		}
+
+		g_string_append(priv->temp_markup_result,
+						"<span color=\"blue\" underline=\"single\">");
+
+		priv->urls = g_list_append(priv->urls, g_strdup(url));
+	}
+	else
+	{
+		int i;
+
+		g_string_append_printf(priv->temp_markup_result,
+							   "<%s", element_name);
+
+		for (i = 0; attribute_names[i] != NULL; i++)
+		{
+			const gchar *attr  = attribute_names[i];
+			const gchar *value = attribute_values[i];
+
+			g_string_append_printf(priv->temp_markup_result,
+								   " %s=\"%s\"",
+								   attr, value);
+		}
+
+		g_string_append_c(priv->temp_markup_result, '>');
+	}
+}
+
+static void
+end_element_handler(GMarkupParseContext *context,
+					const gchar *element_name,
+					gpointer user_data,
+					GError **error)
+{
+	SexyUrlLabel *url_label   = SEXY_URL_LABEL(user_data);
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	if (!strcmp(element_name, "a"))
+	{
+		g_string_append(priv->temp_markup_result, "</span>");
+	}
+	else
+	{
+		g_string_append_printf(priv->temp_markup_result,
+							   "</%s>", element_name);
+	}
+}
+
+static void
+text_handler(GMarkupParseContext *context,
+			 const gchar *text,
+			 gsize text_len,
+			 gpointer user_data,
+			 GError **error)
+{
+	SexyUrlLabel *url_label   = SEXY_URL_LABEL(user_data);
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	gchar *newtext = g_markup_escape_text(text, text_len);
+	g_string_append_len(priv->temp_markup_result, newtext, strlen (newtext));
+	g_free (newtext);
+}
+
+static const GMarkupParser markup_parser =
+{
+	start_element_handler,
+	end_element_handler,
+	text_handler,
+	NULL,
+	NULL
+};
+
+static gboolean
+xml_isspace(char c)
+{
+	return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
+}
+
+static gboolean
+parse_custom_markup(SexyUrlLabel *url_label, const gchar *markup,
+					gchar **ret_markup)
+{
+	GMarkupParseContext *context = NULL;
+	SexyUrlLabelPrivate *priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+	GError *error = NULL;
+	const gchar *p, *end;
+	gboolean needs_root = TRUE;
+	gsize length;
+
+	g_return_val_if_fail(markup     != NULL, FALSE);
+	g_return_val_if_fail(ret_markup != NULL, FALSE);
+
+	priv->temp_markup_result = g_string_new(NULL);
+
+	length = strlen(markup);
+	p = markup;
+	end = markup + length;
+
+	while (p != end && xml_isspace(*p))
+		p++;
+
+	if (end - p >= 8 && strncmp(p, "<markup>", 8) == 0)
+		needs_root = FALSE;
+
+	context = g_markup_parse_context_new(&markup_parser, 0, url_label, NULL);
+
+	if (needs_root)
+	{
+		if (!g_markup_parse_context_parse(context, "<markup>", -1, &error))
+			goto failed;
+	}
+
+	if (!g_markup_parse_context_parse(context, markup, strlen(markup), &error))
+		goto failed;
+
+	if (needs_root)
+	{
+		if (!g_markup_parse_context_parse(context, "</markup>", -1, &error))
+			goto failed;
+	}
+
+	if (!g_markup_parse_context_end_parse(context, &error))
+		goto failed;
+
+	if (error != NULL)
+		g_error_free(error);
+
+	g_markup_parse_context_free(context);
+
+	*ret_markup = g_string_free(priv->temp_markup_result, FALSE);
+	priv->temp_markup_result = NULL;
+
+	return TRUE;
+
+failed:
+	fprintf(stderr, "Unable to parse markup: %s\n", error->message);
+	g_error_free(error);
+
+	g_string_free(priv->temp_markup_result, TRUE);
+	priv->temp_markup_result = NULL;
+
+	g_markup_parse_context_free(context);
+	return FALSE;
+}
+
+/**
+ * sexy_url_label_set_markup
+ * @url_label: A #SexyUrlLabel.
+ * @markup: a markup string (see <link linkend="PangoMarkupFormat">Pango markup format</link>)
+ *
+ * Parses @markup which is marked up with the <link
+ * linkend="PangoMarkupFormat">Pango text markup language</link> as well as
+ * HTML-style hyperlinks, setting the label's text and attribute list based
+ * on the parse results.  If the @markup is external data, you may need to
+ * escape it with g_markup_escape_text() or g_markup_printf_escaped()
+ */
+void
+sexy_url_label_set_markup(SexyUrlLabel *url_label, const gchar *markup)
+{
+	SexyUrlLabelPrivate *priv;
+	gchar *new_markup;
+
+	g_return_if_fail(SEXY_IS_URL_LABEL(url_label));
+
+	priv = SEXY_URL_LABEL_GET_PRIVATE(url_label);
+
+	sexy_url_label_clear_links(url_label);
+	sexy_url_label_clear_urls(url_label);
+
+	if (markup == NULL || *markup == '\0')
+	{
+		gtk_label_set_markup(GTK_LABEL(url_label), "");
+		return;
+	}
+
+	if (parse_custom_markup(url_label, markup, &new_markup))
+	{
+		gtk_label_set_markup(GTK_LABEL(url_label), new_markup);
+		g_free(new_markup);
+	}
+	else
+	{
+		gtk_label_set_markup(GTK_LABEL(url_label), "");
+	}
+
+	sexy_url_label_rescan_label(url_label);
+
+	update_wrap_width(url_label, priv->wrap_width);
+}
+
+// vim:ts=4 sw=4

Added: trunk/capplet/sexy-url-label.h
==============================================================================
--- (empty file)
+++ trunk/capplet/sexy-url-label.h	Wed Jan 21 16:02:03 2009
@@ -0,0 +1,73 @@
+/*
+ * @file libsexy/sexy-url-label.h URL Label
+ *
+ * @Copyright (C) 2005-2006 Christian Hammond
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA  02111-1307, USA.
+ */
+#ifndef _SEXY_URL_LABEL_H_
+#define _SEXY_URL_LABEL_H_
+
+typedef struct _SexyUrlLabel      SexyUrlLabel;
+typedef struct _SexyUrlLabelClass SexyUrlLabelClass;
+
+#include <gtk/gtklabel.h>
+
+#define SEXY_TYPE_URL_LABEL (sexy_url_label_get_type())
+#define SEXY_URL_LABEL(obj) \
+		(G_TYPE_CHECK_INSTANCE_CAST((obj), SEXY_TYPE_URL_LABEL, SexyUrlLabel))
+#define SEXY_URL_LABEL_CLASS(klass) \
+		(G_TYPE_CHECK_CLASS_CAST((klass), SEXY_TYPE_URL_LABEL, SexyUrlLabelClass))
+#define SEXY_IS_URL_LABEL(obj) \
+		(G_TYPE_CHECK_INSTANCE_TYPE((obj), SEXY_TYPE_URL_LABEL))
+#define SEXY_IS_URL_LABEL_CLASS(klass) \
+		(G_TYPE_CHECK_CLASS_TYPE((klass), SEXY_TYPE_URL_LABEL))
+#define SEXY_URL_LABEL_GET_CLASS(obj) \
+		(G_TYPE_INSTANCE_GET_CLASS ((obj), SEXY_TYPE_URL_LABEL, SexyUrlLabelClass))
+
+struct _SexyUrlLabel
+{
+	GtkLabel parent_object;
+
+	void (*gtk_reserved1)(void);
+	void (*gtk_reserved2)(void);
+	void (*gtk_reserved3)(void);
+	void (*gtk_reserved4)(void);
+};
+
+struct _SexyUrlLabelClass
+{
+	GtkLabelClass parent_class;
+
+	/* Signals */
+	void (*url_activated)(SexyUrlLabel *url_label, const gchar *url);
+
+	void (*gtk_reserved1)(void);
+	void (*gtk_reserved2)(void);
+	void (*gtk_reserved3)(void);
+	void (*gtk_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType sexy_url_label_get_type(void);
+
+GtkWidget *sexy_url_label_new(void);
+void sexy_url_label_set_markup(SexyUrlLabel *url_label, const gchar *markup);
+
+G_END_DECLS
+
+#endif /* _SEXY_URL_LABEL_H_ */

Added: trunk/capplet/vino-message-box.c
==============================================================================
--- (empty file)
+++ trunk/capplet/vino-message-box.c	Wed Jan 21 16:02:03 2009
@@ -0,0 +1,218 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * vino-message-box.c
+ * Copyright (C) Jonh Wendell 2009 <wendell bani com br>
+ * 
+ * vino-message-box.c 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 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * vino-message-box.c 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+#include <sexy-url-label.h>
+#include "vino-message-box.h"
+#include "gedit-spinner.h"
+
+struct _VinoMessageBoxPrivate
+{
+  GtkWidget *main_hbox;
+  GtkWidget *label;
+  GtkWidget *image;
+  gboolean  changing_style;
+};
+
+G_DEFINE_TYPE (VinoMessageBox, vino_message_box, GTK_TYPE_HBOX);
+
+static gboolean
+paint_message_area (GtkWidget      *widget,
+		            GdkEventExpose *event,
+		            gpointer        user_data)
+{
+	gtk_paint_flat_box (widget->style,
+			    widget->window,
+			    GTK_STATE_NORMAL,
+			    GTK_SHADOW_OUT,
+			    NULL,
+			    widget,
+			    "tooltip",
+			    widget->allocation.x + 1,
+			    widget->allocation.y + 1,
+			    widget->allocation.width - 2,
+			    widget->allocation.height - 2);
+
+	return FALSE;
+}
+
+static void
+style_set (GtkWidget        *widget,
+	       GtkStyle         *prev_style,
+	       VinoMessageBox   *box)
+{
+	GtkWidget *window;
+	GtkStyle *style;
+
+	if (box->priv->changing_style)
+		return;
+
+	/* This is a hack needed to use the tooltip background color */
+	window = gtk_window_new (GTK_WINDOW_POPUP);
+	gtk_widget_set_name (window, "gtk-tooltip");
+	gtk_widget_ensure_style (window);
+	style = gtk_widget_get_style (window);
+
+	box->priv->changing_style = TRUE;
+	gtk_widget_set_style (GTK_WIDGET (box), style);
+	box->priv->changing_style = FALSE;
+
+	gtk_widget_destroy (window);
+
+	gtk_widget_queue_draw (GTK_WIDGET (box));
+}
+
+static void
+url_activated_cb(GtkWidget *url_label, const gchar *url)
+{
+  GError *error;
+  GdkScreen *screen;
+  gchar *mailto;
+
+  error   = NULL;
+  screen  = gtk_widget_get_screen (url_label);
+  mailto  = g_strdup_printf ("mailto:?Body=%s";, url);
+
+  if (!gtk_show_uri (screen, mailto, GDK_CURRENT_TIME, &error))
+    {
+      GtkWidget *message_dialog, *parent;
+
+      parent = gtk_widget_get_toplevel (GTK_WIDGET (url_label));
+      if (!GTK_IS_WINDOW (parent))
+        parent = NULL;
+      message_dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
+					       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+					       GTK_MESSAGE_ERROR,
+					       GTK_BUTTONS_CLOSE,
+					       _("There was an error showing the URL \"%s\""),
+					       url);
+      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
+						"%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);
+    }
+
+  g_free (mailto);
+}
+
+static void
+vino_message_box_init (VinoMessageBox *box)
+{
+  box->priv = G_TYPE_INSTANCE_GET_PRIVATE (box, VINO_TYPE_MESSAGE_BOX, VinoMessageBoxPrivate);
+
+  box->priv->main_hbox = gtk_hbox_new (FALSE, 0);
+  box->priv->image = NULL;
+
+  box->priv->label = sexy_url_label_new ();
+  gtk_misc_set_alignment (GTK_MISC (box->priv->label), 0.0, 0.0);
+  gtk_label_set_line_wrap (GTK_LABEL (box->priv->label), TRUE);
+  gtk_label_set_selectable (GTK_LABEL (box->priv->label), TRUE);
+  g_signal_connect (box->priv->label,
+                    "url_activated",
+                    G_CALLBACK (url_activated_cb),
+                    NULL);
+
+  gtk_container_set_border_width (GTK_CONTAINER (box->priv->main_hbox), 4);
+  gtk_widget_set_app_paintable (GTK_WIDGET (box), TRUE);
+
+  g_signal_connect (box,
+			        "expose-event",
+			        G_CALLBACK (paint_message_area),
+			        NULL);
+
+  g_signal_connect (box->priv->main_hbox,
+			        "style-set",
+			        G_CALLBACK (style_set),
+			        box);
+
+  gtk_box_pack_start (GTK_BOX (box), box->priv->main_hbox, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (box->priv->main_hbox), box->priv->label, TRUE, TRUE, 2);
+  gtk_widget_show_all (box->priv->main_hbox);
+}
+
+static void
+vino_message_box_finalize (GObject *object)
+{
+	/* TODO: Add deinitalization code here */
+
+	G_OBJECT_CLASS (vino_message_box_parent_class)->finalize (object);
+}
+
+static void
+vino_message_box_class_init (VinoMessageBoxClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = vino_message_box_finalize;
+	g_type_class_add_private (object_class, sizeof(VinoMessageBoxPrivate));
+}
+
+GtkWidget *
+vino_message_box_new (void)
+{
+	return GTK_WIDGET (g_object_new (VINO_TYPE_MESSAGE_BOX, NULL));
+}
+
+void
+vino_message_box_set_label (VinoMessageBox *box, const gchar *label)
+{
+  g_return_if_fail (VINO_IS_MESSAGE_BOX (box));
+
+  sexy_url_label_set_markup (SEXY_URL_LABEL (box->priv->label), label);
+}
+
+void
+vino_message_box_show_image (VinoMessageBox *box)
+{
+  g_return_if_fail (VINO_IS_MESSAGE_BOX (box));
+
+  if (box->priv->image)
+    {
+      gtk_widget_destroy (box->priv->image);
+      box->priv->image = NULL;
+    }
+
+
+  box->priv->image = gedit_spinner_new ();
+  gedit_spinner_set_size (GEDIT_SPINNER (box->priv->image), GTK_ICON_SIZE_MENU);
+  gedit_spinner_start (GEDIT_SPINNER (box->priv->image));
+
+  gtk_box_pack_start (GTK_BOX (box->priv->main_hbox), box->priv->image, FALSE, FALSE, 2);
+  gtk_box_reorder_child (GTK_BOX (box->priv->main_hbox), box->priv->image, 0);
+  gtk_widget_show (box->priv->image);
+}
+
+void
+vino_message_box_hide_image (VinoMessageBox *box)
+{
+  g_return_if_fail (VINO_IS_MESSAGE_BOX (box));
+
+  if (box->priv->image)
+    gtk_widget_destroy (box->priv->image);
+  box->priv->image = NULL;
+}
+

Added: trunk/capplet/vino-message-box.h
==============================================================================
--- (empty file)
+++ trunk/capplet/vino-message-box.h	Wed Jan 21 16:02:03 2009
@@ -0,0 +1,59 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * vino-message-box.c
+ * Copyright (C) Jonh Wendell 2009 <wendell bani com br>
+ * 
+ * vino-message-box.c 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 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * vino-message-box.c 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _VINO_MESSAGE_BOX_H_
+#define _VINO_MESSAGE_BOX_H_
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define VINO_TYPE_MESSAGE_BOX             (vino_message_box_get_type ())
+#define VINO_MESSAGE_BOX(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), VINO_TYPE_MESSAGE_BOX, VinoMessageBox))
+#define VINO_MESSAGE_BOX_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), VINO_TYPE_MESSAGE_BOX, VinoMessageBoxClass))
+#define VINO_IS_MESSAGE_BOX(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VINO_TYPE_MESSAGE_BOX))
+#define VINO_IS_MESSAGE_BOX_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), VINO_TYPE_MESSAGE_BOX))
+#define VINO_MESSAGE_BOX_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), VINO_TYPE_MESSAGE_BOX, VinoMessageBoxClass))
+
+typedef struct _VinoMessageBoxClass VinoMessageBoxClass;
+typedef struct _VinoMessageBox VinoMessageBox;
+typedef struct _VinoMessageBoxPrivate VinoMessageBoxPrivate;
+
+struct _VinoMessageBoxClass
+{
+  GtkHBoxClass parent_class;
+};
+
+struct _VinoMessageBox
+{
+  GtkHBox parent_instance;
+  VinoMessageBoxPrivate *priv;
+};
+
+GType vino_message_box_get_type (void) G_GNUC_CONST;
+
+GtkWidget	*vino_message_box_new (void);
+
+void		vino_message_box_set_label  (VinoMessageBox *box, const gchar *label);
+void		vino_message_box_show_image (VinoMessageBox *box);
+void		vino_message_box_hide_image (VinoMessageBox *box);
+
+G_END_DECLS
+
+#endif /* _VINO_MESSAGE_BOX_H_ */

Modified: trunk/capplet/vino-preferences.c
==============================================================================
--- trunk/capplet/vino-preferences.c	(original)
+++ trunk/capplet/vino-preferences.c	Wed Jan 21 16:02:03 2009
@@ -23,20 +23,14 @@
  */
 
 #include <config.h>
-
-#define _GNU_SOURCE 1
-
 #include <string.h>
-#include <libintl.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <net/if.h>
-#include <ifaddrs.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
 #include <gconf/gconf-client.h>
 #include <dbus/dbus-glib.h>
 #include <glib/gi18n.h>
+#include <libsoup/soup.h>
+#include "vino-message-box.h"
 
 #ifdef VINO_ENABLE_KEYRING
 #include <gnome-keyring.h>
@@ -52,16 +46,10 @@
 #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_MAILTO                 VINO_PREFS_DIR "/mailto"
 #define VINO_PREFS_ICON_VISIBILITY        VINO_PREFS_DIR "/icon_visibility"
-#define VINO_PREFS_NETWORK_INTERFACE      VINO_PREFS_DIR "/network_interface"
-#define VINO_PREFS_ENCRYPTION             VINO_PREFS_DIR "/require_encryption"
-#define VINO_PREFS_USE_ALTERNATIVE_PORT   VINO_PREFS_DIR "/use_alternative_port"
-#define VINO_PREFS_ALTERNATIVE_PORT       VINO_PREFS_DIR "/alternative_port"
-#define VINO_PREFS_LOCK_SCREEN            VINO_PREFS_DIR "/lock_screen_on_disconnect"
-#define VINO_PREFS_DISABLE_BACKGROUND     VINO_PREFS_DIR "/disable_background"
+#define VINO_PREFS_USE_UPNP               VINO_PREFS_DIR "/use_upnp"
 
-#define N_LISTENERS                       13
+#define N_LISTENERS                       7
 
 #define VINO_DBUS_BUS_NAME  "org.gnome.Vino"
 #define VINO_DBUS_INTERFACE "org.gnome.VinoScreen"
@@ -69,44 +57,41 @@
 typedef struct {
   GladeXML    *xml;
   GConfClient *client;
-  char        *mailto;
 
   GtkWidget   *dialog;
   GtkWidget   *writability_warning;
-  GtkWidget   *send_email_button;
-  GtkWidget   *url_label;
   GtkWidget   *allowed_toggle;
-  GtkWidget   *prompt_enabled_toggle;
   GtkWidget   *view_only_toggle;
+  GtkWidget   *message;
+  GtkWidget   *prompt_enabled_toggle;
   GtkWidget   *password_toggle;
-  GtkWidget   *password_box;
   GtkWidget   *password_entry;
   GtkWidget   *icon_always_radio;
   GtkWidget   *icon_client_radio;
   GtkWidget   *icon_never_radio;
-  GtkWidget   *network_interface_combox;
-  GtkWidget   *network_interface_label;
-  GtkWidget   *encryption_toggle;
-  GtkWidget   *use_alternative_port_toggle;
-  GtkWidget   *alternative_port_entry;
-  GtkWidget   *lock_screen_toggle;
-  GtkWidget   *disable_background_toggle;
+  GtkWidget   *use_upnp_toggle;
 #ifdef VINO_ENABLE_LIBUNIQUE
   UniqueApp   *app;
 #endif
 
   DBusGConnection *connection;
-  DBusGProxy      *proxy_name, *proxy_port;
+  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_url_label (VinoPreferencesDialog *dialog);
+static void vino_preferences_dialog_update_message_box (VinoPreferencesDialog *dialog);
+
 
 static char *
 vino_preferences_dialog_get_password_from_keyring (VinoPreferencesDialog *dialog)
@@ -175,399 +160,21 @@
 vino_preferences_dialog_update_for_allowed (VinoPreferencesDialog *dialog,
 					    gboolean               allowed)
 {
-  gtk_widget_set_sensitive (dialog->prompt_enabled_toggle, allowed);
-  gtk_widget_set_sensitive (dialog->view_only_toggle,      allowed);
-  gtk_widget_set_sensitive (dialog->send_email_button,     allowed);
-  gtk_widget_set_sensitive (dialog->password_toggle,       allowed);
-  gtk_widget_set_sensitive (dialog->password_box,          allowed ? dialog->use_password : FALSE);
-  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);
-  gtk_widget_set_sensitive (dialog->network_interface_combox, allowed);
-  gtk_widget_set_sensitive (dialog->network_interface_label,  allowed);
-  gtk_widget_set_sensitive (dialog->encryption_toggle,     allowed);
-  gtk_widget_set_sensitive (dialog->use_alternative_port_toggle, allowed);
-  gtk_widget_set_sensitive (dialog->alternative_port_entry,      allowed &&
-			    gconf_client_get_bool (dialog->client, VINO_PREFS_USE_ALTERNATIVE_PORT, NULL));
-  gtk_widget_set_sensitive (dialog->lock_screen_toggle,          allowed);
-  gtk_widget_set_sensitive (dialog->disable_background_toggle,   allowed);
-}
-
-static GSList *
-vino_preferences_load_network_interfaces (void)
-{
-  struct ifaddrs *myaddrs, *ifa;
-  GSList *list = NULL;
-
-  /* Translators: 'All' means 'All network interfaces' */
-  list = g_slist_append (list, g_strdup (_("All")));
-
-  getifaddrs (&myaddrs);
-  for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
-    {
-      if (ifa->ifa_addr == NULL || ifa->ifa_name == NULL || (ifa->ifa_flags & IFF_UP) == 0) 
-        continue;
-
-      if (ifa->ifa_addr->sa_family == AF_INET || ifa->ifa_addr->sa_family == AF_INET6)
-        {
-          if (g_slist_find_custom (list, ifa->ifa_name, (GCompareFunc)g_strcasecmp) == NULL)
-            {
-              list  = g_slist_append (list, g_strdup (ifa->ifa_name));
-            }
-        }
-    }
-
-  freeifaddrs (myaddrs);
-  return list;
-}
-
-static void
-vino_preferences_dialog_network_interface_update_combox (VinoPreferencesDialog *dialog,
-                                                         const gchar *selected_iface,
-                                                         gboolean first_time)
-{
-  GSList *list;
-  gint    i, sel;
-  gchar  *iface_check;
-
-  list = vino_preferences_load_network_interfaces ();
-
-  if (selected_iface)
-    iface_check = g_strdup (selected_iface);
-  else
-    iface_check = gconf_client_get_string (dialog->client, VINO_PREFS_NETWORK_INTERFACE, NULL);
-
-  sel = 0;
-  for(i = 0; list; list = list->next, i++)
-    {
-      gchar *iface = list->data;
-
-      if (!iface)
-        continue;
-
-      if (first_time)
-	gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->network_interface_combox), iface);
-            
-      if (iface_check && !g_strcasecmp (iface, iface_check))
-	  sel = i;
-
-      g_free (iface);
-    }
-
-  gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->network_interface_combox), sel);
-  g_slist_free (list);
-  g_free (iface_check);
-}
-
-static void
-vino_preferences_dialog_network_interface_notify (GConfClient           *client,
-                                                  guint                  cnx_id,
-                                                  GConfEntry            *entry,
-                                                  VinoPreferencesDialog *dialog)
-{
-  gchar       *old_iface;
-  const gchar *new_iface;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
-    return;
-
-  new_iface = gconf_value_get_string (entry->value);
-  old_iface = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dialog->network_interface_combox));
-
-  if (old_iface && new_iface && g_strcasecmp (old_iface, new_iface) != 0)
-    vino_preferences_dialog_network_interface_update_combox (dialog, new_iface, FALSE);
-
-  g_free (old_iface);
-}
-
-static void
-vino_preferences_dialog_network_interface_changed (gpointer              unused,
-                                                   VinoPreferencesDialog *dialog)
-{
-  gchar *iface;
-
-  iface = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dialog->network_interface_combox));
-
-  if (g_strcasecmp (iface, _("All")))
-    gconf_client_set_string (dialog->client, VINO_PREFS_NETWORK_INTERFACE, iface, NULL);
-  else
-    gconf_client_set_string (dialog->client, VINO_PREFS_NETWORK_INTERFACE, "", NULL);
-
-  g_free (iface);
-}
-
-static void
-vino_preferences_dialog_setup_network_interface_combox (VinoPreferencesDialog *dialog)
-{
-  dialog->network_interface_combox = glade_xml_get_widget (dialog->xml, "network_interface_combox");
-  dialog->network_interface_label = glade_xml_get_widget (dialog->xml, "network_interface_label");
-  g_assert (dialog->network_interface_combox != NULL);
-  vino_preferences_dialog_network_interface_update_combox (dialog, NULL, TRUE);
-
-  g_signal_connect (dialog->network_interface_combox, "changed",
-                    G_CALLBACK (vino_preferences_dialog_network_interface_changed), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_NETWORK_INTERFACE, NULL))
-    {
-      gtk_widget_set_sensitive (dialog->network_interface_combox, FALSE);
-      gtk_widget_set_sensitive (dialog->network_interface_label, FALSE);
-      gtk_widget_show (dialog->writability_warning);
-    }
-
-  dialog->listeners [dialog->n_listeners] =
-    gconf_client_notify_add (dialog->client, 
-                VINO_PREFS_NETWORK_INTERFACE,
-                (GConfClientNotifyFunc)vino_preferences_dialog_network_interface_notify,
-                dialog, NULL, NULL);
-  dialog->n_listeners++;
-}
-
-static void
-vino_preferences_dialog_encryption_toggled (GtkToggleButton       *toggle,
-					    VinoPreferencesDialog *dialog)
-{
-  gboolean encryption;
-
-  encryption = gtk_toggle_button_get_active (toggle);
-
-  gconf_client_set_bool (dialog->client, VINO_PREFS_ENCRYPTION, encryption, NULL);
-}
-
-static void
-vino_preferences_dialog_encryption_notify (GConfClient           *client,
-					   guint                  cnx_id,
-					   GConfEntry            *entry,
-					   VinoPreferencesDialog *dialog)
-{
-  gboolean encryption;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-    return;
-
-  encryption = gconf_value_get_bool (entry->value) != FALSE;
-
-  if (encryption != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->encryption_toggle)))
-    {
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->encryption_toggle), encryption);
-    }
-}
-
-static gboolean
-vino_preferences_dialog_setup_encryption_toggle (VinoPreferencesDialog *dialog)
-{
-  gboolean encryption;
-
-  dialog->encryption_toggle = glade_xml_get_widget (dialog->xml, "encryption_toggle");
-  g_assert (dialog->encryption_toggle != NULL);
-
-  encryption = gconf_client_get_bool (dialog->client, VINO_PREFS_ENCRYPTION, NULL);
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->encryption_toggle), encryption);
-
-  g_signal_connect (dialog->encryption_toggle, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_encryption_toggled), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_ENCRYPTION, NULL))
-    {
-      gtk_widget_set_sensitive (dialog->encryption_toggle, FALSE);
-      gtk_widget_show (dialog->writability_warning);
-    }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_ENCRYPTION,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_encryption_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
-
-  return encryption;
-}
-
-static void
-vino_preferences_dialog_use_alternative_port_toggled (GtkToggleButton       *toggle,
-						      VinoPreferencesDialog *dialog)
-{
-  gboolean use_alternative_port;
-
-  use_alternative_port = gtk_toggle_button_get_active (toggle);
-  gtk_widget_set_sensitive (dialog->alternative_port_entry, use_alternative_port);
-
-  gconf_client_set_bool (dialog->client, VINO_PREFS_USE_ALTERNATIVE_PORT, use_alternative_port, NULL);
-}
-
-static void
-vino_preferences_dialog_use_alternative_port_notify (GConfClient           *client,
-						     guint                  cnx_id,
-						     GConfEntry            *entry,
-						     VinoPreferencesDialog *dialog)
-{
-  gboolean use_alternative_port;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-    return;
-
-  use_alternative_port = gconf_value_get_bool (entry->value) != FALSE;
-
-  if (use_alternative_port != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->use_alternative_port_toggle)))
-    {
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->use_alternative_port_toggle), use_alternative_port);
-    }
-}
-
-static gboolean
-vino_preferences_dialog_setup_use_alternative_port_toggle (VinoPreferencesDialog *dialog)
-{
-  gboolean use_alternative_port;
-
-  dialog->use_alternative_port_toggle = glade_xml_get_widget (dialog->xml, "use_alternative_port_toggle");
-  g_assert (dialog->use_alternative_port_toggle != NULL);
-
-  use_alternative_port = gconf_client_get_bool (dialog->client, VINO_PREFS_USE_ALTERNATIVE_PORT, NULL);
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->use_alternative_port_toggle), use_alternative_port);
-  gtk_widget_set_sensitive (dialog->alternative_port_entry, use_alternative_port);
-
-  g_signal_connect (dialog->use_alternative_port_toggle, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_use_alternative_port_toggled), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_USE_ALTERNATIVE_PORT, NULL))
-    {
-      gtk_widget_set_sensitive (dialog->use_alternative_port_toggle, FALSE);
-      gtk_widget_set_sensitive (dialog->alternative_port_entry, FALSE);
-      gtk_widget_show (dialog->writability_warning);
-    }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_USE_ALTERNATIVE_PORT,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_use_alternative_port_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
-
-  return use_alternative_port;
-}
-
-static void
-vino_preferences_dialog_alternative_port_changed (GtkSpinButton         *button,
-						  VinoPreferencesDialog *dialog)
-{
-  gint alternative_port;
-
-  alternative_port = gtk_spin_button_get_value_as_int (button);
-
-  gconf_client_set_int (dialog->client, VINO_PREFS_ALTERNATIVE_PORT, alternative_port, NULL);
-}
-
-static void
-vino_preferences_dialog_alternative_port_notify (GConfClient           *client,
-						 guint                  cnx_id,
-						 GConfEntry            *entry,
-						 VinoPreferencesDialog *dialog)
-{
-  gint alternative_port;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_INT)
-    return;
-
-  alternative_port = gconf_value_get_int (entry->value);
-
-  if (alternative_port != gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (dialog->alternative_port_entry)))
-    {
-      gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->alternative_port_entry), alternative_port);
-    }
-}
-
-static gint
-vino_preferences_dialog_setup_alternative_port_entry (VinoPreferencesDialog *dialog)
-{
-  gint alternative_port;
-
-  dialog->alternative_port_entry = glade_xml_get_widget (dialog->xml, "alternative_port_entry");
-  g_assert (dialog->alternative_port_entry != NULL);
-
-  alternative_port = gconf_client_get_int (dialog->client, VINO_PREFS_ALTERNATIVE_PORT, NULL);
-
-  gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->alternative_port_entry), alternative_port);
-
-  g_signal_connect (dialog->alternative_port_entry, "value-changed",
-		    G_CALLBACK (vino_preferences_dialog_alternative_port_changed), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_ALTERNATIVE_PORT, NULL))
-    {
-      gtk_widget_set_sensitive (dialog->use_alternative_port_toggle, FALSE);
-      gtk_widget_set_sensitive (dialog->alternative_port_entry, FALSE);
-      gtk_widget_show (dialog->writability_warning);
-    }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_ALTERNATIVE_PORT,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_alternative_port_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
-
-  return alternative_port;
-}
-
-static void
-vino_preferences_dialog_lock_screen_toggled (GtkToggleButton       *toggle,
-					     VinoPreferencesDialog *dialog)
-{
-  gboolean lock_screen;
-
-  lock_screen = gtk_toggle_button_get_active (toggle);
-
-  gconf_client_set_bool (dialog->client, VINO_PREFS_LOCK_SCREEN, lock_screen, NULL);
-}
-
-static void
-vino_preferences_dialog_lock_screen_notify (GConfClient           *client,
-					    guint                  cnx_id,
-					    GConfEntry            *entry,
-					    VinoPreferencesDialog *dialog)
-{
-  gboolean lock_screen;
-
-  if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-    return;
-
-  lock_screen = gconf_value_get_bool (entry->value) != FALSE;
-
-  if (lock_screen != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->lock_screen_toggle)))
-    {
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->lock_screen_toggle), lock_screen);
-    }
+  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);
 }
 
 static gboolean
-vino_preferences_dialog_setup_lock_screen_toggle (VinoPreferencesDialog *dialog)
+delay_update_message (VinoPreferencesDialog *dialog)
 {
-  gboolean lock_screen;
-
-  dialog->lock_screen_toggle = glade_xml_get_widget (dialog->xml, "lock_screen_toggle");
-  g_assert (dialog->lock_screen_toggle != NULL);
-
-  lock_screen = gconf_client_get_bool (dialog->client, VINO_PREFS_LOCK_SCREEN, NULL);
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->lock_screen_toggle), lock_screen);
-
-  g_signal_connect (dialog->lock_screen_toggle, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_lock_screen_toggled), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_LOCK_SCREEN, NULL))
-    {
-      gtk_widget_set_sensitive (dialog->lock_screen_toggle, FALSE);
-      gtk_widget_show (dialog->writability_warning);
-    }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_LOCK_SCREEN,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_lock_screen_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
-
-  return lock_screen;
+  vino_preferences_dialog_update_message_box (dialog);
+  return FALSE;
 }
 
 static void
@@ -581,6 +188,24 @@
   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 conectivity 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
@@ -853,7 +478,7 @@
 
   g_slist_free (auth_methods);
 
-  gtk_widget_set_sensitive (dialog->password_box, dialog->use_password);
+  gtk_widget_set_sensitive (dialog->password_entry, dialog->use_password);
 }
 
 static void
@@ -1025,9 +650,6 @@
   dialog->password_entry = glade_xml_get_widget (dialog->xml, "password_entry");
   g_assert (dialog->password_entry != NULL);
   
-  dialog->password_box = glade_xml_get_widget (dialog->xml, "password_box");
-  g_assert (dialog->password_box != NULL);
-
   password_in_keyring = TRUE;
 
   if (!(password = vino_preferences_dialog_get_password_from_keyring (dialog)))
@@ -1062,13 +684,13 @@
   g_signal_connect (dialog->password_entry, "changed",
 		    G_CALLBACK (vino_preferences_dialog_password_changed), dialog);
 
-  gtk_widget_set_sensitive (dialog->password_box, dialog->use_password);
+  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))
         {
-          gtk_widget_set_sensitive (dialog->password_box, FALSE);
+          gtk_widget_set_sensitive (dialog->password_entry, FALSE);
           gtk_widget_show (dialog->writability_warning);
         }
 
@@ -1086,388 +708,309 @@
 }
 
 static void
-vino_preferences_dialog_disable_background_toggled (GtkToggleButton       *toggle,
-                                                    VinoPreferencesDialog *dialog)
+vino_preferences_dialog_use_upnp_toggled (GtkToggleButton       *toggle,
+					  VinoPreferencesDialog *dialog)
 {
-  gboolean disable_background;
-
-  disable_background = gtk_toggle_button_get_active (toggle);
+  gconf_client_set_bool (dialog->client,
+			 VINO_PREFS_USE_UPNP,
+			 gtk_toggle_button_get_active (toggle),
+			 NULL);
 
-  gconf_client_set_bool (dialog->client, VINO_PREFS_DISABLE_BACKGROUND, disable_background, NULL);
+  g_timeout_add_seconds (1, (GSourceFunc) delay_update_message, dialog);
 }
 
 static void
-vino_preferences_dialog_disable_background_notify (GConfClient           *client,
-                                                   guint                  cnx_id,
-                                                   GConfEntry            *entry,
-                                                   VinoPreferencesDialog *dialog)
+vino_preferences_dialog_use_upnp_notify (GConfClient           *client,
+					 guint                  cnx_id,
+					 GConfEntry            *entry,
+					 VinoPreferencesDialog *dialog)
 {
-  gboolean disable_background;
+  gboolean use_upnp;
 
   if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
     return;
 
-  disable_background = gconf_value_get_bool (entry->value) != FALSE;
+  use_upnp = gconf_value_get_bool (entry->value) != FALSE;
 
-  if (disable_background != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->disable_background_toggle)))
+  if (use_upnp != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->use_upnp_toggle)))
     {
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->disable_background_toggle), disable_background);
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->use_upnp_toggle), use_upnp);
     }
 }
 
-static gboolean
-vino_preferences_dialog_setup_disable_background_toggle (VinoPreferencesDialog *dialog)
+static void
+vino_preferences_dialog_setup_use_upnp_toggle (VinoPreferencesDialog *dialog)
 {
-  gboolean disable_background;
+  gboolean use_upnp;
 
-  dialog->disable_background_toggle = glade_xml_get_widget (dialog->xml, "disable_background_toggle");
-  g_assert (dialog->disable_background_toggle != NULL);
+  dialog->use_upnp_toggle = glade_xml_get_widget (dialog->xml, "use_upnp_toggle");
+  g_assert (dialog->use_upnp_toggle != NULL);
 
-  disable_background = gconf_client_get_bool (dialog->client, VINO_PREFS_DISABLE_BACKGROUND, 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);
 
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->disable_background_toggle), disable_background);
+  g_signal_connect (dialog->use_upnp_toggle, "toggled",
+		    G_CALLBACK (vino_preferences_dialog_use_upnp_toggled), dialog);
 
-  g_signal_connect (dialog->disable_background_toggle, "toggled",
-		    G_CALLBACK (vino_preferences_dialog_disable_background_toggled), dialog);
-
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_DISABLE_BACKGROUND, NULL))
+  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_USE_UPNP, NULL))
     {
-      gtk_widget_set_sensitive (dialog->disable_background_toggle, FALSE);
+      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_DISABLE_BACKGROUND,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_disable_background_notify,
+			     VINO_PREFS_USE_UPNP,
+			     (GConfClientNotifyFunc) vino_preferences_dialog_use_upnp_notify,
 			     dialog, NULL, NULL);
   dialog->n_listeners++;
-
-  return disable_background;
 }
 
 static void
-vino_preferences_server_updated (DBusGProxy *proxy,
-                                 const char *name,
-                                 const char *prev_owner,
-                                 const char *new_owner,
-                                 gpointer user_data)
+vino_preferences_dialog_response (GtkWidget             *widget,
+				  int                    response,
+				  VinoPreferencesDialog *dialog)
 {
-  if ( (new_owner) && (!strcmp (name, VINO_DBUS_BUS_NAME)) )
-    vino_preferences_dialog_update_url_label ( (VinoPreferencesDialog *) user_data);
-}
+  GError    *error;
+  GdkScreen *screen;
 
-static void
-vino_preferences_server_port_changed (DBusGProxy *proxy, gpointer user_data)
-{
-  vino_preferences_dialog_update_url_label ( (VinoPreferencesDialog *) user_data);
-}
+  if (response != GTK_RESPONSE_HELP)
+    {
+      if (dialog->session)
+        soup_session_abort (dialog->session);
+      gtk_widget_destroy (widget);
+      return;
+    }
 
-static void
-vino_preferences_start_listening (VinoPreferencesDialog *dialog)
-{
-  gchar       *obj_path;
-  GdkScreen   *screen;
+  screen = gtk_widget_get_screen (widget);
+  error = NULL;
 
-  dialog->proxy_name = dbus_g_proxy_new_for_name (dialog->connection,
-						  DBUS_SERVICE_DBUS,
-						  DBUS_PATH_DBUS,
-						  DBUS_INTERFACE_DBUS);
-  dbus_g_proxy_add_signal (dialog->proxy_name, "NameOwnerChanged",
-                           G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
-  dbus_g_proxy_connect_signal (dialog->proxy_name, "NameOwnerChanged",
-                          G_CALLBACK (vino_preferences_server_updated), dialog, NULL);
+  gtk_show_uri (screen, "ghelp:user-guide?goscustdesk-90", GDK_CURRENT_TIME, &error);
+  if (error)
+    {
+      GtkWidget *message_dialog;
 
-  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_port = 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_port, "ServerPortChanged", G_TYPE_INVALID);
-  dbus_g_proxy_connect_signal (dialog->proxy_port, "ServerPortChanged",
-                          G_CALLBACK (vino_preferences_server_port_changed), dialog, NULL);
-}
+      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);
 
-static int
-vino_preferences_get_server_port (VinoPreferencesDialog *dialog)
-{
-  DBusGProxy  *proxy;
-  int          port;
-  GdkScreen   *screen;
-  char        *obj_path;
-#ifdef VINO_ENABLE_HTTP_SERVER
-  const char  *method = "GetHttpServerPort";
-#else
-  const char  *method = "GetServerPort";
-#endif
-  
-  screen = gtk_window_get_screen (GTK_WINDOW (dialog->dialog));
-  obj_path = g_strdup_printf ("/org/gnome/vino/screens/%d",
-                              gdk_screen_get_number (screen));
+      g_signal_connect (message_dialog, "response",
+			G_CALLBACK (gtk_widget_destroy),
+			NULL);
 
-  proxy = dbus_g_proxy_new_for_name (dialog->connection,
-                                     VINO_DBUS_BUS_NAME,
-                                     obj_path,
-                                     VINO_DBUS_INTERFACE);
-  g_free (obj_path);
+      gtk_widget_show (message_dialog);
 
-  if (!dbus_g_proxy_call (proxy, method, NULL,
-                          G_TYPE_INVALID,
-                          G_TYPE_INT, &port,
-                          G_TYPE_INVALID))
-    {
-      port = 0;
+      g_error_free (error);
     }
-
-  g_object_unref (proxy);
-  return port;
 }
 
-static char *
-vino_preferences_get_local_hostname (void)
+static void
+vino_preferences_dialog_destroyed (GtkWidget             *widget,
+				   VinoPreferencesDialog *dialog)
 {
-  static char      local_host [NI_MAXHOST] = { 0, };
-  struct addrinfo  hints;
-  struct addrinfo *results;
-  char            *retval;
-
-  if (gethostname (local_host, NI_MAXHOST) == -1)
-    return NULL;
-
-  memset (&hints, 0, sizeof (hints));
-  hints.ai_flags = AI_CANONNAME;
-
-  results = NULL;
-  if (getaddrinfo (local_host,  NULL, &hints, &results) != 0)
-    return NULL;
-
-  retval = g_strdup (results ? results->ai_canonname : local_host);
-
-  if (results)
-    freeaddrinfo (results);
+  dialog->dialog = NULL;
 
-  return retval;
+  gtk_main_quit ();
 }
 
-static char *
-vino_preferences_dialog_get_server_command (VinoPreferencesDialog *dialog)
+static void
+error_message (VinoPreferencesDialog *dialog)
 {
-  char *local_host;
-  char *server_url;
-  int   server_port;
-
-  server_port = vino_preferences_get_server_port (dialog);
-
-  gtk_widget_set_sensitive (dialog->send_email_button, server_port);
+  gchar *msg1, *msg2, *host, *url, *message;
 
-  if (server_port == 0)
-    return g_strdup (_("The service is not running"));
-
-  local_host = vino_preferences_get_local_hostname ();
-  if (!local_host)
-    local_host = g_strdup_printf ("localhost");
-
-#ifdef VINO_ENABLE_HTTP_SERVER
-  server_url = g_strdup_printf ("http://%s:%d";, local_host, server_port);
-#else
-  server_url = g_strdup_printf ("vinagre %s::%d", local_host, server_port);
-#endif
-
-  g_free (local_host);
+  if (!dbus_g_proxy_call (dialog->proxy,
+                          "GetInternalData",
+                          NULL,
+                          G_TYPE_INVALID,
+                          G_TYPE_STRING, &host,
+                          G_TYPE_INT, &dialog->port,
+                          G_TYPE_INVALID))
+    {
+      dialog->port = 5900;
+      host = g_strdup ("localhost");
+    }
 
-  return server_url;
+  url = g_strdup_printf ("<a href=\"vnc://%s::%d\">%s</a>", host, dialog->port, host);
+  msg1 = g_strdup (_("Your desktop is only reachable over the local network."));
+  msg2 = g_strdup_printf (_("Others can access your computer using the address %s."), url);
+  message = g_strjoin (" ", msg1, msg2, NULL);
+  vino_message_box_hide_image (VINO_MESSAGE_BOX (dialog->message));
+  vino_message_box_set_label (VINO_MESSAGE_BOX (dialog->message), message);
+  g_free (msg1);
+  g_free (msg2);
+  g_free (message);
+  g_free (url);
+  g_free (host);
 }
 
-static char *
-vino_preferences_dialog_construct_mailto (VinoPreferencesDialog *dialog)
-{
-  GString *mailto;
-  char *command;
+static void
+got_status (SoupSession *session, SoupMessage *msg, VinoPreferencesDialog *dialog)
+{
+  gboolean       status;
+  GError         *error;
+  GHashTable     *hash;
+  GHashTableIter iter;
+  gpointer       key, value;
+  gchar          *ip, *message, *url;
 
-  command = vino_preferences_dialog_get_server_command (dialog);
+  error = NULL;
+  ip = NULL;
+  status = FALSE;
 
-  mailto = g_string_new ("mailto:";);
-  if (dialog->mailto)
-    mailto = g_string_append (mailto, dialog->mailto);
+  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)
+	{
+	  url = g_strdup_printf ("<a href=\"vnc://%s::%d\">%s</a>", ip, dialog->port, ip);
+	  message = g_strdup_printf (_("Others can access your computer using the address %s."), url);
+	  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_free (url);
+	}
+      else
+	error_message (dialog);
 
-  mailto = g_string_append_c (mailto, '?');
-  g_string_append_printf (mailto, "Body=%s", command);
+      g_free (ip);
+    }
+  else
+    {
+      if (error)
+	{
+	  g_warning ("%s", error->message);
+	  g_error_free (error);
+	}
+      error_message (dialog);
+    }
 
-  g_free (command);
-  return g_string_free (mailto, FALSE);
+  dialog->retrieving_info = FALSE;
 }
 
-static void
-vino_preferences_dialog_update_url_label (VinoPreferencesDialog *dialog)
+static gboolean
+request_timeout_cb (VinoPreferencesDialog *dialog)
 {
-  char *command, *label;
+  if (!dialog->retrieving_info)
+    return FALSE;
 
-  command = vino_preferences_dialog_get_server_command (dialog);
-  label = g_strdup_printf ("<i>%s</i>", command);
-  
-  gtk_label_set_label (GTK_LABEL (dialog->url_label), label);
-  
-  g_free (command);
-  g_free (label);
+  soup_session_cancel_message (dialog->session, dialog->msg, 408);
+  return FALSE;
 }
 
+#define TIMEOUT 6
 static void
-vino_preferences_dialog_mailto_notify (GConfClient           *client,
-				       guint                  cnx_id,
-				       GConfEntry            *entry,
-				       VinoPreferencesDialog *dialog)
+vino_preferences_dialog_update_message_box (VinoPreferencesDialog *dialog)
 {
-  const char *mailto;
+  gboolean allowed;
 
-  if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
+  if (dialog->retrieving_info)
     return;
+  dialog->retrieving_info = TRUE;
 
-  mailto = gconf_value_get_string (entry->value);
-
-  if (!mailto || mailto [0] == '\0' || mailto [0] == ' ')
-    {
-      g_free (dialog->mailto);
-      dialog->mailto = NULL;
-      vino_preferences_dialog_update_url_label (dialog);
-    }
-  else if (!dialog->mailto || (dialog->mailto && strcmp (dialog->mailto, mailto)))
+  allowed = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->allowed_toggle));
+  if (!allowed)
     {
-      g_free (dialog->mailto);
-      dialog->mailto = g_strdup (mailto);
+      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;
     }
-}
 
-static void
-vino_preferences_email_button_clicked (GtkButton *button,
-				       VinoPreferencesDialog *dialog)
-{
-  GError *error;
-  GdkScreen *screen;
-  char *mailto, *command;
+  vino_message_box_show_image (VINO_MESSAGE_BOX (dialog->message));
+  vino_message_box_set_label (VINO_MESSAGE_BOX (dialog->message),
+			      _("Checking the conectivity of this machine..."));
 
-  error   = NULL;
-  screen  = gtk_widget_get_screen (GTK_WIDGET (button));
-  mailto  = vino_preferences_dialog_construct_mailto (dialog);
-  command = vino_preferences_dialog_get_server_command (dialog);
+  dbus_g_proxy_call (dialog->proxy,
+                     "GetExternalPort",
+                     NULL,
+                     G_TYPE_INVALID,
+                     G_TYPE_INT, &dialog->port,
+                     G_TYPE_INVALID);
 
-  if (!gtk_show_uri (screen, mailto, GDK_CURRENT_TIME, &error))
-    {
-      GtkWidget *message_dialog;
+  if (!dialog->session)
+    dialog->session = soup_session_async_new ();
 
-      message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog->dialog),
-					       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-					       GTK_MESSAGE_ERROR,
-					       GTK_BUTTONS_CLOSE,
-					       _("There was an error showing the URL \"%s\""),
-					       command);
-      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
-						"%s",
-						error->message);
+  dialog->msg = soup_xmlrpc_request_new ("http://blog.jorgepereira.com.br/jorge/org.gnome.vino.Service.php";,
+					 "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);
 
-      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);
-    }
-
-  g_free (mailto);
-  g_free (command);
+  g_timeout_add_seconds (TIMEOUT+1,
+			 (GSourceFunc) request_timeout_cb,
+			 dialog);
 }
 
 static void
-vino_preferences_dialog_setup_url_labels (VinoPreferencesDialog *dialog)
+vino_preferences_dialog_setup_message_box (VinoPreferencesDialog *dialog)
 {
-  char *command, *label;
-  GtkWidget *image;
+  GtkWidget *message_box;
 
-  dialog->url_label = glade_xml_get_widget (dialog->xml, "url_label");
-  dialog->send_email_button = glade_xml_get_widget (dialog->xml, "send_email_button");
-  g_assert (dialog->url_label);
+  message_box = glade_xml_get_widget (dialog->xml, "message_box");
+  g_assert (message_box != NULL);
 
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_MAILTO,
-			     (GConfClientNotifyFunc) vino_preferences_dialog_mailto_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
-  
-  dialog->mailto = gconf_client_get_string (dialog->client, VINO_PREFS_MAILTO, NULL);
-  if (!dialog->mailto || dialog->mailto [0] == '\0'|| dialog->mailto [0] == ' ')
-    {
-      g_free (dialog->mailto);
-      dialog->mailto = NULL;
-    }
-
-  command = vino_preferences_dialog_get_server_command (dialog);
-  label = g_strdup_printf ("<i>%s</i>", command);
-  
-  gtk_label_set_label (GTK_LABEL (dialog->url_label), label);
-
-  image = gtk_image_new_from_icon_name ("gnome-stock-mail-fwd", GTK_ICON_SIZE_BUTTON);
-  gtk_button_set_image (GTK_BUTTON (dialog->send_email_button), image);
-  g_signal_connect (dialog->send_email_button,
-		    "clicked",
-		    G_CALLBACK (vino_preferences_email_button_clicked),
-		    dialog);
+  dialog->message = vino_message_box_new ();
+  gtk_box_pack_end (GTK_BOX (message_box), dialog->message, TRUE, TRUE, 0);
+  gtk_widget_show (dialog->message);
 
-  g_free (command);
-  g_free (label);
+  vino_preferences_dialog_update_message_box (dialog);
 }
 
 static void
-vino_preferences_dialog_response (GtkWidget             *widget,
-				  int                    response,
-				  VinoPreferencesDialog *dialog)
+handle_server_info_message (DBusGProxy *proxy, VinoPreferencesDialog *dialog)
 {
-  GError    *error;
-  GdkScreen *screen;
-
-  if (response != GTK_RESPONSE_HELP)
-    {
-      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);
-    }
+  vino_preferences_dialog_update_message_box (dialog);
 }
 
 static void
-vino_preferences_dialog_destroyed (GtkWidget             *widget,
-				   VinoPreferencesDialog *dialog)
+vino_preferences_start_listening (VinoPreferencesDialog *dialog)
 {
-  dialog->dialog = NULL;
+  gchar       *obj_path;
+  GdkScreen   *screen;
 
-  gtk_main_quit ();
+  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
@@ -1505,39 +1048,35 @@
   dialog->client = gconf_client_get_default ();
   gconf_client_add_dir (dialog->client, VINO_PREFS_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, 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_dialog_setup_url_labels (dialog);
-
   dialog->writability_warning = glade_xml_get_widget (dialog->xml, "writability_warning");
   g_assert (dialog->writability_warning != NULL);
   gtk_widget_hide (dialog->writability_warning);
 
   allowed = vino_preferences_dialog_setup_allowed_toggle (dialog);
 
-  vino_preferences_dialog_setup_prompt_enabled_toggle       (dialog);
   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);
-  vino_preferences_dialog_setup_network_interface_combox    (dialog);
-  vino_preferences_dialog_setup_encryption_toggle           (dialog);
-  vino_preferences_dialog_setup_alternative_port_entry      (dialog);
-  vino_preferences_dialog_setup_use_alternative_port_toggle (dialog);
-  vino_preferences_dialog_setup_lock_screen_toggle          (dialog);
-  vino_preferences_dialog_setup_disable_background_toggle   (dialog);
 
   g_assert (dialog->n_listeners == dialog->expected_listeners);
 
   vino_preferences_dialog_update_for_allowed (dialog, allowed);
 
+  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);
 
 #ifdef VINO_ENABLE_LIBUNIQUE
@@ -1556,10 +1095,6 @@
     gtk_widget_destroy (dialog->dialog);
   dialog->dialog = NULL;
 
-  if (dialog->mailto)
-    g_free (dialog->mailto);
-  dialog->mailto = NULL;
-
   if (dialog->client)
     {
       int i;
@@ -1588,13 +1123,13 @@
   dialog->app = NULL;
 #endif
 
-  if (dialog->proxy_name)
-    g_object_unref (dialog->proxy_name);
-  dialog->proxy_name = NULL;
-
-  if (dialog->proxy_port)
-    g_object_unref (dialog->proxy_port);
-  dialog->proxy_port = NULL;
+  if (dialog->session)
+    g_object_unref (dialog->session);
+  dialog->session = NULL;
+
+  if (dialog->proxy)
+    g_object_unref (dialog->proxy);
+  dialog->proxy = NULL;
 
   if (dialog->connection)
     dbus_g_connection_unref (dialog->connection);
@@ -1645,7 +1180,6 @@
       return 1;
     }
 
-  vino_preferences_start_listening (&dialog);
   gtk_main ();
 
   vino_preferences_dialog_finalize (&dialog);

Modified: trunk/capplet/vino-preferences.glade
==============================================================================
--- trunk/capplet/vino-preferences.glade	(original)
+++ trunk/capplet/vino-preferences.glade	Wed Jan 21 16:02:03 2009
@@ -1,11 +1,12 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--*- mode: xml -*-->
+<!--Generated with glade3 3.4.5 on Fri Jan  9 12:24:40 2009 -->
 <glade-interface>
   <widget class="GtkDialog" id="vino_dialog">
     <property name="border_width">5</property>
     <property name="title" translatable="yes">Remote Desktop Preferences</property>
     <property name="resizable">False</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
     <property name="icon_name">preferences-desktop-remote-desktop</property>
     <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
     <property name="has_separator">False</property>
@@ -14,26 +15,31 @@
         <property name="visible">True</property>
         <property name="spacing">2</property>
         <child>
-          <widget class="GtkNotebook" id="notebook1">
+          <widget class="GtkVBox" id="vbox1">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-            <property name="border_width">5</property>
+            <property name="border_width">6</property>
+            <property name="spacing">18</property>
             <child>
-              <widget class="GtkVBox" id="vbox34">
+              <widget class="GtkVBox" id="sharing_box">
                 <property name="visible">True</property>
-                <property name="border_width">12</property>
-                <property name="spacing">18</property>
+                <property name="spacing">3</property>
                 <child>
-                  <widget class="GtkVBox" id="vbox36">
+                  <widget class="GtkLabel" id="label1">
                     <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Sharing&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="writability_warning">
+                    <property name="no_show_all">True</property>
+                    <property name="border_width">3</property>
                     <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkLabel" id="label48">
+                      <widget class="GtkLabel" id="label6">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">&lt;b&gt;Sharing&lt;/b&gt;</property>
-                        <property name="use_markup">True</property>
+                        <property name="label" translatable="yes"> </property>
                       </widget>
                       <packing>
                         <property name="expand">False</property>
@@ -41,188 +47,39 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkHBox" id="hbox31">
+                      <widget class="GtkImage" id="image1">
                         <property name="visible">True</property>
-                        <property name="spacing">12</property>
-                        <child>
-                          <widget class="GtkImage" id="sharing_icon">
-                            <property name="visible">True</property>
-                            <property name="yalign">0</property>
-                            <property name="icon_size">6</property>
-                            <property name="icon_name">preferences-desktop-remote-desktop</property>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkVBox" id="vbox34">
-                            <property name="visible">True</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <widget class="GtkHBox" id="writability_warning">
-                                <property name="visible">True</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <widget class="GtkImage" id="image1">
-                                    <property name="visible">True</property>
-                                    <property name="stock">gtk-dialog-warning</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkLabel" id="label47">
-                                    <property name="visible">True</property>
-                                    <property name="label" translatable="yes">Some of these preferences are locked down</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                            </child>
-                            <child>
-                              <widget class="GtkCheckButton" id="allowed_toggle">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="has_tooltip">True</property>
-                                <property name="tooltip" translatable="yes" comments="tooltip in preferences applet">Your desktop will be shared</property>
-                                <property name="label" translatable="yes">Allow other users to _view your desktop</property>
-                                <property name="use_underline">True</property>
-                                <property name="response_id">0</property>
-                                <property name="draw_indicator">True</property>
-                              </widget>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkHBox" id="hbox27">
-                                <property name="visible">True</property>
-                                <child>
-                                  <widget class="GtkLabel" id="label49">
-                                    <property name="visible">True</property>
-                                    <property name="label">    </property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkCheckButton" id="view_only_toggle">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="has_tooltip">True</property>
-                                    <property name="tooltip" translatable="yes" comments="tooltip in preferences applet">Remote users are able to control your mouse and keyboard</property>
-                                    <property name="label" translatable="yes">_Allow other users to control your desktop</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="response_id">0</property>
-                                    <property name="draw_indicator">True</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="position">2</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkVBox" id="url_labels_box">
-                                <property name="visible">True</property>
-                                <child>
-                                  <widget class="GtkLabel" id="label56">
-                                    <property name="visible">True</property>
-                                    <property name="xalign">0</property>
-                                    <property name="yalign">0</property>
-                                    <property name="label" translatable="yes">Users can view your desktop using this command:</property>
-                                    <property name="use_markup">True</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkHBox" id="hbox2">
-                                    <property name="visible">True</property>
-                                    <property name="spacing">5</property>
-                                    <child>
-                                      <widget class="GtkLabel" id="url_label">
-                                        <property name="visible">True</property>
-                                        <property name="xalign">0</property>
-                                        <property name="xpad">1</property>
-                                        <property name="label">label</property>
-                                        <property name="use_markup">True</property>
-                                        <property name="selectable">True</property>
-                                      </widget>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <widget class="GtkButton" id="send_email_button">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">True</property>
-                                        <property name="receives_default">True</property>
-                                        <property name="has_tooltip">True</property>
-                                        <property name="tooltip" translatable="yes">Send this command by email</property>
-                                        <property name="relief">GTK_RELIEF_NONE</property>
-                                        <property name="xalign">0</property>
-                                        <property name="response_id">0</property>
-                                      </widget>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">False</property>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                  </widget>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="position">3</property>
-                              </packing>
-                            </child>
-                          </widget>
-                          <packing>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
+                        <property name="stock">gtk-dialog-warning</property>
                       </widget>
                       <packing>
+                        <property name="expand">False</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
+                    <child>
+                      <widget class="GtkLabel" id="label8">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">&lt;i&gt;Some of these preferences are locked down&lt;/i&gt;</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
                   </widget>
                   <packing>
-                    <property name="expand">False</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
                 <child>
-                  <widget class="GtkVBox" id="vbox37">
+                  <widget class="GtkHBox" id="hbox1">
                     <property name="visible">True</property>
-                    <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkLabel" id="label50">
+                      <widget class="GtkLabel" id="label2">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">&lt;b&gt;Security&lt;/b&gt;</property>
-                        <property name="use_markup">True</property>
+                        <property name="label" translatable="yes">   </property>
                       </widget>
                       <packing>
                         <property name="expand">False</property>
@@ -230,152 +87,15 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkHBox" id="hbox32">
+                      <widget class="GtkCheckButton" id="allowed_toggle">
                         <property name="visible">True</property>
-                        <property name="spacing">12</property>
-                        <child>
-                          <widget class="GtkImage" id="security_icon">
-                            <property name="visible">True</property>
-                            <property name="yalign">0</property>
-                            <property name="icon_size">6</property>
-                            <property name="icon_name">system-lock-screen</property>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkVBox" id="vbox35">
-                            <property name="visible">True</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <widget class="GtkLabel" id="label51">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">When a user tries to view or control your desktop:</property>
-                              </widget>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkHBox" id="hbox28">
-                                <property name="visible">True</property>
-                                <child>
-                                  <widget class="GtkLabel" id="label52">
-                                    <property name="visible">True</property>
-                                    <property name="label">    </property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkCheckButton" id="prompt_enabled_toggle">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="label" translatable="yes">A_sk you for confirmation</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="response_id">0</property>
-                                    <property name="draw_indicator">True</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkHBox" id="hbox30">
-                                <property name="visible">True</property>
-                                <child>
-                                  <widget class="GtkLabel" id="label54">
-                                    <property name="visible">True</property>
-                                    <property name="label">    </property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkCheckButton" id="password_toggle">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="label" translatable="yes">_Require the user to enter this password:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="response_id">0</property>
-                                    <property name="draw_indicator">True</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="position">2</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkHBox" id="password_box">
-                                <property name="visible">True</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <widget class="GtkLabel" id="label46">
-                                    <property name="visible">True</property>
-                                    <property name="label">        </property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkLabel" id="password_label">
-                                    <property name="visible">True</property>
-                                    <property name="label" translatable="yes">_Password:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">password_entry</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget 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>
-                                  </widget>
-                                  <packing>
-                                    <property name="position">2</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="position">3</property>
-                              </packing>
-                            </child>
-                          </widget>
-                          <packing>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
+                        <property name="can_focus">True</property>
+                        <property name="has_tooltip">True</property>
+                        <property name="tooltip" translatable="yes">Your desktop will be shared</property>
+                        <property name="label" translatable="yes">Allow other users to _view your desktop</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
                       </widget>
                       <packing>
                         <property name="position">1</property>
@@ -383,40 +103,16 @@
                     </child>
                   </widget>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="position">1</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
-              </widget>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="label1">
-                <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label" translatable="yes">General</property>
-              </widget>
-              <packing>
-                <property name="type">tab</property>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox5">
-                <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
-                <property name="border_width">12</property>
-                <property name="spacing">18</property>
                 <child>
-                  <widget class="GtkVBox" id="vbox3">
+                  <widget class="GtkHBox" id="hbox2">
                     <property name="visible">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkLabel" id="label7">
+                      <widget class="GtkLabel" id="label3">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">&lt;b&gt;Network&lt;/b&gt;</property>
-                        <property name="use_markup">True</property>
+                        <property name="label" translatable="yes">       </property>
                       </widget>
                       <packing>
                         <property name="expand">False</property>
@@ -424,145 +120,32 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkHBox" id="hbox4">
+                      <widget class="GtkCheckButton" id="view_only_toggle">
                         <property name="visible">True</property>
-                        <property name="spacing">12</property>
-                        <child>
-                          <widget class="GtkImage" id="network_icon">
-                            <property name="visible">True</property>
-                            <property name="yalign">0</property>
-                            <property name="icon_size">6</property>
-                            <property name="icon_name">network-workgroup</property>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkVBox" id="vbox6">
-                            <property name="visible">True</property>
-                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <widget class="GtkHBox" id="hbox3">
-                                <property name="visible">True</property>
-                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <widget class="GtkLabel" id="network_interface_label">
-                                    <property name="visible">True</property>
-                                    <property name="tooltip" translatable="yes">Which network interface we should listen to.</property>
-                                    <property name="xalign">0</property>
-                                    <property name="label" translatable="yes">_Listen this interface:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">network_interface_combox</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkComboBox" id="network_interface_combox">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="tearoff_title">Click here to change the network interface!</property>
-                                    <property name="button_sensitivity">GTK_SENSITIVITY_ON</property>
-                                    <property name="items" translatable="yes"></property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="padding">1</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkHBox" id="hbox5">
-                                <property name="visible">True</property>
-                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <widget class="GtkCheckButton" id="use_alternative_port_toggle">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                    <property name="has_tooltip">True</property>
-                                    <property name="tooltip" translatable="yes">The server will use another port, instead of the default (5900)</property>
-                                    <property name="label" translatable="yes">_Use an alternative port:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="response_id">0</property>
-                                    <property name="draw_indicator">True</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <widget class="GtkSpinButton" id="alternative_port_entry">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                    <property name="activates_default">True</property>
-                                    <property name="adjustment">0 0 65000 1 10 0</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="padding">1</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkCheckButton" id="disable_background_toggle">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="tooltip" translatable="yes">Disable the wallpaper when successfull connection</property>
-                                <property name="label" translatable="yes">Disable the _wallpaper when connected</property>
-                                <property name="use_underline">True</property>
-                                <property name="response_id">0</property>
-                                <property name="draw_indicator">True</property>
-                              </widget>
-                              <packing>
-                                <property name="position">2</property>
-                              </packing>
-                            </child>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
+                        <property name="can_focus">True</property>
+                        <property name="has_tooltip">True</property>
+                        <property name="tooltip" translatable="yes">Remote users are able to control your mouse and keyboard</property>
+                        <property name="label" translatable="yes">_Allow other users to control your desktop</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
                       </widget>
                       <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </widget>
+                  <packing>
+                    <property name="position">3</property>
+                  </packing>
                 </child>
                 <child>
-                  <widget class="GtkVBox" id="vbox10">
+                  <widget class="GtkHBox" id="message_box">
                     <property name="visible">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkLabel" id="label5">
+                      <widget class="GtkLabel" id="label14">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">&lt;b&gt;Security&lt;/b&gt;</property>
-                        <property name="use_markup">True</property>
+                        <property name="label" translatable="yes">       </property>
                       </widget>
                       <packing>
                         <property name="expand">False</property>
@@ -570,187 +153,184 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkHBox" id="hbox7">
+                      <placeholder/>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">4</property>
+                  </packing>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="security_box">
+                <property name="visible">True</property>
+                <property name="spacing">3</property>
+                <child>
+                  <widget class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Security&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox3">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkCheckButton" id="prompt_enabled_toggle">
                         <property name="visible">True</property>
-                        <property name="spacing">12</property>
-                        <child>
-                          <widget class="GtkImage" id="network_icon2">
-                            <property name="visible">True</property>
-                            <property name="yalign">0</property>
-                            <property name="icon_size">6</property>
-                            <property name="icon_name">system-lock-screen</property>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkVBox" id="vbox11">
-                            <property name="visible">True</property>
-                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <widget class="GtkCheckButton" id="encryption_toggle">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="has_tooltip">True</property>
-                                <property name="tooltip" translatable="yes">Remote users' VNC clients accessing the desktop are required to support encryption</property>
-                                <property name="label" translatable="yes">_Require encryption</property>
-                                <property name="use_underline">True</property>
-                                <property name="response_id">0</property>
-                                <property name="draw_indicator">True</property>
-                              </widget>
-                            </child>
-                            <child>
-                              <widget class="GtkVBox" id="url_labels_box3">
-                                <property name="visible">True</property>
-                                <child>
-                                  <widget class="GtkCheckButton" id="lock_screen_toggle">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                    <property name="has_tooltip">True</property>
-                                    <property name="tooltip" translatable="yes">Screen will be locked after the last remote client disconnect</property>
-                                    <property name="label" translatable="yes">_Lock screen on disconnect</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="response_id">0</property>
-                                    <property name="draw_indicator">True</property>
-                                  </widget>
-                                </child>
-                              </widget>
-                              <packing>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
+                        <property name="can_focus">True</property>
+                        <property name="has_tooltip">True</property>
+                        <property name="tooltip" translatable="yes">You will be queried to allow or to refuse every incoming connection</property>
+                        <property name="label" translatable="yes">_You must confirm each access to this machine</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                      </widget>
+                      <packing>
+                        <property name="padding">12</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox4">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkCheckButton" id="password_toggle">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="label" translatable="yes">_Require the user to enter this password:</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
                       </widget>
                       <packing>
                         <property name="expand">False</property>
-                        <property name="fill">False</property>
+                        <property name="padding">12</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget 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>
+                      </widget>
+                      <packing>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </widget>
                   <packing>
-                    <property name="position">1</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
                 <child>
-                  <widget class="GtkVBox" id="vbox1">
+                  <widget class="GtkHBox" id="hbox7">
                     <property name="visible">True</property>
-                    <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkLabel" id="label2">
+                      <widget class="GtkCheckButton" id="use_upnp_toggle">
                         <property name="visible">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">&lt;b&gt;Notification Area&lt;/b&gt;</property>
-                        <property name="use_markup">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="has_tooltip">True</property>
+                        <property name="tooltip" translatable="yes">The router must have the UPnP feature enabled</property>
+                        <property name="label" translatable="yes">_Talk to the router and try to open the doors there</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
                       </widget>
+                      <packing>
+                        <property name="padding">12</property>
+                      </packing>
                     </child>
+                  </widget>
+                  <packing>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="notification_box">
+                <property name="visible">True</property>
+                <property name="spacing">3</property>
+                <child>
+                  <widget class="GtkLabel" id="label12">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Notification Area&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox8">
+                    <property name="visible">True</property>
                     <child>
-                      <widget class="GtkHBox" id="hbox1">
+                      <widget class="GtkVBox" id="vbox2">
                         <property name="visible">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="spacing">12</property>
+                        <property name="spacing">3</property>
+                        <child>
+                          <widget class="GtkRadioButton" id="icon_always_radio">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="label" translatable="yes">Al_ways display an icon</property>
+                            <property name="use_underline">True</property>
+                            <property name="response_id">0</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                          </widget>
+                        </child>
                         <child>
-                          <widget class="GtkImage" id="notification_icon">
+                          <widget class="GtkRadioButton" id="icon_client_radio">
                             <property name="visible">True</property>
-                            <property name="yalign">0</property>
-                            <property name="icon_size">6</property>
-                            <property name="icon_name">gnome-panel-notification-area</property>
+                            <property name="can_focus">True</property>
+                            <property name="label" translatable="yes">_Only display an icon when there is someone connected</property>
+                            <property name="use_underline">True</property>
+                            <property name="response_id">0</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">icon_always_radio</property>
                           </widget>
                           <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="position">1</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkVBox" id="vbox2">
+                          <widget class="GtkRadioButton" id="icon_never_radio">
                             <property name="visible">True</property>
-                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <widget class="GtkRadioButton" id="icon_always_radio">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="label" translatable="yes">Al_ways display an icon</property>
-                                <property name="use_underline">True</property>
-                                <property name="response_id">0</property>
-                                <property name="active">True</property>
-                                <property name="draw_indicator">True</property>
-                              </widget>
-                            </child>
-                            <child>
-                              <widget class="GtkRadioButton" id="icon_client_radio">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="label" translatable="yes">_Only display an icon when there is someone connected</property>
-                                <property name="use_underline">True</property>
-                                <property name="response_id">0</property>
-                                <property name="active">True</property>
-                                <property name="draw_indicator">True</property>
-                                <property name="group">icon_always_radio</property>
-                              </widget>
-                              <packing>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkRadioButton" id="icon_never_radio">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="label" translatable="yes">_Never display an icon</property>
-                                <property name="use_underline">True</property>
-                                <property name="response_id">0</property>
-                                <property name="active">True</property>
-                                <property name="draw_indicator">True</property>
-                                <property name="group">icon_always_radio</property>
-                              </widget>
-                              <packing>
-                                <property name="position">2</property>
-                              </packing>
-                            </child>
+                            <property name="can_focus">True</property>
+                            <property name="label" translatable="yes">_Never display an icon</property>
+                            <property name="use_underline">True</property>
+                            <property name="response_id">0</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">icon_always_radio</property>
                           </widget>
                           <packing>
-                            <property name="position">1</property>
+                            <property name="position">2</property>
                           </packing>
                         </child>
                       </widget>
                       <packing>
-                        <property name="position">1</property>
+                        <property name="padding">12</property>
                       </packing>
                     </child>
                   </widget>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="position">2</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
               </widget>
               <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="label3">
-                <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label" translatable="yes">Advanced</property>
-              </widget>
-              <packing>
-                <property name="type">tab</property>
-                <property name="position">1</property>
-                <property name="tab_fill">False</property>
+                <property name="position">2</property>
               </packing>
             </child>
           </widget>
@@ -759,27 +339,24 @@
           </packing>
         </child>
         <child internal-child="action_area">
-          <widget class="GtkHButtonBox" id="hbuttonbox1">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
             <property name="visible">True</property>
-            <property name="layout_style">GTK_BUTTONBOX_END</property>
             <child>
-              <widget class="GtkButton" id="helpbutton1">
+              <widget class="GtkButton" id="button1">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="label">gtk-help</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-help</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">-11</property>
               </widget>
             </child>
             <child>
-              <widget class="GtkButton" id="button4">
+              <widget class="GtkButton" id="button2">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="has_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="has_default">True</property>
-                <property name="label">gtk-close</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-close</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">-7</property>
               </widget>

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Wed Jan 21 16:02:03 2009
@@ -46,10 +46,11 @@
 GTK_VERSION=2.13.1
 GLIB_VERSION=2.17.0
 DBUS_VERSION=1.2.3
+SOUP_VERSION=2.24.0
 
 PKG_CHECK_MODULES(VINO_SERVER, glib-2.0 >= $GLIB_VERSION gtk+-x11-2.0 >= $GTK_VERSION gconf-2.0 libglade-2.0 dbus-1 >= $DBUS_VERSION dbus-glib-1 libgnomeui-2.0)
 
-PKG_CHECK_MODULES(VINO_CAPPLET, glib-2.0 >= $GLIB_VERSION gtk+-2.0 >= $GTK_VERSION gconf-2.0 libglade-2.0 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 libglade-2.0 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)
 

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Wed Jan 21 16:02:03 2009
@@ -1,5 +1,7 @@
 # List of source files containing translatable strings.
 # Please keep this file sorted alphabetically.
+capplet/sexy-url-label.c
+capplet/vino-message-box.c
 capplet/vino-preferences.c
 capplet/vino-preferences.desktop.in.in
 capplet/vino-preferences.glade

Modified: trunk/server/vino-dbus-listener.c
==============================================================================
--- trunk/server/vino-dbus-listener.c	(original)
+++ trunk/server/vino-dbus-listener.c	Wed Jan 21 16:02:03 2009
@@ -33,6 +33,10 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <net/if.h>
+#include <ifaddrs.h>
 
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
@@ -42,9 +46,8 @@
 #include "vino-http.h"
 #endif
 
-#define VINO_DBUS_LISTENER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o),                     \
-                                                                        VINO_TYPE_DBUS_LISTENER, \
-                                                                        VinoDBusListenerPrivate))
+#define VINO_DBUS_INTERFACE "org.gnome.VinoScreen"
+#define VINO_DBUS_BUS_NAME  "org.gnome.Vino"
 
 G_DEFINE_TYPE (VinoDBusListener, vino_dbus_listener, G_TYPE_OBJECT)
 
@@ -62,6 +65,33 @@
 static void vino_dbus_listener_set_server (VinoDBusListener *listener,
                                            VinoServer       *server);
 
+static char *
+get_local_hostname (void)
+{
+  static char      local_host [NI_MAXHOST] = { 0, };
+  struct addrinfo  hints;
+  struct addrinfo *results;
+  char            *retval;
+
+  if (gethostname (local_host, NI_MAXHOST) == -1)
+    return NULL;
+
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_flags = AI_CANONNAME;
+
+  results = NULL;
+  if (getaddrinfo (local_host,  NULL, &hints, &results) != 0)
+    return NULL;
+
+  retval = g_strdup (results ? results->ai_canonname : local_host);
+
+  if (results)
+    freeaddrinfo (results);
+
+  return retval;
+}
+
+
 static void
 vino_dbus_listener_set_property (GObject       *object,
                                  guint          prop_id,
@@ -103,7 +133,7 @@
 static void
 vino_dbus_listener_init (VinoDBusListener *listener)
 {
-  listener->priv = VINO_DBUS_LISTENER_GET_PRIVATE (listener);
+  listener->priv = G_TYPE_INSTANCE_GET_PRIVATE (listener, VINO_TYPE_DBUS_LISTENER, VinoDBusListenerPrivate);
 }
 
 static void
@@ -149,16 +179,15 @@
   "    </method>\n"
   "  </interface>\n"
   "  <interface name=\"org.gnome.VinoScreen\">\n"
-  "    <method name=\"GetServerPort\">\n"
-  "      <arg name=\"port\" direction=\"out\" type=\"u\"/>\n"
+  "    <method name=\"GetInternalData\">\n"
+  "      <arg name=\"hostname\" direction=\"out\" type=\"s\"/>\n"
+  "      <arg name=\"port\" direction=\"out\" type=\"d\"/>\n"
   "    </method>\n"
-  "    <signal name=\"ServerPortChanged\">\n"
-  "    </signal>\n"
-#ifdef VINO_ENABLE_HTTP_SERVER
-  "    <method name=\"GetHttpServerPort\">\n"
-  "      <arg name=\"port\" direction=\"out\" type=\"u\"/>\n"
+  "    <method name=\"GetExternalPort\">\n"
+  "      <arg name=\"port\" direction=\"out\" type=\"d\"/>\n"
   "    </method>\n"
-#endif
+  "    <signal name=\"ServerInfoChanged\">\n"
+  "    </signal>\n"
   "  </interface>\n"
   "</node>\n";
 
@@ -196,13 +225,13 @@
                                            DBusConnection   *connection,
                                            DBusMessage      *message)
 {
-  DBusMessage  *reply;
-  dbus_int32_t  port;
+  DBusMessage *reply;
+  gint        port;
 
   if (!(reply = dbus_message_new_method_return (message)))
     goto oom;
 
-  port = vino_server_get_port (listener->priv->server);
+  port = vino_server_get_external_port (listener->priv->server);
 
   if (!dbus_message_append_args (reply, DBUS_TYPE_INT32, &port, DBUS_TYPE_INVALID))
     goto oom;
@@ -221,21 +250,29 @@
   return DBUS_HANDLER_RESULT_NEED_MEMORY;
 }
 
-#ifdef VINO_ENABLE_HTTP_SERVER
 static DBusHandlerResult
-vino_dbus_listener_handle_get_http_server_port (VinoDBusListener *listener,
-                                                DBusConnection   *connection,
-                                                DBusMessage      *message)
+vino_dbus_listener_handle_get_internal_data (VinoDBusListener *listener,
+                                             DBusConnection   *connection,
+                                             DBusMessage      *message)
 {
-  DBusMessage  *reply;
-  dbus_int32_t  port;
+  DBusMessage *reply;
+  gint        port;
+  char        *host = NULL;
 
   if (!(reply = dbus_message_new_method_return (message)))
     goto oom;
 
-  port = vino_get_http_server_port();
+#ifdef VINO_ENABLE_HTTP_SERVER
+  port = vino_get_http_server_port (listener->priv->server));
+#else
+  port = vino_server_get_port (listener->priv->server);
+#endif
 
-  if (!dbus_message_append_args (reply, DBUS_TYPE_INT32, &port, DBUS_TYPE_INVALID))
+  host = get_local_hostname ();
+  if (!dbus_message_append_args (reply,
+                                 DBUS_TYPE_STRING, &host,
+                                 DBUS_TYPE_INT32, &port,
+                                 DBUS_TYPE_INVALID))
     goto oom;
 
   if (!dbus_connection_send (connection, reply, NULL))
@@ -243,23 +280,22 @@
     
   dbus_message_unref (reply);
 
-  dprintf (DBUS, "Successfully handled '%s' message: port = %d\n", dbus_message_get_member (message), port);
+  dprintf (DBUS, "Successfully handled '%s' message\n", dbus_message_get_member (message));
 
   return DBUS_HANDLER_RESULT_HANDLED;
 
  oom:
+
+  g_free (host);
   g_error (_("Out of memory handling '%s' message"), dbus_message_get_member (message));
   return DBUS_HANDLER_RESULT_NEED_MEMORY;
 }
-#endif /* VINO_ENABLE_HTTP_SERVER */
 
 static DBusHandlerResult
 vino_dbus_listener_message_handler (DBusConnection *connection,
                                     DBusMessage    *message,
                                     void           *user_data)
 {
-#define VINO_DBUS_INTERFACE "org.gnome.VinoScreen"
-
   VinoDBusListener *listener = VINO_DBUS_LISTENER (user_data);
 
   dprintf (DBUS, "D-Bus message: obj_path = '%s' interface = '%s' method = '%s' destination = '%s'\n",
@@ -270,22 +306,20 @@
 
   if (dbus_message_is_method_call (message,
                                    VINO_DBUS_INTERFACE,
-                                   "GetServerPort"))
+                                   "GetInternalData"))
     {
-      return vino_dbus_listener_handle_get_server_port (listener,
-                                                        connection,
-                                                        message);
+      return vino_dbus_listener_handle_get_internal_data (listener,
+                                                          connection,
+                                                          message);
     }
-#ifdef VINO_ENABLE_HTTP_SERVER
-  else if (dbus_message_is_method_call (message,
+  if (dbus_message_is_method_call (message,
                                    VINO_DBUS_INTERFACE,
-                                   "GetHttpServerPort"))
+                                   "GetExternalPort"))
     {
-      return vino_dbus_listener_handle_get_http_server_port (listener,
-                                                             connection,
-                                                             message);
+      return vino_dbus_listener_handle_get_server_port (listener,
+                                                        connection,
+                                                        message);
     }
-#endif
   else if (dbus_message_is_method_call (message,
                                         "org.freedesktop.DBus.Introspectable",
                                         "Introspect"))
@@ -298,24 +332,22 @@
     {
       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
-
-#undef VINO_DBUS_INTERFACE
 }
 
 static void
-vino_dbus_listener_port_changed (VinoServer *server, VinoDBusListener *listener)
+vino_dbus_listener_info_changed (VinoServer *server, VinoDBusListener *listener)
 {
   DBusMessage *message;
   gchar *obj_path;
 
-  dprintf (DBUS, "Emitting ServerPortChanged signal\n");
+  dprintf (DBUS, "Emitting ServerInfoChanged signal\n");
 
   obj_path = g_strdup_printf ("/org/gnome/vino/screens/%d",
                               gdk_screen_get_number (vino_server_get_screen (server)));
 
   message = dbus_message_new_signal (obj_path,
-                                     "org.gnome.VinoScreen",
-                                     "ServerPortChanged");
+                                     VINO_DBUS_INTERFACE,
+                                     "ServerInfoChanged");
   g_free (obj_path);
 
   if (!message)
@@ -369,12 +401,8 @@
   dprintf (DBUS, "Object registered at path '%s'\n", obj_path);
 
   g_signal_connect (server, "notify::alternative-port",
-		    G_CALLBACK (vino_dbus_listener_port_changed),
-		    listener);
-  g_signal_connect (server, "notify::use-alternative-port",
-		    G_CALLBACK (vino_dbus_listener_port_changed),
+		    G_CALLBACK (vino_dbus_listener_info_changed),
 		    listener);
-
   g_free (obj_path);
 }
 
@@ -428,7 +456,6 @@
 gboolean
 vino_dbus_request_name (void)
 {
-#define VINO_DBUS_BUS_NAME "org.gnome.Vino"
 
   DBusConnection *connection;
   DBusError       error;
@@ -459,6 +486,4 @@
 
   dprintf (DBUS, "Successfully acquired D-Bus name '%s'\n", VINO_DBUS_BUS_NAME);
   return TRUE;
-
-#undef VINO_DBUS_BUS_NAME
 }

Modified: trunk/server/vino-server.c
==============================================================================
--- trunk/server/vino-server.c	(original)
+++ trunk/server/vino-server.c	Wed Jan 21 16:02:03 2009
@@ -1545,6 +1545,7 @@
         }
 
       g_object_notify (G_OBJECT (server), "use-alternative-port");
+      g_object_notify (G_OBJECT (server), "alternative-port");
     }
 }
 
@@ -1773,6 +1774,16 @@
   return server->priv->rfb_screen->rfbPort;
 }
 
+int
+vino_server_get_external_port (VinoServer *server)
+{
+  g_return_val_if_fail (VINO_IS_SERVER (server), 0);
+
+  return server->priv->use_upnp && VINO_IS_UPNP (server->priv->upnp) ?
+           vino_upnp_get_external_port (server->priv->upnp) :
+           server->priv->rfb_screen->rfbPort;
+}
+
 gboolean
 vino_server_get_lock_screen (VinoServer *server)
 {
@@ -1797,7 +1808,6 @@
     }
 }
 
-
 VinoStatusIcon *
 vino_server_get_status_icon (VinoServer *server)
 {

Modified: trunk/server/vino-server.h
==============================================================================
--- trunk/server/vino-server.h	(original)
+++ trunk/server/vino-server.h	Wed Jan 21 16:02:03 2009
@@ -85,6 +85,7 @@
 void                 vino_server_set_alternative_port     (VinoServer     *server,
 							   int             alternative_port);
 int                  vino_server_get_port                 (VinoServer     *server);
+int                  vino_server_get_external_port        (VinoServer     *server);
 
 void                 vino_server_set_network_interface    (VinoServer     *server,
                                                            const char     *network_interface);
@@ -111,7 +112,7 @@
 gboolean             vino_server_get_use_upnp              (VinoServer     *server);
 
 #include "vino-status-icon.h"
-VinoStatusIcon      *vino_server_get_status_icon          (VinoServer     *server);
+VinoStatusIcon      *vino_server_get_status_icon          (VinoServer      *server);
 
 G_CONST_RETURN char *vino_client_get_hostname (VinoClient *client);
 void                 vino_client_disconnect   (VinoClient *client);



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