[vinagre] Added the option to keep the aspect ratio when using scaling.



commit 12a94e0822dcc682c6aee46b324e0d6486da78cd
Author: Jonh Wendell <jwendell gnome org>
Date:   Tue Feb 2 11:38:27 2010 -0300

    Added the option to keep the aspect ratio when using scaling.
    
    Closes #599594.

 plugins/vnc/vinagre-vnc-connection.c |   51 +++++++++++-
 plugins/vnc/vinagre-vnc-connection.h |    4 +
 plugins/vnc/vinagre-vnc-plugin.c     |   53 +++++++++---
 plugins/vnc/vinagre-vnc-tab.c        |  154 ++++++++++++++++++++++------------
 plugins/vnc/vinagre-vnc-tab.h        |    2 +
 5 files changed, 196 insertions(+), 68 deletions(-)
---
diff --git a/plugins/vnc/vinagre-vnc-connection.c b/plugins/vnc/vinagre-vnc-connection.c
index 82a9099..20e3163 100644
--- a/plugins/vnc/vinagre-vnc-connection.c
+++ b/plugins/vnc/vinagre-vnc-connection.c
@@ -31,6 +31,7 @@ struct _VinagreVncConnectionPrivate
   gchar    *desktop_name;
   gboolean view_only;
   gboolean scaling;
+  gboolean keep_ratio;
   gint     shared;
   gint     fd;
   gint     depth_profile;
@@ -44,6 +45,7 @@ enum
   PROP_DESKTOP_NAME,
   PROP_VIEW_ONLY,
   PROP_SCALING,
+  PROP_KEEP_RATIO,
   PROP_SHARED,
   PROP_FD,
   PROP_DEPTH_PROFILE,
@@ -62,6 +64,7 @@ vinagre_vnc_connection_init (VinagreVncConnection *conn)
   conn->priv->desktop_name = NULL;
   conn->priv->view_only = FALSE;
   conn->priv->scaling = FALSE;
+  conn->priv->keep_ratio = FALSE;
   conn->priv->shared = -1;
   conn->priv->fd = 0;
   conn->priv->depth_profile = 0;
