vino r1049 - in trunk: . capplet po server
- From: jwendell svn gnome org
- To: svn-commits-list gnome org
- Subject: vino r1049 - in trunk: . capplet po server
- Date: Wed, 21 Jan 2009 16:02:03 +0000 (UTC)
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"><b>Sharing</b></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"><b>Sharing</b></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"><i>Some of these preferences are locked down</i></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"><b>Security</b></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"><b>Network</b></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"><b>Security</b></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"><b>Security</b></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"><b>Notification Area</b></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"><b>Notification Area</b></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]