@@ -109,6 +112,10 @@ vinagre_vnc_connection_set_property (GObject *object, guint prop_id, const GValu
 	vinagre_vnc_connection_set_scaling (conn, g_value_get_boolean (value));
 	break;
 
+      case PROP_KEEP_RATIO:
+	vinagre_vnc_connection_set_keep_ratio (conn, g_value_get_boolean (value));
+	break;
+
       case PROP_SHARED:
 	vinagre_vnc_connection_set_shared (conn, g_value_get_int (value));
 	break;
@@ -158,6 +165,10 @@ vinagre_vnc_connection_get_property (GObject *object, guint prop_id, GValue *val
 	g_value_set_boolean (value, conn->priv->scaling);
 	break;
 
+      case PROP_KEEP_RATIO:
+	g_value_set_boolean (value, conn->priv->keep_ratio);
+	break;
+
       case PROP_SHARED:
 	g_value_set_int (value, conn->priv->shared);
 	break;
@@ -192,6 +203,7 @@ vnc_fill_writer (VinagreConnection *conn, xmlTextWriter *writer)
 
   xmlTextWriterWriteFormatElement (writer, (const xmlChar *)"view_only", "%d", vnc_conn->priv->view_only);
   xmlTextWriterWriteFormatElement (writer, (const xmlChar *)"scaling", "%d", vnc_conn->priv->scaling);
+  xmlTextWriterWriteFormatElement (writer, (const xmlChar *)"keep_ratio", "%d", vnc_conn->priv->keep_ratio);
   xmlTextWriterWriteFormatElement (writer, (const xmlChar *)"depth_profile", "%d", vnc_conn->priv->depth_profile);
   xmlTextWriterWriteFormatElement (writer, (const xmlChar *)"lossy_encoding", "%d", vnc_conn->priv->lossy_encoding);
 
@@ -221,6 +233,10 @@ vnc_parse_item (VinagreConnection *conn, xmlNode *root)
 	  if (!scaling_command_line)
 	    vinagre_vnc_connection_set_scaling (vnc_conn, vinagre_utils_parse_boolean ((const gchar *)s_value));
 	}
+      else if (!xmlStrcmp(curr->name, (const xmlChar *)"keep_ratio"))
+	{
+	  vinagre_vnc_connection_set_keep_ratio (vnc_conn, vinagre_utils_parse_boolean ((const gchar *)s_value));
+	}
       else if (!xmlStrcmp(curr->name, (const xmlChar *)"depth_profile"))
 	{
 	  vinagre_vnc_connection_set_depth_profile (vnc_conn, atoi((const char *)s_value));
@@ -277,14 +293,15 @@ vnc_fill_conn_from_file (VinagreConnection *conn, GKeyFile *file)
 static void
 vnc_parse_options_widget (VinagreConnection *conn, GtkWidget *widget)
 {
-  GtkWidget *view_only, *scaling, *depth_combo, *lossy, *ssh_host;
+  GtkWidget *view_only, *scaling, *depth_combo, *lossy, *ssh_host, *ratio;
 
   view_only = g_object_get_data (G_OBJECT (widget), "view_only");
   scaling = g_object_get_data (G_OBJECT (widget), "scaling");
+  ratio = g_object_get_data (G_OBJECT (widget), "ratio");
   depth_combo = g_object_get_data (G_OBJECT (widget), "depth_combo");
   lossy = g_object_get_data (G_OBJECT (widget), "lossy");
   ssh_host = g_object_get_data (G_OBJECT (widget), "ssh_host");
-  if (!view_only || !scaling || !depth_combo || !lossy || !ssh_host)
+  if (!view_only || !scaling || !depth_combo || !lossy || !ssh_host || !ratio)
     {
       g_warning ("Wrong widget passed to vnc_parse_options_widget()");
       return;
@@ -292,6 +309,7 @@ vnc_parse_options_widget (VinagreConnection *conn, GtkWidget *widget)
 
   vinagre_cache_prefs_set_boolean ("vnc-connection", "view-only", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view_only)));
   vinagre_cache_prefs_set_boolean ("vnc-connection", "scaling", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scaling)));
+  vinagre_cache_prefs_set_boolean ("vnc-connection", "keep-ratio", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ratio)));
   vinagre_cache_prefs_set_integer ("vnc-connection", "depth-profile", gtk_combo_box_get_active (GTK_COMBO_BOX (depth_combo)));
   vinagre_cache_prefs_set_boolean ("vnc-connection", "lossy-encoding", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lossy)));
   vinagre_cache_prefs_set_string  ("vnc-connection", "ssh-tunnel-host", gtk_entry_get_text (GTK_ENTRY (ssh_host)));
@@ -299,6 +317,7 @@ vnc_parse_options_widget (VinagreConnection *conn, GtkWidget *widget)
   g_object_set (conn,
 		"view-only", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view_only)),
 		"scaling", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scaling)),
+		"keep-ratio", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ratio)),
 		"depth-profile", gtk_combo_box_get_active (GTK_COMBO_BOX (depth_combo)),
 		"lossy-encoding", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lossy)),
 		"ssh-tunnel-host", gtk_entry_get_text (GTK_ENTRY (ssh_host)),
@@ -360,6 +379,18 @@ vinagre_vnc_connection_class_init (VinagreVncConnectionClass *klass)
                                                         G_PARAM_STATIC_BLURB));
 
   g_object_class_install_property (object_class,
+                                   PROP_KEEP_RATIO,
+                                   g_param_spec_boolean ("keep-ratio",
+                                                        "Keep Ratio",
+	                                                "Whether to keep the aspect ratio when using scaling",
+                                                        FALSE,
+	                                                G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
                                    PROP_SHARED,
                                    g_param_spec_int ("shared",
                                                      "shared flag",
@@ -500,6 +531,22 @@ vinagre_vnc_connection_get_scaling (VinagreVncConnection *conn)
 }
 
 void
+vinagre_vnc_connection_set_keep_ratio (VinagreVncConnection *conn,
+				       gboolean value)
+{
+  g_return_if_fail (VINAGRE_IS_VNC_CONNECTION (conn));
+
+  conn->priv->keep_ratio = value;
+}
+gboolean
+vinagre_vnc_connection_get_keep_ratio (VinagreVncConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_VNC_CONNECTION (conn), FALSE);
+
+  return conn->priv->keep_ratio;
+}
+
+void
 vinagre_vnc_connection_set_fd (VinagreVncConnection *conn,
 			       gint                 value)
 {
diff --git a/plugins/vnc/vinagre-vnc-connection.h b/plugins/vnc/vinagre-vnc-connection.h
index 8d456c7..7c45d72 100644
--- a/plugins/vnc/vinagre-vnc-connection.h
+++ b/plugins/vnc/vinagre-vnc-connection.h
@@ -67,6 +67,10 @@ gboolean	    vinagre_vnc_connection_get_scaling      (VinagreVncConnection *conn
 void		    vinagre_vnc_connection_set_scaling      (VinagreVncConnection *conn,
 							     gboolean value);
 
+gboolean	    vinagre_vnc_connection_get_keep_ratio   (VinagreVncConnection *conn);
+void		    vinagre_vnc_connection_set_keep_ratio   (VinagreVncConnection *conn,
+							     gboolean value);
+
 gint		    vinagre_vnc_connection_get_shared       (VinagreVncConnection *conn);
 void		    vinagre_vnc_connection_set_shared       (VinagreVncConnection *conn,
 							     gint value);
diff --git a/plugins/vnc/vinagre-vnc-plugin.c b/plugins/vnc/vinagre-vnc-plugin.c
index dc741d0..074cd5f 100644
--- a/plugins/vnc/vinagre-vnc-plugin.c
+++ b/plugins/vnc/vinagre-vnc-plugin.c
@@ -352,13 +352,22 @@ ssh_tunnel_check_toggled_cb (GtkToggleButton *button, GObject *box)
     gtk_entry_set_text (GTK_ENTRY (ssh_host_entry), "");
 }
 
+static void
+scaling_check_toggled_cb (GtkToggleButton *button, GObject *box)
+{
+  gboolean active = gtk_toggle_button_get_active (button);
+  GtkWidget *ratio = g_object_get_data (G_OBJECT (box), "ratio");
+
+  gtk_widget_set_sensitive (ratio, active);
+}
+
 static GtkWidget *
 impl_get_connect_widget (VinagrePlugin *plugin, VinagreConnection *conn)
 {
-  GtkWidget *box, *check, *label, *combo, *depth_box, *ssh_box, *ssh_host_entry;
+  GtkWidget *box, *check, *label, *combo, *box2, *ssh_host_entry;
   GtkTable  *table;
   gchar     *str, *ssh_host;
-  gboolean has_conn = VINAGRE_IS_VNC_CONNECTION (conn);
+  gboolean has_conn = VINAGRE_IS_VNC_CONNECTION (conn), active;
 
   box = gtk_vbox_new (FALSE, 0);
 
@@ -370,7 +379,7 @@ impl_get_connect_widget (VinagrePlugin *plugin, VinagreConnection *conn)
   gtk_misc_set_padding (GTK_MISC (label), 0, 6);
   gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
 
-  table = GTK_TABLE (gtk_table_new (5, 2, FALSE));
+  table = GTK_TABLE (gtk_table_new (6, 2, FALSE));
   label = gtk_label_new ("  ");
   gtk_table_attach (table, label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
 
@@ -389,21 +398,39 @@ impl_get_connect_widget (VinagrePlugin *plugin, VinagreConnection *conn)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
 				has_conn ? vinagre_vnc_connection_get_scaling (VINAGRE_VNC_CONNECTION (conn))
 				: vinagre_cache_prefs_get_boolean ("vnc-connection", "scaling", FALSE));
+  active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check));
+  g_signal_connect (check,
+		    "toggled",
+		    G_CALLBACK (scaling_check_toggled_cb),
+		    box);
+
+  /* Keep ratio check button */
+  box2 = gtk_hbox_new (FALSE, 4);
+  label = gtk_label_new ("   ");
+  gtk_box_pack_start (GTK_BOX (box2), GTK_WIDGET (label), FALSE, FALSE, 0);
+  check = gtk_check_button_new_with_mnemonic (_("_Keep aspect ratio"));
+  gtk_box_pack_start (GTK_BOX (box2), check, TRUE, TRUE, 0);
+  g_object_set_data (G_OBJECT (box), "ratio", check);
+  gtk_table_attach_defaults (table, box2, 1, 2, 2, 3);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
+				has_conn ? vinagre_vnc_connection_get_keep_ratio (VINAGRE_VNC_CONNECTION (conn))
+				: vinagre_cache_prefs_get_boolean ("vnc-connection", "keep-ratio", TRUE));
+  gtk_widget_set_sensitive (check, active);
 
   /* JPEG Compression check button */
   check = gtk_check_button_new_with_mnemonic (_("_Use JPEG Compression"));
   gtk_widget_set_tooltip_text (check, _("This might not work on all VNC servers"));
   g_object_set_data (G_OBJECT (box), "lossy", check);
-  gtk_table_attach_defaults (table, check, 1, 2, 2, 3);
+  gtk_table_attach_defaults (table, check, 1, 2, 3, 4);
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
 				has_conn ? vinagre_vnc_connection_get_lossy_encoding (VINAGRE_VNC_CONNECTION (conn))
 				: vinagre_cache_prefs_get_boolean ("vnc-connection", "lossy-encoding", FALSE));
 
   /* Depth color combo box */
-  depth_box = gtk_hbox_new (FALSE, 4);
+  box2 = gtk_hbox_new (FALSE, 4);
   label = gtk_label_new_with_mnemonic (_("_Depth Color:"));
   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-  gtk_box_pack_start (GTK_BOX (depth_box), GTK_WIDGET (label), FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (box2), GTK_WIDGET (label), FALSE, FALSE, 0);
 
   combo = gtk_combo_box_new_text ();
   gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Use Server Settings"));
@@ -416,28 +443,28 @@ impl_get_connect_widget (VinagrePlugin *plugin, VinagreConnection *conn)
 			    : vinagre_cache_prefs_get_integer ("vnc-connection", "depth-profile", 0));
   g_object_set_data (G_OBJECT (box), "depth_combo", combo);
   gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
-  gtk_box_pack_start (GTK_BOX (depth_box), GTK_WIDGET (combo), FALSE, FALSE, 0);
-  gtk_table_attach_defaults (table, depth_box, 1, 2, 3, 4);
+  gtk_box_pack_start (GTK_BOX (box2), GTK_WIDGET (combo), FALSE, FALSE, 0);
+  gtk_table_attach_defaults (table, box2, 1, 2, 4, 5);
 
   /* SSH Tunneling */
-  ssh_box = gtk_hbox_new (FALSE, 4);
+  box2 = gtk_hbox_new (FALSE, 4);
 
   /* Translators: the whole sentence will be: Use host <hostname> as a SSH tunnel*/
   check = gtk_check_button_new_with_mnemonic (_("Use h_ost"));
   g_object_set_data (G_OBJECT (box), "use_ssh", check);
-  gtk_box_pack_start (GTK_BOX (ssh_box), check, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (box2), check, FALSE, FALSE, 0);
 
   ssh_host_entry = gtk_entry_new ();
   gtk_widget_set_sensitive (ssh_host_entry, FALSE);
   g_object_set_data (G_OBJECT (box), "ssh_host", ssh_host_entry);
   /* Translators: This is the tooltip of the SSH tunneling entry */
   gtk_widget_set_tooltip_text (ssh_host_entry, _("hostname or user hostname"));
-  gtk_box_pack_start (GTK_BOX (ssh_box), ssh_host_entry, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (box2), ssh_host_entry, FALSE, FALSE, 0);
 
   /* Translators: the whole sentence will be: Use host <hostname> as a SSH tunnel*/
   label = gtk_label_new_with_mnemonic (_("as a SSH tunnel"));
   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-  gtk_box_pack_start (GTK_BOX (ssh_box), label, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
 
   g_signal_connect (check,
 		    "toggled",
@@ -451,7 +478,7 @@ impl_get_connect_widget (VinagrePlugin *plugin, VinagreConnection *conn)
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), ssh_host && *ssh_host);
   g_free (ssh_host);
 
-  gtk_table_attach_defaults (table, ssh_box, 1, 2, 4, 5);
+  gtk_table_attach_defaults (table, box2, 1, 2, 5, 6);
 
   gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (table), FALSE, FALSE, 0);
   return box;
diff --git a/plugins/vnc/vinagre-vnc-tab.c b/plugins/vnc/vinagre-vnc-tab.c
index ad8dfba..b8f668e 100644
--- a/plugins/vnc/vinagre-vnc-tab.c
+++ b/plugins/vnc/vinagre-vnc-tab.c
@@ -34,13 +34,13 @@
 
 struct _VinagreVncTabPrivate
 {
-  GtkWidget  *vnc;
+  GtkWidget  *vnc, *align;
   gboolean   pointer_grab;
   gchar      *clipboard_str;
   GSList     *connected_actions, *initialized_actions;
   GtkWidget  *viewonly_button, *scaling_button;
-  GtkAction  *scaling_action, *viewonly_action, *original_size_action;
-  gulong     signal_clipboard;
+  GtkAction  *scaling_action, *viewonly_action, *original_size_action, *keep_ratio_action;
+  gulong     signal_clipboard, signal_align;
 };
 
 G_DEFINE_TYPE (VinagreVncTab, vinagre_vnc_tab, VINAGRE_TYPE_TAB)
@@ -86,6 +86,13 @@ view_scaling_cb (GtkAction *action, VinagreVncTab *vnc_tab)
 }
 
 static void
+view_keep_ratio_cb (GtkAction *action, VinagreVncTab *vnc_tab)
+{
+  vinagre_vnc_tab_set_keep_ratio (vnc_tab,
+				  gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+}
+
+static void
 view_viewonly_cb (GtkAction *action, VinagreVncTab *vnc_tab)
 {
   vinagre_vnc_tab_set_viewonly (vnc_tab,
@@ -410,17 +417,19 @@ vnc_initialized_cb (VncDisplay *vnc, VinagreVncTab *vnc_tab)
 {
   GtkLabel *label;
   gchar    *name;
-  gboolean scaling, view_only, fullscreen;
+  gboolean scaling, view_only, fullscreen, keep_ratio;
   VinagreTab *tab = VINAGRE_TAB (vnc_tab);
   VinagreConnection *conn = vinagre_tab_get_conn (tab);
 
   g_object_get (conn,
 		"view-only", &view_only,
 		"scaling", &scaling,
+		"keep_ratio", &keep_ratio,
 		"fullscreen", &fullscreen,
 		NULL);
 
   gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (vnc_tab->priv->scaling_action), scaling);
+  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (vnc_tab->priv->keep_ratio_action), keep_ratio);
   gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (vnc_tab->priv->viewonly_action), view_only);
   vnc_display_set_pointer_local (vnc, TRUE);
   vnc_display_set_keyboard_grab (vnc, TRUE);
@@ -599,6 +608,20 @@ create_connected_actions (VinagreVncTab *tab)
   list = g_slist_append (list, a);
   tab->priv->scaling_action = a->action;
 
+  /* View->Keep Ratio */
+  a = g_new (VinagreTabUiAction, 1);
+  a->paths = g_new (gchar *, 2);
+  a->paths[0] = g_strdup ("/MenuBar/ViewMenu");
+  a->paths[1] = NULL;
+  a->action = GTK_ACTION (gtk_toggle_action_new ("VNCViewKeepRatio",
+						 _("_Keep Aspect Ratio"),
+						 _("Keeps the screen aspect ratio when using scaling"),
+						 NULL));
+  gtk_action_set_sensitive (a->action, FALSE);
+  g_signal_connect (a->action, "activate", G_CALLBACK (view_keep_ratio_cb), tab);
+  list = g_slist_append (list, a);
+  tab->priv->keep_ratio_action = a->action;
+
   /* View->View Only */
   a = g_new (VinagreTabUiAction, 1);
   a->paths = g_new (gchar *, 3);
@@ -757,52 +780,10 @@ vnc_tab_clipboard_cb (GtkClipboard *cb, GdkEvent *event, VinagreVncTab *vnc_tab)
   g_free (text);
 }
 
-/*
- * Called when the main container widget's size has been set.
- * It attempts to fit the VNC widget into this space while
- * maintaining aspect ratio
- *
- * Code borrowed from from virt-viewer, thanks Daniel Berrange :)
- */
-static void
-vnc_tab_resize_align (GtkWidget *widget,
-		      GtkAllocation *alloc,
-		      VinagreVncTab *vnc_tab)
-{
-  double desktopAspect = (double)vnc_display_get_width (VNC_DISPLAY (vnc_tab->priv->vnc)) / (double)vnc_display_get_height (VNC_DISPLAY (vnc_tab->priv->vnc));
-  double scrollAspect = (double)alloc->width / (double)alloc->height;
-  int height, width;
-  GtkAllocation child;
-  int dx = 0, dy = 0;
-
-  if (!vnc_display_is_open (VNC_DISPLAY (vnc_tab->priv->vnc)))
-    return;
-
-  if (scrollAspect > desktopAspect)
-    {
-      width = alloc->height * desktopAspect;
-      dx = (alloc->width - width) / 2;
-      height = alloc->height;
-    }
-  else
-    {
-      width = alloc->width;
-      height = alloc->width / desktopAspect;
-      dy = (alloc->height - height) / 2;
-    }
-
-  child.x = alloc->x + dx;
-  child.y = alloc->y + dy;
-  child.width = width;
-  child.height = height;
-  gtk_widget_size_allocate(vnc_tab->priv->vnc, &child);
-}
-
 static void
 vinagre_vnc_tab_init (VinagreVncTab *vnc_tab)
 {
   GtkClipboard *cb;
-  GtkWidget *align;
 
   vnc_tab->priv = VINAGRE_VNC_TAB_GET_PRIVATE (vnc_tab);
   vnc_tab->priv->clipboard_str = NULL;
@@ -811,13 +792,11 @@ vinagre_vnc_tab_init (VinagreVncTab *vnc_tab)
 
   /* Create the vnc widget */
   vnc_tab->priv->vnc = vnc_display_new ();
-  align = gtk_alignment_new (0.5, 0.5, 1, 1);
+  vnc_tab->priv->align = gtk_alignment_new (0.5, 0.5, 1, 1);
+  vnc_tab->priv->signal_align = 0;
+  gtk_container_add (GTK_CONTAINER (vnc_tab->priv->align), vnc_tab->priv->vnc);
 
-  g_signal_connect(align, "size-allocate",
-		  G_CALLBACK (vnc_tab_resize_align), vnc_tab);
-  gtk_container_add (GTK_CONTAINER (align), vnc_tab->priv->vnc);
-
-  vinagre_tab_add_view (VINAGRE_TAB (vnc_tab), align);
+  vinagre_tab_add_view (VINAGRE_TAB (vnc_tab), vnc_tab->priv->align);
 
   g_signal_connect (vnc_tab->priv->vnc,
 		    "vnc-connected",
@@ -944,6 +923,7 @@ vinagre_vnc_tab_set_scaling (VinagreVncTab *tab, gboolean active) {
 
   gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (tab->priv->scaling_button),
 				     active);
+  gtk_action_set_sensitive (tab->priv->keep_ratio_action, active);
 
   if (active)
     gtk_widget_set_size_request (tab->priv->vnc, 0, 0);
@@ -969,7 +949,6 @@ vinagre_vnc_tab_set_viewonly (VinagreVncTab *tab, gboolean active) {
   vnc_display_set_read_only (VNC_DISPLAY (tab->priv->vnc), active);
   gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (tab->priv->viewonly_button),
 				     active);
-
 }
 
 gboolean
@@ -979,6 +958,75 @@ vinagre_vnc_tab_get_viewonly (VinagreVncTab *tab) {
   return vnc_display_get_read_only (VNC_DISPLAY (tab->priv->vnc));
 }
 
+/*
+ * Called when the main container widget's size has been set.
+ * It attempts to fit the VNC widget into this space while
+ * maintaining aspect ratio
+ *
+ * Code borrowed from from virt-viewer, thanks Daniel Berrange :)
+ */
+
+static void
+vnc_tab_resize_align (GtkWidget *widget,
+		      GtkAllocation *alloc,
+		      VinagreVncTab *vnc_tab)
+{
+  double desktopAspect = (double)vnc_display_get_width (VNC_DISPLAY (vnc_tab->priv->vnc)) / (double)vnc_display_get_height (VNC_DISPLAY (vnc_tab->priv->vnc));
+  double scrollAspect = (double)alloc->width / (double)alloc->height;
+  int height, width;
+  GtkAllocation child;
+  int dx = 0, dy = 0;
+
+  if (!vnc_display_is_open (VNC_DISPLAY (vnc_tab->priv->vnc)))
+    return;
+
+  if (scrollAspect > desktopAspect)
+    {
+      width = alloc->height * desktopAspect;
+      dx = (alloc->width - width) / 2;
+      height = alloc->height;
+    }
+  else
+    {
+      width = alloc->width;
+      height = alloc->width / desktopAspect;
+      dy = (alloc->height - height) / 2;
+    }
+
+  child.x = alloc->x + dx;
+  child.y = alloc->y + dy;
+  child.width = width;
+  child.height = height;
+  gtk_widget_size_allocate(vnc_tab->priv->vnc, &child);
+}
+
+void
+vinagre_vnc_tab_set_keep_ratio (VinagreVncTab *tab, gboolean active)
+{
+  g_return_if_fail (VINAGRE_IS_VNC_TAB (tab));
+
+  if (tab->priv->signal_align > 0)
+    g_signal_handler_disconnect (tab->priv->align, tab->priv->signal_align);
+
+  if (active)
+    tab->priv->signal_align = g_signal_connect (tab->priv->align,
+						"size-allocate",
+						G_CALLBACK (vnc_tab_resize_align),
+						tab);
+  else
+    tab->priv->signal_align = 0;
+
+  gtk_widget_queue_resize_no_redraw (tab->priv->align);
+}
+
+gboolean
+vinagre_vnc_tab_get_keep_ratio (VinagreVncTab *tab)
+{
+  g_return_val_if_fail (VINAGRE_IS_VNC_TAB (tab), FALSE);
+
+  return vinagre_vnc_connection_get_keep_ratio (VINAGRE_VNC_CONNECTION (vinagre_tab_get_conn (VINAGRE_TAB (tab))));
+}
+
 gboolean
 vinagre_vnc_tab_is_pointer_grab (VinagreVncTab *tab)
 {
diff --git a/plugins/vnc/vinagre-vnc-tab.h b/plugins/vnc/vinagre-vnc-tab.h
index 7f6eddb..a5dc611 100644
--- a/plugins/vnc/vinagre-vnc-tab.h
+++ b/plugins/vnc/vinagre-vnc-tab.h
@@ -61,6 +61,8 @@ void		vinagre_vnc_tab_paste_text		(VinagreVncTab *tab,
 
 gboolean	vinagre_vnc_tab_set_scaling		(VinagreVncTab *tab, gboolean active);
 gboolean	vinagre_vnc_tab_get_scaling		(VinagreVncTab *tab);
+void		vinagre_vnc_tab_set_keep_ratio		(VinagreVncTab *tab, gboolean active);
+gboolean	vinagre_vnc_tab_get_keep_ratio		(VinagreVncTab *tab);
 void		vinagre_vnc_tab_set_viewonly		(VinagreVncTab *tab, gboolean active);
 gboolean	vinagre_vnc_tab_get_viewonly		(VinagreVncTab *tab);
 



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