[vinagre] Initial work to make vinagre a generic viewer



commit 747ff32dd203651a5dc64a568b9219a0557f001b
Author: Jonh Wendell <jwendell gnome org>
Date:   Fri May 8 16:05:46 2009 -0300

    Initial work to make vinagre a generic viewer
---
 data/vinagre-ui.xml               |    9 +-
 src/Makefile.am                   |    3 +
 src/vinagre-bacon.c               |    4 +-
 src/vinagre-bookmarks-migration.c |   10 +-
 src/vinagre-bookmarks-ui.c        |    6 +
 src/vinagre-bookmarks.c           |   63 +--
 src/vinagre-bookmarks.h           |    1 +
 src/vinagre-commands.c            |   70 +---
 src/vinagre-commands.h            |   10 +-
 src/vinagre-connection.c          |  434 +++++++----------
 src/vinagre-connection.h          |   67 ++--
 src/vinagre-main.c                |    3 +-
 src/vinagre-mdns.c                |    2 +-
 src/vinagre-notebook.c            |  414 ++++++++++++++--
 src/vinagre-notebook.h            |   60 +--
 src/vinagre-tab.c                 | 1011 +++++++++----------------------------
 src/vinagre-tab.h                 |   93 +++-
 src/vinagre-ui.h                  |   56 +--
 src/vinagre-utils.c               |   10 +
 src/vinagre-utils.h               |    3 +
 src/vinagre-vnc-connection.c      |  341 +++++++++++++
 src/vinagre-vnc-connection.h      |   75 +++
 src/vinagre-vnc-tab.c             | 1000 ++++++++++++++++++++++++++++++++++++
 src/vinagre-vnc-tab.h             |   75 +++
 src/vinagre-window-private.h      |    9 +-
 src/vinagre-window.c              |  238 ++--------
 src/vinagre-window.h              |   14 +-
 27 files changed, 2524 insertions(+), 1557 deletions(-)

diff --git a/data/vinagre-ui.xml b/data/vinagre-ui.xml
index 071d2a4..55ec04b 100644
--- a/data/vinagre-ui.xml
+++ b/data/vinagre-ui.xml
@@ -2,7 +2,7 @@
  * vinagre-ui.xml
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@
       <separator/>
       <menuitem name="MachineCloseMenu" action="MachineClose"/>
       <menuitem name="MachineTakeScreenshotMenu" action="MachineTakeScreenshot"/>
-      <menuitem name="MachineSendCtrlAltDelMenu" action="MachineSendCtrlAltDel"/>
+      <placeholder name="MachineOps_1" />
       <placeholder name="FileRecentsPlaceholder">
         <separator/>
       </placeholder>
@@ -46,9 +46,6 @@
       <menuitem name="ViewSidePanelMenu" action="ViewSidePanel"/>
       <separator/>
       <menuitem name="ViewFullScreenMenu" action="ViewFullScreen"/>
-      <menuitem name="ViewOriginalSizeMenu" action="ViewOriginalSize"/>
-      <menuitem name="ViewScalingMenu" action="ViewScaling"/>
-      <menuitem name="ViewReadOnlyMenu" action="ViewReadOnly"/>
     </menu>
 
     <menu name="BookmarksMenu" action="Bookmarks">
@@ -75,7 +72,7 @@
     <separator/>
     <toolitem action="ViewFullScreen"/>
     <toolitem action="MachineTakeScreenshot"/>
-    <toolitem action="MachineSendCtrlAltDel"/>
+    <separator/>
   </toolbar>
 
   <popup name="FavPopupConn" action="FavPopupActionConn">
diff --git a/src/Makefile.am b/src/Makefile.am
index 2bcb1ae..a0ec889 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,11 +24,13 @@ vinagre_SOURCES = \
 	vinagre-commands.c vinagre-commands.h			\
 	vinagre-connect.c vinagre-connect.h			\
 	vinagre-connection.c vinagre-connection.h		\
+	vinagre-vnc-connection.c vinagre-vnc-connection.h	\
 	vinagre-fav.c vinagre-fav.h				\
 	vinagre-bookmarks.c vinagre-bookmarks.h			\
 	vinagre-main.c 						\
 	vinagre-notebook.c vinagre-notebook.h			\
 	vinagre-tab.c vinagre-tab.h				\
+	vinagre-vnc-tab.c vinagre-vnc-tab.h			\
 	vinagre-utils.c vinagre-utils.h				\
 	vinagre-window.c vinagre-window.h			\
 	vinagre-ui.h vinagre-window-private.h			\
@@ -85,6 +87,7 @@ vinagre_applet_SOURCES =					\
 	vinagre-applet.c					\
 	vinagre-bookmarks.h vinagre-bookmarks.c			\
 	vinagre-connection.h vinagre-connection.c		\
+	vinagre-vnc-connection.c vinagre-vnc-connection.h	\
 	vinagre-utils.h vinagre-utils.c				\
 	vinagre-enums.h vinagre-enums.c				\
 	vinagre-bookmarks-entry.h vinagre-bookmarks-entry.c	\
diff --git a/src/vinagre-bacon.c b/src/vinagre-bacon.c
index b2bef26..af3beaf 100644
--- a/src/vinagre-bacon.c
+++ b/src/vinagre-bacon.c
@@ -2,7 +2,7 @@
  * vinagre-bacon.c
  * This file is part of vinagre
  *
- * Copyright (C) 2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -156,7 +156,9 @@ vinagre_bacon_message_received (const char *message,
       
       next = l->next;
       vinagre_cmd_direct_connect (conn, window);
+      g_object_unref (conn);
     }
+  g_slist_free (servers);
 
   /* set the proper interaction time on the window.
    * Fall back to roundtripping to the X server when we
diff --git a/src/vinagre-bookmarks-migration.c b/src/vinagre-bookmarks-migration.c
index 9a7b7bb..17c84f1 100644
--- a/src/vinagre-bookmarks-migration.c
+++ b/src/vinagre-bookmarks-migration.c
@@ -61,8 +61,8 @@ fill_xml (GSList *list, xmlTextWriter *writer)
 	    xmlTextWriterWriteElement (writer, "name", vinagre_connection_get_name (conn));
 	    xmlTextWriterWriteElement (writer, "host", vinagre_connection_get_host (conn));
 	    xmlTextWriterWriteFormatElement (writer, "port", "%d", vinagre_connection_get_port (conn));
-	    xmlTextWriterWriteFormatElement (writer, "view_only", "%d", vinagre_connection_get_view_only (conn));
-	    xmlTextWriterWriteFormatElement (writer, "scaling", "%d", vinagre_connection_get_scaling (conn));
+	    //xmlTextWriterWriteFormatElement (writer, "view_only", "%d", vinagre_connection_get_view_only (conn));
+	    //xmlTextWriterWriteFormatElement (writer, "scaling", "%d", vinagre_connection_get_scaling (conn));
 	    xmlTextWriterWriteFormatElement (writer, "fullscreen", "%d", vinagre_connection_get_fullscreen (conn));
 
 	    xmlTextWriterEndElement (writer);
@@ -167,7 +167,7 @@ create_list (GKeyFile *kf)
       if (!s_value)
         continue;
 
-      conn = vinagre_connection_new ();
+      conn = vinagre_connection_new (VINAGRE_CONNECTION_PROTOCOL_VNC);
       vinagre_connection_set_name (conn, conns[i]);
       vinagre_connection_set_host (conn, s_value);
       g_free (s_value);
@@ -178,13 +178,13 @@ create_list (GKeyFile *kf)
       vinagre_connection_set_port (conn, i_value);
 
       b_value = g_key_file_get_boolean (kf, conns[i], "view_only", NULL);
-      vinagre_connection_set_view_only (conn, b_value);
+      //vinagre_connection_set_view_only (conn, b_value);
 
       b_value = g_key_file_get_boolean (kf, conns[i], "fullscreen", NULL);
       vinagre_connection_set_fullscreen (conn, b_value);
 
       b_value = g_key_file_get_boolean (kf, conns[i], "scaling", NULL);
-      vinagre_connection_set_scaling (conn, b_value);
+      //vinagre_connection_set_scaling (conn, b_value);
 
       entries = g_slist_insert_sorted  (entries,
 					vinagre_bookmarks_entry_new_conn (conn),
diff --git a/src/vinagre-bookmarks-ui.c b/src/vinagre-bookmarks-ui.c
index 352db28..ed1cd8c 100644
--- a/src/vinagre-bookmarks-ui.c
+++ b/src/vinagre-bookmarks-ui.c
@@ -127,6 +127,7 @@ show_dialog_conn (VinagreBookmarks      *book,
   GtkWidget         *box, *tree, *save_button;
   VinagreConnection *conn;
   const gchar       *name;
+  VinagreConnectionProtocol protocol;
 
   xml = glade_xml_new (vinagre_utils_get_glade_filename (),
 		       "bookmarks_add_edit_conn_dialog",
@@ -152,12 +153,14 @@ show_dialog_conn (VinagreBookmarks      *book,
   gtk_entry_set_text (GTK_ENTRY (host_entry), str);
   g_free (str);
 
+/*
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fs_check),
 				vinagre_connection_get_fullscreen (conn));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sc_check),
 				vinagre_connection_get_scaling (conn));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (vo_check),
 				vinagre_connection_get_view_only (conn));
+*/
 
   g_signal_connect (name_entry, "changed", G_CALLBACK (control_save_button_visibility), save_button);
 
@@ -198,6 +201,7 @@ show_dialog_conn (VinagreBookmarks      *book,
 	}
 
       if (!vinagre_connection_split_string (gtk_entry_get_text (GTK_ENTRY (host_entry)),
+					    &protocol,
 					    &host,
 					    &port,
 					    &error_str))
@@ -214,10 +218,12 @@ show_dialog_conn (VinagreBookmarks      *book,
   vinagre_connection_set_name (conn, name);
   vinagre_connection_set_host (conn, host);
   vinagre_connection_set_port (conn, port);
+/*
   vinagre_connection_set_view_only  (conn,
 				     gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (vo_check)));
   vinagre_connection_set_scaling    (conn,
 				     gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sc_check)));
+*/
   vinagre_connection_set_fullscreen (conn,
 				     gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fs_check)));
 
diff --git a/src/vinagre-bookmarks.c b/src/vinagre-bookmarks.c
index 9738951..d773bfc 100644
--- a/src/vinagre-bookmarks.c
+++ b/src/vinagre-bookmarks.c
@@ -2,7 +2,7 @@
  * vinagre-bookmarks.c
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008  Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009  Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
 #include "vinagre-bookmarks.h"
 #include "vinagre-bookmarks-entry.h"
 #include "vinagre-bookmarks-migration.h"
+#include "vinagre-connection.h"
 
 struct _VinagreBookmarksPrivate
 {
@@ -144,7 +145,10 @@ vinagre_bookmarks_class_init (VinagreBookmarksClass *klass)
 }
 
 static VinagreConnection *
-find_conn_by_host (GSList *entries, const gchar *host, gint port)
+find_conn_by_host (GSList *entries,
+		   VinagreConnectionProtocol protocol,
+		   const gchar *host,
+		   gint port)
 {
   GSList *l;
   VinagreConnection *conn;
@@ -157,15 +161,17 @@ find_conn_by_host (GSList *entries, const gchar *host, gint port)
 	{
 	  case VINAGRE_BOOKMARKS_ENTRY_NODE_FOLDER:
 	    if ((conn = find_conn_by_host (vinagre_bookmarks_entry_get_children (entry),
-					  host,
-					  port)))
+					   protocol,
+					   host,
+					   port)))
 	      return conn;
 	    break;
 
 	  case VINAGRE_BOOKMARKS_ENTRY_NODE_CONN:
 	    conn = vinagre_bookmarks_entry_get_conn (entry);
 	    if ( (g_str_equal (host, vinagre_connection_get_host (conn))) &&
-		 (port == vinagre_connection_get_port (conn) ) )
+		 (port == vinagre_connection_get_port (conn)) &&
+		 (protocol == vinagre_connection_get_protocol (conn)) )
 	      return g_object_ref (conn);
 	    break;
 
@@ -178,6 +184,7 @@ find_conn_by_host (GSList *entries, const gchar *host, gint port)
 
 VinagreConnection *
 vinagre_bookmarks_exists (VinagreBookmarks *book,
+                          VinagreConnectionProtocol protocol,
                           const gchar *host,
                           gint port)
 {
@@ -187,7 +194,7 @@ vinagre_bookmarks_exists (VinagreBookmarks *book,
   g_return_val_if_fail (VINAGRE_IS_BOOKMARKS (book), NULL);
   g_return_val_if_fail (host != NULL, NULL);
 
-  return find_conn_by_host (book->priv->entries, host, port);
+  return find_conn_by_host (book->priv->entries, protocol, host, port);
 }
 
 static void
@@ -214,13 +221,7 @@ vinagre_bookmarks_save_fill_xml (GSList *list, xmlTextWriter *writer)
 	    conn = vinagre_bookmarks_entry_get_conn (entry);
 
 	    xmlTextWriterStartElement (writer, "item");
-	    xmlTextWriterWriteElement (writer, "name", vinagre_connection_get_name (conn));
-	    xmlTextWriterWriteElement (writer, "host", vinagre_connection_get_host (conn));
-	    xmlTextWriterWriteFormatElement (writer, "port", "%d", vinagre_connection_get_port (conn));
-	    xmlTextWriterWriteFormatElement (writer, "view_only", "%d", vinagre_connection_get_view_only (conn));
-	    xmlTextWriterWriteFormatElement (writer, "scaling", "%d", vinagre_connection_get_scaling (conn));
-	    xmlTextWriterWriteFormatElement (writer, "fullscreen", "%d", vinagre_connection_get_fullscreen (conn));
-
+	    vinagre_connection_fill_writer (conn, writer);
 	    xmlTextWriterEndElement (writer);
 	    break;
 
@@ -230,15 +231,6 @@ vinagre_bookmarks_save_fill_xml (GSList *list, xmlTextWriter *writer)
     }
 }
 
-static gboolean
-vinagre_bookmarks_parse_boolean (const gchar* value)
-{
-  if (g_ascii_strcasecmp (value, "true") == 0 || strcmp (value, "1") == 0)
-    return TRUE;
-
-  return FALSE;
-}
-
 static VinagreBookmarksEntry *
 vinagre_bookmarks_parse_item (xmlNode *root)
 {
@@ -246,31 +238,22 @@ vinagre_bookmarks_parse_item (xmlNode *root)
   VinagreConnection     *conn;
   xmlNode               *curr;
   xmlChar               *s_value;
+  VinagreConnectionProtocol protocol = VINAGRE_CONNECTION_PROTOCOL_VNC;
 
-  conn = vinagre_connection_new ();
-
+  /* Loop to discover the protocol */
   for (curr = root->children; curr; curr = curr->next)
     {
-      s_value = xmlNodeGetContent (curr);
-
-      if (!xmlStrcmp(curr->name, (const xmlChar *)"host"))
-	vinagre_connection_set_host (conn, s_value);
-      else if (!xmlStrcmp(curr->name, (const xmlChar *)"name"))
-	vinagre_connection_set_name (conn, s_value);
-      else if (!xmlStrcmp(curr->name, (const xmlChar *)"port"))
-	vinagre_connection_set_port (conn, atoi (s_value));
-      else if (!xmlStrcmp(curr->name, (const xmlChar *)"view_only"))
-	vinagre_connection_set_view_only (conn, vinagre_bookmarks_parse_boolean (s_value));
-      else if (!xmlStrcmp(curr->name, (const xmlChar *)"scaling"))
-	vinagre_connection_set_scaling (conn, vinagre_bookmarks_parse_boolean (s_value));
-      else if (!xmlStrcmp(curr->name, (const xmlChar *)"fullscreen"))
-	vinagre_connection_set_fullscreen (conn, vinagre_bookmarks_parse_boolean (s_value));
+      if (xmlStrcmp(curr->name, (const xmlChar *)"protocol"))
+        continue;
 
+      s_value = xmlNodeGetContent (curr);
+      protocol = vinagre_connection_protocol_by_name ((const gchar *)s_value);
       xmlFree (s_value);
+      break;
     }
 
-  if (vinagre_connection_get_port (conn) <= 0)
-    vinagre_connection_set_port (conn, 5900);
+  conn = vinagre_connection_new (protocol);
+  vinagre_connection_parse_item (conn, root);
 
   if (vinagre_connection_get_host (conn))
     entry = vinagre_bookmarks_entry_new_conn (conn);
diff --git a/src/vinagre-bookmarks.h b/src/vinagre-bookmarks.h
index 7ccf52c..2aabf08 100644
--- a/src/vinagre-bookmarks.h
+++ b/src/vinagre-bookmarks.h
@@ -71,6 +71,7 @@ gboolean           vinagre_bookmarks_remove_entry  (VinagreBookmarks      *book,
                                                     VinagreBookmarksEntry *entry);
 
 VinagreConnection  *vinagre_bookmarks_exists       (VinagreBookmarks *book,
+                                                    VinagreConnectionProtocol protocol,
                                                     const gchar *host,
                                                     gint port);
 
diff --git a/src/vinagre-commands.c b/src/vinagre-commands.c
index 7fa20ab..82a2a38 100644
--- a/src/vinagre-commands.c
+++ b/src/vinagre-commands.c
@@ -2,7 +2,7 @@
  * vinagre-commands.c
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -87,6 +87,8 @@ vinagre_cmd_machine_connect (GtkAction     *action,
 				VINAGRE_TAB (tab),
 				-1);
     }
+
+  g_object_unref (conn);
 }
 
 static void
@@ -129,7 +131,7 @@ vinagre_cmd_machine_open (GtkAction     *action,
     {
       files = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
       for (l = files; l; l = l->next)
-        {
+	{
 	  uri = (gchar *)l->data;
 	  conn = vinagre_connection_new_from_file (uri, &error, FALSE);
 
@@ -137,8 +139,9 @@ vinagre_cmd_machine_open (GtkAction     *action,
 	    {
 	      tab = vinagre_tab_new (conn, window);
 	      vinagre_notebook_add_tab (VINAGRE_NOTEBOOK (window->priv->notebook),
-				        VINAGRE_TAB (tab),
-				        -1);
+					VINAGRE_TAB (tab),
+					-1);
+	      g_object_unref (conn);
 	    }
 	  else
 	    {
@@ -180,13 +183,6 @@ vinagre_cmd_machine_take_screenshot (GtkAction     *action,
 }
 
 void
-vinagre_cmd_machine_send_ctrlaltdel (GtkAction     *action,
-				     VinagreWindow *window)
-{
-  vinagre_tab_send_ctrlaltdel (vinagre_window_get_active_tab (window));
-}
-
-void
 vinagre_cmd_machine_close_all (GtkAction     *action,
 			       VinagreWindow *window)
 {
@@ -257,49 +253,6 @@ vinagre_cmd_view_fullscreen (GtkAction     *action,
   vinagre_window_toggle_fullscreen (window);
 }
 
-void
-vinagre_cmd_view_original_size (GtkAction     *action,
-				VinagreWindow *window)
-{
-  g_return_if_fail (VINAGRE_IS_WINDOW (window));
-
-  vinagre_tab_original_size (vinagre_window_get_active_tab (window));
-}
-
-void
-vinagre_cmd_view_scaling (GtkAction     *action,
-			  VinagreWindow *window)
-{
-  gboolean active;
-  VinagreTab *tab;
-
-  g_return_if_fail (VINAGRE_IS_WINDOW (window));
-
-  tab = vinagre_window_get_active_tab (window);
-  if (!tab)
-    return;
-
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
-
-  if (!vinagre_tab_set_scaling (tab, active))
-    gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
-}
-
-void
-vinagre_cmd_view_readonly (GtkAction     *action,
-			   VinagreWindow *window)
-{
-  gboolean active;
-  VinagreTab *tab;
-
-  tab = vinagre_window_get_active_tab (window);
-  if (!tab)
-    return;
-
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
-  vinagre_tab_set_readonly (tab, active);
-}
-
 /* Bookmarks Menu */
 void
 vinagre_cmd_open_bookmark (VinagreWindow     *window,
@@ -318,8 +271,7 @@ vinagre_cmd_open_bookmark (VinagreWindow     *window,
     }
   else
     {
-      new_conn = vinagre_connection_clone (conn);
-      tab = VINAGRE_TAB (vinagre_tab_new (new_conn, window));
+      tab = VINAGRE_TAB (vinagre_tab_new (conn, window));
       vinagre_notebook_add_tab (VINAGRE_NOTEBOOK (window->priv->notebook),
 				VINAGRE_TAB (tab),
 				-1);
@@ -336,14 +288,15 @@ vinagre_cmd_bookmarks_add (GtkAction     *action,
 
   g_return_if_fail (VINAGRE_IS_WINDOW (window));
 
-  tab = window->priv->active_tab;
+  //tab = window->priv->active_tab;
   conn = vinagre_tab_get_conn (VINAGRE_TAB (tab));
-  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
+  //g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
 
   vinagre_bookmarks_add (vinagre_bookmarks_get_default (),
                          conn,
                          GTK_WINDOW (window));
 
+/*
   if (window->priv->active_tab == tab)
     {
       name = vinagre_connection_get_best_name (conn);
@@ -351,6 +304,7 @@ vinagre_cmd_bookmarks_add (GtkAction     *action,
 			     name);
       g_free (name);
     }
+*/
 }
 
 void
diff --git a/src/vinagre-commands.h b/src/vinagre-commands.h
index 67ab5e6..8683e41 100644
--- a/src/vinagre-commands.h
+++ b/src/vinagre-commands.h
@@ -2,7 +2,7 @@
  * vinagre-commands.h
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,8 +38,6 @@ void		vinagre_cmd_machine_close	(GtkAction     *action,
 						 VinagreWindow *window);
 void		vinagre_cmd_machine_take_screenshot (GtkAction     *action,
 						     VinagreWindow *window);
-void		vinagre_cmd_machine_send_ctrlaltdel (GtkAction     *action,
-						     VinagreWindow *window);
 
 void		vinagre_cmd_machine_close_all	(GtkAction     *action,
 						 VinagreWindow *window);
@@ -55,14 +53,8 @@ void		vinagre_cmd_view_show_statusbar	(GtkAction     *action,
 						 VinagreWindow *window);
 void		vinagre_cmd_view_show_fav_panel	(GtkAction     *action,
 						 VinagreWindow *window);
-void		vinagre_cmd_view_scaling	(GtkAction     *action,
-						 VinagreWindow *window);
-void		vinagre_cmd_view_original_size	(GtkAction     *action,
-						 VinagreWindow *window);
 void		vinagre_cmd_view_fullscreen	(GtkAction     *action,
 						 VinagreWindow *window);
-void		vinagre_cmd_view_readonly	(GtkAction     *action,
-						 VinagreWindow *window);
 
 void		vinagre_cmd_open_bookmark	(VinagreWindow     *window,
 						 VinagreConnection *conn);
diff --git a/src/vinagre-connection.c b/src/vinagre-connection.c
index 4c83a5f..595b236 100644
--- a/src/vinagre-connection.c
+++ b/src/vinagre-connection.c
@@ -2,7 +2,7 @@
  * vinagre-connection.c
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,19 +26,16 @@
 #include "vinagre-connection.h"
 #include "vinagre-enums.h"
 #include "vinagre-bookmarks.h"
+#include "vinagre-vnc-connection.h"
 
 struct _VinagreConnectionPrivate
 {
   VinagreConnectionProtocol protocol;
   gchar *host;
   gint   port;
-  gchar *name;
   gchar *username;
   gchar *password;
-  gchar *desktop_name;
-  gint   shared;
-  gboolean view_only;
-  gboolean scaling;
+  gchar *name;
   gboolean fullscreen;
 };
 
@@ -48,40 +45,32 @@ enum
   PROP_PROTOCOL,
   PROP_HOST,
   PROP_PORT,
-  PROP_NAME,
   PROP_USERNAME,
   PROP_PASSWORD,
-  PROP_DESKTOP_NAME,
+  PROP_NAME,
   PROP_BEST_NAME,
   PROP_ICON,
-  PROP_VIEW_ONLY,
-  PROP_SCALING,
-  PROP_FULLSCREEN,
-  PROP_SHARED,
+  PROP_FULLSCREEN
 };
 
 gint   vinagre_connection_default_port [VINAGRE_CONNECTION_PROTOCOL_INVALID-1] = {5900, 3389};
 gchar* vinagre_connection_protos [VINAGRE_CONNECTION_PROTOCOL_INVALID-1] = {"vnc", "rdp"};
 
 #define VINAGRE_CONNECTION_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), VINAGRE_TYPE_CONNECTION, VinagreConnectionPrivate))
-G_DEFINE_TYPE (VinagreConnection, vinagre_connection, G_TYPE_OBJECT);
+G_DEFINE_ABSTRACT_TYPE (VinagreConnection, vinagre_connection, G_TYPE_OBJECT);
 
 static void
 vinagre_connection_init (VinagreConnection *conn)
 {
   conn->priv = G_TYPE_INSTANCE_GET_PRIVATE (conn, VINAGRE_TYPE_CONNECTION, VinagreConnectionPrivate);
 
-  conn->priv->protocol = VINAGRE_CONNECTION_PROTOCOL_VNC;
+  conn->priv->protocol = VINAGRE_CONNECTION_PROTOCOL_INVALID;
   conn->priv->host = NULL;
   conn->priv->port = 0;
   conn->priv->password = NULL;
   conn->priv->username = NULL;
   conn->priv->name = NULL;
-  conn->priv->desktop_name = NULL;
-  conn->priv->view_only = FALSE;
-  conn->priv->scaling = FALSE;
   conn->priv->fullscreen = FALSE;
-  conn->priv->shared = -1;
 }
 
 static void
@@ -93,7 +82,6 @@ vinagre_connection_finalize (GObject *object)
   g_free (conn->priv->username);
   g_free (conn->priv->password);
   g_free (conn->priv->name);
-  g_free (conn->priv->desktop_name);
 
   G_OBJECT_CLASS (vinagre_connection_parent_class)->finalize (object);
 }
@@ -129,28 +117,12 @@ vinagre_connection_set_property (GObject *object, guint prop_id, const GValue *v
 	vinagre_connection_set_password (conn, g_value_get_string (value));
 	break;
 
-      case PROP_NAME:
-	vinagre_connection_set_name (conn, g_value_get_string (value));
-	break;
-
-      case PROP_DESKTOP_NAME:
-	vinagre_connection_set_desktop_name (conn, g_value_get_string (value));
-	break;
-
-      case PROP_VIEW_ONLY:
-	vinagre_connection_set_view_only (conn, g_value_get_boolean (value));
-	break;
-
-      case PROP_SCALING:
-	vinagre_connection_set_scaling (conn, g_value_get_boolean (value));
-	break;
-
       case PROP_FULLSCREEN:
 	vinagre_connection_set_fullscreen (conn, g_value_get_boolean (value));
 	break;
 
-      case PROP_SHARED:
-	vinagre_connection_set_shared (conn, g_value_get_int (value));
+      case PROP_NAME:
+	vinagre_connection_set_name (conn, g_value_get_string (value));
 	break;
 
       default:
@@ -191,36 +163,20 @@ vinagre_connection_get_property (GObject *object, guint prop_id, GValue *value,
 	g_value_set_string (value, conn->priv->password);
 	break;
 
-      case PROP_NAME:
-	g_value_set_string (value, conn->priv->name);
-	break;
-
-      case PROP_DESKTOP_NAME:
-	g_value_set_string (value, conn->priv->desktop_name);
-	break;
-
-      case PROP_BEST_NAME:
-	g_value_set_string (value, vinagre_connection_get_best_name (conn));
-	break;
-
       case PROP_ICON:
 	g_value_set_object (value, vinagre_connection_get_icon (conn));
 	break;
 
-      case PROP_VIEW_ONLY:
-	g_value_set_boolean (value, conn->priv->view_only);
-	break;
-
-      case PROP_SCALING:
-	g_value_set_boolean (value, conn->priv->scaling);
-	break;
-
       case PROP_FULLSCREEN:
 	g_value_set_boolean (value, conn->priv->fullscreen);
 	break;
 
-      case PROP_SHARED:
-	g_value_set_int (value, conn->priv->shared);
+      case PROP_NAME:
+	g_value_set_string (value, conn->priv->name);
+	break;
+
+      case PROP_BEST_NAME:
+	g_value_set_string (value, vinagre_connection_get_best_name (conn));
 	break;
 
       default:
@@ -230,10 +186,57 @@ vinagre_connection_get_property (GObject *object, guint prop_id, GValue *value,
 }
 
 static void
+default_fill_writer (VinagreConnection *conn, xmlTextWriter *writer)
+{
+  xmlTextWriterWriteElement (writer, "name", conn->priv->name);
+  xmlTextWriterWriteElement (writer, "host", conn->priv->host);
+  xmlTextWriterWriteFormatElement (writer, "port", "%d", conn->priv->port);
+  xmlTextWriterWriteFormatElement (writer, "fullscreen", "%d", conn->priv->fullscreen);
+}
+
+static void
+default_parse_item (VinagreConnection *conn, xmlNode *root)
+{
+  xmlNode *curr;
+  xmlChar *s_value;
+
+  for (curr = root->children; curr; curr = curr->next)
+    {
+      s_value = xmlNodeGetContent (curr);
+
+      if (!xmlStrcmp(curr->name, (const xmlChar *)"host"))
+	vinagre_connection_set_host (conn, s_value);
+      else if (!xmlStrcmp(curr->name, (const xmlChar *)"name"))
+	vinagre_connection_set_name (conn, s_value);
+      else if (!xmlStrcmp(curr->name, (const xmlChar *)"port"))
+	vinagre_connection_set_port (conn, atoi (s_value));
+      else if (!xmlStrcmp(curr->name, (const xmlChar *)"fullscreen"))
+	vinagre_connection_set_fullscreen (conn, vinagre_utils_parse_boolean (s_value));
+
+      xmlFree (s_value);
+    }
+
+  if (conn->priv->port <= 0)
+    vinagre_connection_set_port (conn, vinagre_connection_default_port [conn->priv->protocol-1]);
+
+}
+
+static gchar *
+default_get_best_name (VinagreConnection *conn)
+{
+  if (conn->priv->name)
+    return g_strdup (conn->priv->name);
+
+  if (conn->priv->host)
+    return vinagre_connection_get_string_rep (conn, FALSE);
+
+  return NULL;
+}
+
+static void
 vinagre_connection_class_init (VinagreConnectionClass *klass)
 {
   GObjectClass* object_class = G_OBJECT_CLASS (klass);
-  GObjectClass* parent_class = G_OBJECT_CLASS (klass);
 
   g_type_class_add_private (klass, sizeof (VinagreConnectionPrivate));
 
@@ -241,6 +244,11 @@ vinagre_connection_class_init (VinagreConnectionClass *klass)
   object_class->set_property = vinagre_connection_set_property;
   object_class->get_property = vinagre_connection_get_property;
 
+  klass->impl_fill_writer = default_fill_writer;
+  klass->impl_parse_item = default_parse_item;
+  klass->impl_get_best_name = default_get_best_name;
+  klass->impl_fill_conn_from_file = NULL;
+
   g_object_class_install_property (object_class,
                                    PROP_PROTOCOL,
                                    g_param_spec_enum ("protocol",
@@ -273,7 +281,7 @@ vinagre_connection_class_init (VinagreConnectionClass *klass)
 	                                              "tcp/ip port of this connection",
                                                       0,
                                                       G_MAXINT,
-                                                      5900,
+                                                      0,
 	                                              G_PARAM_READWRITE |
                                                       G_PARAM_CONSTRUCT |
                                                       G_PARAM_STATIC_NICK |
@@ -317,18 +325,6 @@ vinagre_connection_class_init (VinagreConnectionClass *klass)
                                                         G_PARAM_STATIC_BLURB));
 
   g_object_class_install_property (object_class,
-                                   PROP_DESKTOP_NAME,
-                                   g_param_spec_string ("desktop-name",
-                                                        "desktop-name",
-	                                                "name of this connection as reported by the server",
-                                                        NULL,
-	                                                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_BEST_NAME,
                                    g_param_spec_string ("best-name",
                                                         "best-name",
@@ -350,28 +346,6 @@ vinagre_connection_class_init (VinagreConnectionClass *klass)
                                                         G_PARAM_STATIC_NAME |
                                                         G_PARAM_STATIC_BLURB));
   g_object_class_install_property (object_class,
-                                   PROP_VIEW_ONLY,
-                                   g_param_spec_boolean ("view-only",
-                                                        "View-only connection",
-	                                                "Whether this connection is a view-only one",
-                                                        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_SCALING,
-                                   g_param_spec_boolean ("scaling",
-                                                        "Use scaling",
-	                                                "Whether to use scaling on this connection",
-                                                        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_FULLSCREEN,
                                    g_param_spec_boolean ("fullscreen",
                                                         "Full screen connection",
@@ -383,26 +357,6 @@ vinagre_connection_class_init (VinagreConnectionClass *klass)
                                                         G_PARAM_STATIC_NAME |
                                                         G_PARAM_STATIC_BLURB));
 
-  g_object_class_install_property (object_class,
-                                   PROP_PORT,
-                                   g_param_spec_int ("shared",
-                                                     "shared flag",
-	                                              "if the server should allow more than one client connected",
-                                                      -1,
-                                                      1,
-                                                      -1,
-	                                              G_PARAM_READWRITE |
-                                                      G_PARAM_CONSTRUCT |
-                                                      G_PARAM_STATIC_NICK |
-                                                      G_PARAM_STATIC_NAME |
-                                                      G_PARAM_STATIC_BLURB));
-
-}
-
-VinagreConnection *
-vinagre_connection_new ()
-{
-  return g_object_new (VINAGRE_TYPE_CONNECTION, NULL);
 }
 
 void
@@ -422,14 +376,33 @@ vinagre_connection_get_protocol (VinagreConnection *conn)
   return conn->priv->protocol;
 }
 
+const gchar *
+vinagre_connection_get_protocol_as_string (VinagreConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
+
+  return vinagre_connection_protos [conn->priv->protocol-1];
+}
+
+VinagreConnectionProtocol
+vinagre_connection_protocol_by_name (const gchar *protocol)
+{
+  int i;
+
+  for (i = VINAGRE_CONNECTION_PROTOCOL_VNC; i <= VINAGRE_CONNECTION_PROTOCOL_INVALID; i++)
+    if (g_strcmp0 (vinagre_connection_protos [i-1], protocol) == 0)
+      return i;
+
+  return VINAGRE_CONNECTION_PROTOCOL_INVALID;
+}
+
 void
 vinagre_connection_set_host (VinagreConnection *conn,
 			     const gchar *host)
 {
   g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
 
-  if (conn->priv->host)
-    g_free (conn->priv->host);
+  g_free (conn->priv->host);
   conn->priv->host = g_strdup (host);
 }
 const gchar *
@@ -491,95 +464,76 @@ vinagre_connection_get_password (VinagreConnection *conn)
 }
 
 void
-vinagre_connection_set_name (VinagreConnection *conn,
-			     const gchar *name)
+vinagre_connection_set_fullscreen (VinagreConnection *conn,
+				  gboolean value)
 {
   g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
 
-  g_free (conn->priv->name);
-  conn->priv->name = g_strdup (name);
+  conn->priv->fullscreen = value;
 }
-const gchar *
-vinagre_connection_get_name (VinagreConnection *conn)
+gboolean
+vinagre_connection_get_fullscreen (VinagreConnection *conn)
 {
-  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), FALSE);
 
-  return conn->priv->name;
+  return conn->priv->fullscreen;
 }
 
 void
-vinagre_connection_set_desktop_name (VinagreConnection *conn,
-			             const gchar *desktop_name)
+vinagre_connection_set_name (VinagreConnection *conn,
+			     const gchar *name)
 {
   g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
 
-  g_free (conn->priv->desktop_name);
-  conn->priv->desktop_name = g_strdup (desktop_name);
+  g_free (conn->priv->name);
+  conn->priv->name = g_strdup (name);
 }
 const gchar *
-vinagre_connection_get_desktop_name (VinagreConnection *conn)
+vinagre_connection_get_name (VinagreConnection *conn)
 {
   g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
 
-  return conn->priv->desktop_name;
+  return conn->priv->name;
 }
 
-gchar *
-vinagre_connection_get_best_name (VinagreConnection *conn)
+GdkPixbuf *
+vinagre_connection_get_icon (VinagreConnection *conn)
 {
-  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
-
-  if (conn->priv->name)
-    return g_strdup (conn->priv->name);
-
-  if (conn->priv->desktop_name)
-    return g_strdup (conn->priv->desktop_name);
-
-  if (conn->priv->host)
-        return g_strdup_printf ("%s:%d", conn->priv->host, conn->priv->port);
-
-  return NULL;
-}
+  GdkPixbuf         *pixbuf;
+  GtkIconTheme      *icon_theme;
+  gchar             *icon_name;
 
-void
-vinagre_connection_set_shared (VinagreConnection *conn,
-			       gint value)
-{
-  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
-  g_return_if_fail (value >=0 && value <=1);
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
+  g_return_val_if_fail (conn->priv->protocol != VINAGRE_CONNECTION_PROTOCOL_INVALID, NULL);
 
-  conn->priv->shared = value;
-}
-gint
-vinagre_connection_get_shared (VinagreConnection *conn)
-{
-  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), -1);
+  icon_name = g_strdup_printf ("application-x-%s",
+			       vinagre_connection_protos [conn->priv->protocol-1]);
+  icon_theme = gtk_icon_theme_get_default ();
+  pixbuf = gtk_icon_theme_load_icon (icon_theme,
+				     icon_name,
+				     16,
+				     0,
+				     NULL);
 
-  return conn->priv->shared;
+  g_free (icon_name);
+  return pixbuf;
 }
 
-VinagreConnection *
-vinagre_connection_clone (VinagreConnection *conn)
+VinagreConnectionProtocol
+protocol_by_name (const gchar *protocol)
 {
-  VinagreConnection *new_conn;
+  gint i;
 
-  new_conn = vinagre_connection_new ();
+  for (i=0; i<VINAGRE_CONNECTION_PROTOCOL_INVALID; i++)
+    if (g_strcmp0 (vinagre_connection_protos[i], protocol) == 0)
+      return i;
 
-  vinagre_connection_set_host (new_conn, vinagre_connection_get_host (conn));
-  vinagre_connection_set_port (new_conn, vinagre_connection_get_port (conn));
-  vinagre_connection_set_username (new_conn, vinagre_connection_get_username (conn));
-  vinagre_connection_set_password (new_conn, vinagre_connection_get_password (conn));
-  vinagre_connection_set_name (new_conn, vinagre_connection_get_name (conn));
-  vinagre_connection_set_desktop_name (new_conn, vinagre_connection_get_desktop_name (conn));
-  vinagre_connection_set_view_only (new_conn, vinagre_connection_get_view_only (conn));
-  vinagre_connection_set_scaling (new_conn, vinagre_connection_get_scaling (conn));
-  vinagre_connection_set_fullscreen (new_conn, vinagre_connection_get_fullscreen (conn));
-
-  return new_conn;
+  return VINAGRE_CONNECTION_PROTOCOL_INVALID;
 }
 
 gboolean
 vinagre_connection_split_string (const gchar *uri,
+				 VinagreConnectionProtocol *protocol,
 				 gchar **host,
 				 gint *port,
 				 gchar **error_msg)
@@ -596,7 +550,8 @@ vinagre_connection_split_string (const gchar *uri,
   url = g_strsplit (uri, "://", 2);
   if (g_strv_length (url) == 2)
     {
-      if (g_strcmp0 (url[0], "vnc"))
+      *protocol = protocol_by_name (url[0]);
+      if (*protocol == VINAGRE_CONNECTION_PROTOCOL_INVALID)
 	{
 	  *error_msg = g_strdup_printf (_("The protocol %s is not supported."),
 					url[0]);
@@ -606,7 +561,10 @@ vinagre_connection_split_string (const gchar *uri,
       lhost = url[1];
     }
   else
-    lhost = (gchar *) uri;
+    {
+      *protocol = VINAGRE_CONNECTION_PROTOCOL_VNC;
+      lhost = (gchar *) uri;
+    }
 
   if (lhost[0] == '[')
     {
@@ -623,14 +581,14 @@ vinagre_connection_split_string (const gchar *uri,
   if (g_strrstr (lhost, "::") != NULL)
     {
       server = g_strsplit (lhost, "::", 2);
-      lport = server[1] ? atoi (server[1]) : 5900;
+      lport = server[1] ? atoi (server[1]) : vinagre_connection_default_port [*protocol];
     }
   else
     {
       server = g_strsplit (lhost, ":", 2);
-      lport = server[1] ? atoi (server[1]) : 5900;
+      lport = server[1] ? atoi (server[1]) : vinagre_connection_default_port [*protocol];
 
-      if (lport < 1024)
+      if ((*protocol == VINAGRE_CONNECTION_PROTOCOL_VNC) && (lport < 1024))
         lport += 5900;
     }
 
@@ -649,19 +607,21 @@ VinagreConnection *
 vinagre_connection_new_from_string (const gchar *uri, gchar **error_msg, gboolean use_bookmarks)
 {
   VinagreConnection *conn = NULL;
+  VinagreConnectionProtocol protocol;
   gint    port;
   gchar  *host;
 
-  if (!vinagre_connection_split_string (uri, &host, &port, error_msg))
+  if (!vinagre_connection_split_string (uri, &protocol, &host, &port, error_msg))
     return NULL;
 
   if (use_bookmarks)
     conn = vinagre_bookmarks_exists (vinagre_bookmarks_get_default (),
+				     protocol,
 				     host,
 				     port);
   if (!conn)
     {
-      conn = vinagre_connection_new ();
+      conn = vinagre_connection_new (protocol);
       vinagre_connection_set_host (conn, host);
       vinagre_connection_set_port (conn, port);
     }
@@ -681,6 +641,7 @@ vinagre_connection_new_from_file (const gchar *uri, gchar **error_msg, gboolean
   gint               port;
   int                file_size;
   GFile             *file_a;
+  VinagreConnectionProtocol protocol;
 
   *error_msg = NULL;
   host = NULL;
@@ -735,7 +696,7 @@ vinagre_connection_new_from_file (const gchar *uri, gchar **error_msg, gboolean
     {
       if (!port)
 	{
-	  if (!vinagre_connection_split_string (host, &actual_host, &port, error_msg))
+	  if (!vinagre_connection_split_string (host, &protocol, &actual_host, &port, error_msg))
 	    goto the_end;
 
 	  g_free (host);
@@ -743,14 +704,14 @@ vinagre_connection_new_from_file (const gchar *uri, gchar **error_msg, gboolean
 	}
 
       if (use_bookmarks)
-        conn = vinagre_bookmarks_exists (vinagre_bookmarks_get_default (), host, port);
+        conn = vinagre_bookmarks_exists (vinagre_bookmarks_get_default (), protocol, host, port);
       if (!conn)
 	{
 	  gchar *username, *password;
 	  gint shared;
 	  GError *e = NULL;
 
-	  conn = vinagre_connection_new ();
+	  conn = vinagre_connection_new (protocol);
 	  vinagre_connection_set_host (conn, host);
 	  vinagre_connection_set_port (conn, port);
 
@@ -762,14 +723,8 @@ vinagre_connection_new_from_file (const gchar *uri, gchar **error_msg, gboolean
 	  vinagre_connection_set_password (conn, password);
 	  g_free (password);
 
-	  shared = g_key_file_get_integer (file, "options", "shared", &e);
-	  if (e)
-	    g_error_free (e);
-	  else
-	    if (shared == 0 || shared == 1)
-	      vinagre_connection_set_shared (conn, shared);
-	    else
-	      g_message (_("Bad value for 'shared' flag: %d. It is supposed to be 0 or 1. Ignoring it."), shared);
+	  if (VINAGRE_CONNECTION_GET_CLASS (conn)->impl_fill_conn_from_file)
+	    VINAGRE_CONNECTION_GET_CLASS (conn)->impl_fill_conn_from_file (conn, file);
 	}
 
       g_free (host);
@@ -786,72 +741,6 @@ the_end:
   return conn;
 }
 
-GdkPixbuf *
-vinagre_connection_get_icon (VinagreConnection *conn)
-{
-  GdkPixbuf         *pixbuf;
-  GtkIconTheme      *icon_theme;
-
-  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
-
-  icon_theme = gtk_icon_theme_get_default ();
-  pixbuf = gtk_icon_theme_load_icon (icon_theme,
-				     "application-x-vnc",
-				     16,
-				     0,
-				     NULL);
-
-  return pixbuf;
-}
-
-void
-vinagre_connection_set_view_only (VinagreConnection *conn,
-				  gboolean value)
-{
-  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
-
-  conn->priv->view_only = value;
-}
-gboolean
-vinagre_connection_get_view_only (VinagreConnection *conn)
-{
-  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), FALSE);
-
-  return conn->priv->view_only;
-}
-
-void
-vinagre_connection_set_scaling (VinagreConnection *conn,
-				gboolean value)
-{
-  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
-
-  conn->priv->scaling = value;
-}
-gboolean
-vinagre_connection_get_scaling (VinagreConnection *conn)
-{
-  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), FALSE);
-
-  return conn->priv->scaling;
-}
-
-void
-vinagre_connection_set_fullscreen (VinagreConnection *conn,
-				  gboolean value)
-{
-  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
-
-  conn->priv->fullscreen = value;
-}
-gboolean
-vinagre_connection_get_fullscreen (VinagreConnection *conn)
-{
-  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), FALSE);
-
-  return conn->priv->fullscreen;
-}
-
 gchar*
 vinagre_connection_get_string_rep (VinagreConnection *conn,
 				   gboolean has_protocol)
@@ -887,4 +776,33 @@ vinagre_connection_get_string_rep (VinagreConnection *conn,
   return result;
 }
 
+VinagreConnection *
+vinagre_connection_new (VinagreConnectionProtocol protocol)
+{
+  switch (protocol)
+    {
+      case VINAGRE_CONNECTION_PROTOCOL_VNC: return vinagre_vnc_connection_new ();
+      default: g_assert_not_reached ();
+    }
+}
+
+void
+vinagre_connection_fill_writer (VinagreConnection *conn,
+				xmlTextWriter *writer)
+{
+  VINAGRE_CONNECTION_GET_CLASS (conn)->impl_fill_writer (conn, writer);
+}
+
+void
+vinagre_connection_parse_item (VinagreConnection *conn,
+			       xmlNode *root)
+{
+  VINAGRE_CONNECTION_GET_CLASS (conn)->impl_parse_item (conn, root);
+}
+
+gchar*
+vinagre_connection_get_best_name (VinagreConnection *conn)
+{
+  return VINAGRE_CONNECTION_GET_CLASS (conn)->impl_get_best_name (conn);
+}
 /* vim: set ts=8: */
diff --git a/src/vinagre-connection.h b/src/vinagre-connection.h
index bc0f0a0..2c92e6a 100644
--- a/src/vinagre-connection.h
+++ b/src/vinagre-connection.h
@@ -1,8 +1,9 @@
 /*
  * vinagre-connection.h
+ * Abstract base class for all types of connections: VNC, RDP, etc.
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,6 +24,7 @@
 
 #include <glib.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
+#include <libxml/xmlwriter.h>
 
 G_BEGIN_DECLS
 
@@ -46,7 +48,13 @@ typedef enum
 
 struct _VinagreConnectionClass
 {
-  GObjectClass parent_class;
+  GObjectClass	parent_class;
+
+  /* Virtual functions */
+  void		(*impl_fill_writer)		(VinagreConnection *conn, xmlTextWriter *writer);
+  void		(*impl_parse_item)		(VinagreConnection *conn, xmlNode *root);
+  gchar *	(*impl_get_best_name)		(VinagreConnection *conn);
+  void		(*impl_fill_conn_from_file)	(VinagreConnection *conn, GKeyFile *file);
 };
 
 struct _VinagreConnection
@@ -55,12 +63,15 @@ struct _VinagreConnection
   VinagreConnectionPrivate *priv;
 };
 
+
 GType vinagre_connection_get_type (void) G_GNUC_CONST;
 
-VinagreConnection *vinagre_connection_new (void);
+VinagreConnection *vinagre_connection_new (VinagreConnectionProtocol protocol);
+VinagreConnectionProtocol vinagre_connection_protocol_by_name (const gchar *protocol);
 
 VinagreConnectionProtocol vinagre_connection_get_protocol (VinagreConnection *conn);
-void		          vinagre_connection_set_protocol (VinagreConnection *conn,
+const gchar*		  vinagre_connection_get_protocol_as_string (VinagreConnection *conn);
+void			  vinagre_connection_set_protocol (VinagreConnection *conn,
 							   VinagreConnectionProtocol protocol);
 
 const gchar*	    vinagre_connection_get_host		(VinagreConnection *conn);
@@ -79,46 +90,42 @@ const gchar*	    vinagre_connection_get_password	(VinagreConnection *conn);
 void		    vinagre_connection_set_password	(VinagreConnection *conn,
 							 const gchar *password);
 
-const gchar*	    vinagre_connection_get_name         (VinagreConnection *conn);
-void		    vinagre_connection_set_name	        (VinagreConnection *conn,
+const gchar*	    vinagre_connection_get_name		(VinagreConnection *conn);
+void		    vinagre_connection_set_name		(VinagreConnection *conn,
 							 const gchar *name);
 
-const gchar*	    vinagre_connection_get_desktop_name	(VinagreConnection *conn);
-void		    vinagre_connection_set_desktop_name	(VinagreConnection *conn,
-							 const gchar *desktop_name);
-
-gchar*		    vinagre_connection_get_best_name	(VinagreConnection *conn);
-
-VinagreConnection*  vinagre_connection_clone		(VinagreConnection *conn);
-
-VinagreConnection*  vinagre_connection_new_from_string	(const gchar *url, gchar **error_msg, gboolean use_bookmarks);
-VinagreConnection*  vinagre_connection_new_from_file	(const gchar *uri, gchar **error_msg, gboolean use_bookmarks);
-
-GdkPixbuf*          vinagre_connection_get_icon	(VinagreConnection *conn);
-
-gboolean	    vinagre_connection_get_view_only	(VinagreConnection *conn);
-void		    vinagre_connection_set_view_only	(VinagreConnection *conn,
-							 gboolean value);
-
-gboolean	    vinagre_connection_get_scaling	(VinagreConnection *conn);
-void		    vinagre_connection_set_scaling	(VinagreConnection *conn,
-							 gboolean value);
-
 gboolean	    vinagre_connection_get_fullscreen	(VinagreConnection *conn);
 void		    vinagre_connection_set_fullscreen	(VinagreConnection *conn,
 							 gboolean value);
 
-gint		    vinagre_connection_get_shared	(VinagreConnection *conn);
-void		    vinagre_connection_set_shared	(VinagreConnection *conn,
-							 gint value);
+VinagreConnection*  vinagre_connection_new_from_string	(const gchar *url, gchar **error_msg, gboolean use_bookmarks);
+VinagreConnection*  vinagre_connection_new_from_file	(const gchar *uri, gchar **error_msg, gboolean use_bookmarks);
 
 gboolean	    vinagre_connection_split_string	(const gchar *uri,
+							 VinagreConnectionProtocol *protocol,
 							 gchar **host,
 							 gint *port,
 							 gchar **error_msg);
 
 gchar*		    vinagre_connection_get_string_rep	(VinagreConnection *conn,
 							 gboolean has_protocol);
+
+GdkPixbuf*          vinagre_connection_get_icon		(VinagreConnection *conn);
+
+/* Methods that can be overrided */
+
+/* vinagre_connection_fill_writer(): Used to fill a xml writer when saving bookmarks.
+   subclasses must inherit from it and call super() */
+void                vinagre_connection_fill_writer	(VinagreConnection *conn,
+							 xmlTextWriter *writer);
+
+/* vinagre_connection_parse_item(): Used to parse a xml item when loading bookmarks.
+   subclasses must inherit from it and call super() */
+void                vinagre_connection_parse_item	(VinagreConnection *conn,
+							 xmlNode *root);
+
+gchar*		    vinagre_connection_get_best_name    (VinagreConnection *conn);
+
 G_END_DECLS
 
 #endif /* __VINAGRE_CONNECTION_H__  */
diff --git a/src/vinagre-main.c b/src/vinagre-main.c
index fd8da06..cca7e41 100644
--- a/src/vinagre-main.c
+++ b/src/vinagre-main.c
@@ -2,7 +2,7 @@
  * vinagre-main.c
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -168,6 +168,7 @@ int main (int argc, char **argv) {
       
       next = l->next;
       vinagre_cmd_direct_connect (conn, window);
+      g_object_unref (conn);
     }
   g_slist_free (servers);
 
diff --git a/src/vinagre-mdns.c b/src/vinagre-mdns.c
index 1ca18dd..fb0e9d6 100644
--- a/src/vinagre-mdns.c
+++ b/src/vinagre-mdns.c
@@ -60,7 +60,7 @@ mdns_resolver_found (GaServiceResolver *resolver,
   VinagreConnection     *conn;
   VinagreBookmarksEntry *entry;
 
-  conn = vinagre_connection_new ();
+  conn = vinagre_connection_new (VINAGRE_CONNECTION_PROTOCOL_VNC);
   g_object_set (conn,
                 "name", name,
                 "port", port,
diff --git a/src/vinagre-notebook.c b/src/vinagre-notebook.c
index 18e3a5c..af34bf7 100644
--- a/src/vinagre-notebook.c
+++ b/src/vinagre-notebook.c
@@ -2,7 +2,7 @@
  * vinagre-notebook.c
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,9 +22,7 @@
 #include <config.h>
 #endif
 
-#include <glib-object.h>
 #include <glib/gi18n.h>
-#include <gtk/gtk.h>
 
 #include "vinagre-notebook.h"
 #include "vinagre-utils.h"
@@ -35,25 +33,93 @@
 struct _VinagreNotebookPrivate
 {
   VinagreWindow *window;
+  GtkUIManager  *manager;
+  guint         ui_merge_id;
+  VinagreTab    *active_tab;
+};
+
+/* Properties */
+enum
+{
+  PROP_0,
+  PROP_WINDOW
 };
 
 G_DEFINE_TYPE(VinagreNotebook, vinagre_notebook, GTK_TYPE_NOTEBOOK)
 
 static void
+vinagre_notebook_get_property (GObject    *object,
+			       guint       prop_id,
+			       GValue     *value,
+			       GParamSpec *pspec)
+{
+  VinagreNotebook *nb = VINAGRE_NOTEBOOK (object);
+
+  switch (prop_id)
+    {
+      case PROP_WINDOW:
+        g_value_set_object (value, nb->priv->window);
+	break;
+      default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	break;			
+    }
+}
+
+static void
+vinagre_notebook_set_window (VinagreNotebook *nb, VinagreWindow *window)
+{
+  nb->priv->window = window;
+  nb->priv->manager = vinagre_window_get_ui_manager (window);
+  nb->priv->ui_merge_id = gtk_ui_manager_new_merge_id (nb->priv->manager);
+}
+
+static void
+vinagre_notebook_set_property (GObject      *object,
+			       guint         prop_id,
+			       const GValue *value,
+			       GParamSpec   *pspec)
+{
+  VinagreNotebook *nb = VINAGRE_NOTEBOOK (object);
+
+  switch (prop_id)
+    {
+      case PROP_WINDOW:
+	vinagre_notebook_set_window (nb, VINAGRE_WINDOW (g_value_get_object (value)));
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;			
+    }
+}
+
+static void
 vinagre_notebook_class_init (VinagreNotebookClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->get_property = vinagre_notebook_get_property;
+  object_class->set_property = vinagre_notebook_set_property;
+
+  g_object_class_install_property (object_class,
+				   PROP_WINDOW,
+				   g_param_spec_object ("window",
+							"Window",
+							"The VinagreWindow",
+							VINAGRE_TYPE_WINDOW,
+							G_PARAM_READWRITE |
+							G_PARAM_CONSTRUCT_ONLY |
+							G_PARAM_STATIC_NAME |
+							G_PARAM_STATIC_NICK |
+							G_PARAM_STATIC_BLURB));
+
   g_type_class_add_private (object_class, sizeof(VinagreNotebookPrivate));
 }
 
-GtkWidget *
+VinagreNotebook *
 vinagre_notebook_new (VinagreWindow *window)
 {
-  VinagreNotebook *nb = g_object_new (VINAGRE_TYPE_NOTEBOOK, NULL);
-
-  nb->priv->window = window;
-  return GTK_WIDGET (nb);
+  return VINAGRE_NOTEBOOK (g_object_new (VINAGRE_TYPE_NOTEBOOK, "window", window, NULL));
 }
 
 void
@@ -114,24 +180,189 @@ drag_data_get_handl (GtkWidget *widget,
 }
 
 static void
-vinagre_notebook_init (VinagreNotebook *notebook)
+vinagre_notebook_update_ui_sentitivity (VinagreNotebook *nb)
 {
-  notebook->priv = VINAGRE_NOTEBOOK_GET_PRIVATE (notebook);
+  gboolean       active;
+  GtkActionGroup *action_group;
 
-  gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
+  active = gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) > 0;
+  action_group = vinagre_window_get_connected_action (nb->priv->window);
+  gtk_action_group_set_sensitive (action_group, active);
+
+  action_group = vinagre_window_get_initialized_action (nb->priv->window);
+  active = (nb->priv->active_tab) &&
+	   (vinagre_tab_get_state (VINAGRE_TAB (nb->priv->active_tab)) == VINAGRE_TAB_STATE_CONNECTED);
+  gtk_action_group_set_sensitive (action_group, active);
+}
+
+static void
+vinagre_notebook_update_window_title (VinagreNotebook *nb)
+{
+  gchar *title, *name, *extra;
+
+  if (nb->priv->active_tab == NULL)
+    {
+      gtk_window_set_title (GTK_WINDOW (nb->priv->window), g_get_application_name ());
+      return;
+    }
+
+  extra = vinagre_tab_get_extra_title (nb->priv->active_tab);
+  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (nb->priv->active_tab));
+  if (extra)
+    title = g_strdup_printf ("%s %s - %s",
+			     name,
+			     extra,
+			     g_get_application_name ());
+  else
+    title = g_strdup_printf ("%s - %s",
+			     name,
+			     g_get_application_name ());
+
+  gtk_window_set_title (GTK_WINDOW (nb->priv->window), title);
+  g_free (title);
+  g_free (extra);
+  g_free (name);
+}
 
-  g_signal_connect (notebook,
+static void
+insert_actions_ui (VinagreNotebook *nb, GtkActionGroup *action_group, const GSList *actions)
+{
+  VinagreTabUiAction *action;
+  const gchar        *name;
+  gint               i;
+
+  while (actions)
+    {
+      action = (VinagreTabUiAction *) actions->data;
+      name = gtk_action_get_name (action->action);
+
+      gtk_action_group_add_action (action_group, action->action);
+
+      for (i = 0; i < g_strv_length (action->paths); i++)
+	gtk_ui_manager_add_ui (nb->priv->manager,
+			       nb->priv->ui_merge_id,
+			       action->paths[i],
+			       name,
+			       name,
+			       GTK_UI_MANAGER_AUTO,
+			       FALSE);
+
+      actions = actions->next;
+    }
+}
+
+static void
+merge_tab_ui (VinagreNotebook *nb)
+{
+  const GSList   *actions;
+  GtkActionGroup *action_group;
+
+  if (!nb->priv->active_tab)
+    return;
+
+  /* Always sensitive actions */
+  action_group = vinagre_window_get_always_sensitive_action (nb->priv->window);
+  actions = vinagre_tab_get_always_sensitive_actions (nb->priv->active_tab);
+  insert_actions_ui (nb, action_group, actions);
+
+  /* Connected actions */
+  action_group = vinagre_window_get_connected_action (nb->priv->window);
+  actions = vinagre_tab_get_connected_actions (nb->priv->active_tab);
+  insert_actions_ui (nb, action_group, actions);
+
+  /* Initialized actions */
+  action_group = vinagre_window_get_initialized_action (nb->priv->window);
+  actions = vinagre_tab_get_initialized_actions (nb->priv->active_tab);
+  insert_actions_ui (nb, action_group, actions);
+}
+
+static void
+remove_actions_ui (VinagreNotebook *nb, GtkActionGroup *action_group, const GSList *actions)
+{
+  VinagreTabUiAction *action;
+
+  while (actions)
+    {
+      action = (VinagreTabUiAction *) actions->data;
+
+      gtk_action_group_remove_action (action_group, action->action);
+      actions = actions->next;
+    }
+}
+
+static void
+unmerge_tab_ui (VinagreNotebook *nb)
+{
+  const GSList   *actions;
+  GtkActionGroup *action_group;
+
+  if (!nb->priv->active_tab)
+    return;
+
+  gtk_ui_manager_remove_ui (nb->priv->manager,
+			    nb->priv->ui_merge_id);
+
+  /* Always sensitive actions */
+  action_group = vinagre_window_get_always_sensitive_action (nb->priv->window);
+  actions = vinagre_tab_get_always_sensitive_actions (nb->priv->active_tab);
+  remove_actions_ui (nb, action_group, actions);
+
+  /* Connected actions */
+  action_group = vinagre_window_get_connected_action (nb->priv->window);
+  actions = vinagre_tab_get_connected_actions (nb->priv->active_tab);
+  remove_actions_ui (nb, action_group, actions);
+
+  /* Initialized actions */
+  action_group = vinagre_window_get_initialized_action (nb->priv->window);
+  actions = vinagre_tab_get_initialized_actions (nb->priv->active_tab);
+  remove_actions_ui (nb, action_group, actions);
+}
+
+static void 
+vinagre_notebook_page_switched (GtkNotebook     *notebook,
+				GtkNotebookPage *pg,
+				gint            page_num, 
+				gpointer        data)
+{
+  VinagreNotebook *nb = VINAGRE_NOTEBOOK (notebook);
+  VinagreTab *tab;
+
+  tab = VINAGRE_TAB (gtk_notebook_get_nth_page (notebook, page_num));
+  if (tab == nb->priv->active_tab)
+    return;
+
+  unmerge_tab_ui (nb);
+  nb->priv->active_tab = tab;
+  merge_tab_ui (nb);
+
+  vinagre_notebook_update_window_title (nb);
+  vinagre_notebook_update_ui_sentitivity (nb);
+}
+
+static void
+vinagre_notebook_init (VinagreNotebook *nb)
+{
+  nb->priv = VINAGRE_NOTEBOOK_GET_PRIVATE (nb);
+  nb->priv->active_tab = NULL;
+
+  gtk_notebook_set_scrollable (GTK_NOTEBOOK (nb), TRUE);
+
+  g_signal_connect (nb,
 		    "page-added",
 		    G_CALLBACK (vinagre_notebook_show_hide_tabs),
 		    NULL);
-  g_signal_connect (notebook,
+  g_signal_connect (nb,
 		    "page-removed",
 		    G_CALLBACK (vinagre_notebook_show_hide_tabs),
 		    NULL);
+  g_signal_connect (nb,
+		    "switch-page",
+		    G_CALLBACK (vinagre_notebook_page_switched),
+		    NULL);
   g_signal_connect_swapped (vinagre_prefs_get_default (),
 			    "notify::always-show-tabs",
 			     G_CALLBACK (vinagre_notebook_show_hide_tabs),
-			     notebook);
+			     nb);
 }
 
 static void
@@ -141,7 +372,7 @@ close_button_clicked_cb (GtkWidget *widget,
   VinagreNotebook *notebook;
 
   notebook = VINAGRE_NOTEBOOK (gtk_widget_get_parent (tab));
-  vinagre_notebook_remove_tab (notebook, VINAGRE_TAB (tab));
+  vinagre_notebook_close_tab (notebook, VINAGRE_TAB (tab));
 }
 
 static void
@@ -153,7 +384,7 @@ tab_size_changed_cb (VinagreTab *tab, VinagreNotebook *nb)
   label = GTK_WIDGET (g_object_get_data (G_OBJECT (tab), "label-ebox"));
   g_return_if_fail (label != NULL);
 
-  str = vinagre_tab_get_tooltips (tab);
+  str = vinagre_tab_get_tooltip (tab);
   gtk_widget_set_tooltip_markup (label, str);
 
   g_free (str);
@@ -171,7 +402,42 @@ tab_disconnected_cb (VinagreTab *tab, VinagreNotebook *nb)
   g_free (message);
   g_free (name);
 
-  vinagre_notebook_remove_tab (nb, tab);
+  vinagre_notebook_close_tab (nb, tab);
+}
+
+static void
+tab_auth_failed_cb (VinagreTab *tab, const gchar *msg, VinagreNotebook *nb)
+{
+  GString *message;
+  gchar   *name;
+
+  message = g_string_new (NULL);
+  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (tab));
+
+  g_string_printf (message, _("Authentication to host <i>%s</i> has failed"),
+		   name);
+  if (msg)
+  	g_string_append_printf (message, " (%s)", msg);
+  g_string_append_c (message, '.');
+
+  vinagre_utils_show_error (_("Authentication failed"), message->str, GTK_WINDOW (nb->priv->window));
+  g_string_free (message, TRUE);
+  g_free (name);
+
+  // TODO: Remover se der pau
+  //if (tab->priv->keyring_item_id > 0)
+  //  {
+   //   gnome_keyring_item_delete_sync (NULL, tab->priv->keyring_item_id);
+   //   tab->priv->keyring_item_id = 0;
+  //  }
+
+  vinagre_notebook_close_tab (nb, tab);
+}
+
+static void
+tab_initialized_cb (VinagreTab *tab, VinagreNotebook *nb)
+{
+  vinagre_notebook_update_ui_sentitivity (nb);
 }
 
 static GtkWidget *
@@ -257,16 +523,6 @@ build_tab_label (VinagreNotebook *nb,
   g_object_set_data (G_OBJECT (hbox), "close-button", close_button);
   g_object_set_data (G_OBJECT (tab),  "close-button", close_button);
 
-  g_signal_connect (tab,
-		    "notify::original-width",
-		    G_CALLBACK (tab_size_changed_cb),
-		    nb);
-
-  g_signal_connect (tab,
-		    "tab-disconnected",
-		    G_CALLBACK (tab_disconnected_cb),
-		    nb);
-
   gtk_drag_source_set ( GTK_WIDGET (hbox),
 			GDK_BUTTON1_MASK,
 			vinagre_target_list,
@@ -285,14 +541,23 @@ vinagre_notebook_add_tab (VinagreNotebook *nb,
 			  VinagreTab      *tab,
 			  gint           position)
 {
-  GtkWidget *label;
-  int pos;
+  GtkWidget      *label;
+  GtkActionGroup *action_group;
+  int            pos;
 
   g_return_if_fail (VINAGRE_IS_NOTEBOOK (nb));
   g_return_if_fail (VINAGRE_IS_TAB (tab));
 
-  label = build_tab_label (nb, tab);
+  /* Unmerge the UI for the current tab */
+  unmerge_tab_ui (nb);
 
+  nb->priv->active_tab = tab;  
+  
+  /* Merge the UI for the new tab */
+  merge_tab_ui (nb);
+
+  /* Actually add the new tab */
+  label = build_tab_label (nb, tab);
   pos = gtk_notebook_insert_page (GTK_NOTEBOOK (nb), 
 				  GTK_WIDGET (tab),
 				  label, 
@@ -300,40 +565,103 @@ vinagre_notebook_add_tab (VinagreNotebook *nb,
 
   gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), pos);
   vinagre_tab_set_notebook (tab, nb);
-}
 
-static void
-remove_tab (VinagreTab *tab,
-	    VinagreNotebook *nb)
-{
-  vinagre_notebook_remove_tab (nb, tab);
+  g_signal_connect (tab,
+		    "notify::original-width",
+		    G_CALLBACK (tab_size_changed_cb),
+		    nb);
+
+  g_signal_connect (tab,
+		    "tab-disconnected",
+		    G_CALLBACK (tab_disconnected_cb),
+		    nb);
+
+  g_signal_connect (tab,
+		    "tab-auth-failed",
+		    G_CALLBACK (tab_auth_failed_cb),
+		    nb);
+
+  g_signal_connect (tab,
+		    "tab-initialized",
+		    G_CALLBACK (tab_initialized_cb),
+		    nb);
+
+  vinagre_notebook_update_window_title (nb);
+  vinagre_notebook_update_ui_sentitivity (nb);
 }
 
 void
-vinagre_notebook_remove_tab (VinagreNotebook *nb,
-			     VinagreTab      *tab)
+vinagre_notebook_close_tab (VinagreNotebook *nb,
+			    VinagreTab      *tab)
 {
-  gint position;
+  gint           position;
+  GtkActionGroup *action_group;
+  GtkNotebook    *notebook;
 
   g_return_if_fail (VINAGRE_IS_NOTEBOOK (nb));
   g_return_if_fail (VINAGRE_IS_TAB (tab));
 
-  position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (tab));
+  notebook = GTK_NOTEBOOK (nb);
 
   g_signal_handlers_disconnect_by_func (tab,
 					G_CALLBACK (tab_disconnected_cb),
 					nb);
+  g_signal_handlers_disconnect_by_func (tab,
+					G_CALLBACK (tab_auth_failed_cb),
+					nb);
+
+  /* If it's closing the current tab, unmerge the UI */
+  if (nb->priv->active_tab == tab)
+    unmerge_tab_ui (nb);
 
-  gtk_notebook_remove_page (GTK_NOTEBOOK (nb), position);
+  position = gtk_notebook_page_num (notebook, GTK_WIDGET (tab));
+  g_signal_handlers_block_by_func (notebook, vinagre_notebook_page_switched, NULL);
+  gtk_notebook_remove_page (notebook, position);
+  g_signal_handlers_unblock_by_func (notebook, vinagre_notebook_page_switched, NULL);
+  
+  position = gtk_notebook_get_current_page (notebook);
+  nb->priv->active_tab = VINAGRE_TAB (gtk_notebook_get_nth_page (notebook,
+								 position));
+
+  /* Merge the UI for the new tab (if one exists) */
+  merge_tab_ui (nb);
+
+  vinagre_notebook_update_window_title (nb);
+  vinagre_notebook_update_ui_sentitivity (nb);
+}
+
+static void
+close_tab (VinagreTab *tab,
+	    VinagreNotebook *nb)
+{
+  vinagre_notebook_close_tab (nb, tab);
 }
 
 void
-vinagre_notebook_remove_all_tabs (VinagreNotebook *nb)
+vinagre_notebook_close_all_tabs (VinagreNotebook *nb)
 {	
   g_return_if_fail (VINAGRE_IS_NOTEBOOK (nb));
 	
   gtk_container_foreach (GTK_CONTAINER (nb),
-			(GtkCallback) remove_tab,
+			(GtkCallback) close_tab,
 			 nb);
 }
+
+void
+vinagre_notebook_close_active_tab (VinagreNotebook *nb)
+{
+  g_return_if_fail (VINAGRE_IS_NOTEBOOK (nb));
+  g_return_if_fail (nb->priv->active_tab != NULL);
+
+  vinagre_notebook_close_tab (nb, nb->priv->active_tab);
+}
+
+VinagreTab *
+vinagre_notebook_get_active_tab (VinagreNotebook *nb)
+{
+  g_return_val_if_fail (VINAGRE_IS_NOTEBOOK (nb), NULL);
+
+  return nb->priv->active_tab;
+}
+
 /* vim: set ts=8: */
diff --git a/src/vinagre-notebook.h b/src/vinagre-notebook.h
index 200bbe3..afa52c6 100644
--- a/src/vinagre-notebook.h
+++ b/src/vinagre-notebook.h
@@ -2,7 +2,7 @@
  * vinagre-notebook.h
  * This file is part of vinagre
  *
- * Copyright (C) 2007 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,14 +21,10 @@
 #ifndef __VINAGRE_NOTEBOOK_H__
 #define __VINAGRE_NOTEBOOK_H__
 
-#include <glib.h>
 #include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 
-/*
- * Type checking and casting macros
- */
 #define VINAGRE_TYPE_NOTEBOOK		(vinagre_notebook_get_type ())
 #define VINAGRE_NOTEBOOK(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), VINAGRE_TYPE_NOTEBOOK, VinagreNotebook))
 #define VINAGRE_NOTEBOOK_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), VINAGRE_TYPE_NOTEBOOK, VinagreNotebookClass))
@@ -36,12 +32,8 @@ G_BEGIN_DECLS
 #define VINAGRE_IS_NOTEBOOK_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), VINAGRE_TYPE_NOTEBOOK))
 #define VINAGRE_NOTEBOOK_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), VINAGRE_TYPE_NOTEBOOK, VinagreNotebookClass))
 
-/* Private structure type */
 typedef struct _VinagreNotebookPrivate	VinagreNotebookPrivate;
-
-/*
- * Main object structure
- */
+typedef struct _VinagreNotebookClass	VinagreNotebookClass;
 typedef struct _VinagreNotebook		VinagreNotebook;
 
 #include "vinagre-window.h"
@@ -49,51 +41,29 @@ typedef struct _VinagreNotebook		VinagreNotebook;
 
 struct _VinagreNotebook
 {
-	GtkNotebook notebook;
-
-	/*< private >*/
-        VinagreNotebookPrivate *priv;
+  GtkNotebook notebook;
+  VinagreNotebookPrivate *priv;
 };
 
-/*
- * Class definition
- */
-typedef struct _VinagreNotebookClass	VinagreNotebookClass;
-
 struct _VinagreNotebookClass
 {
   GtkNotebookClass parent_class;
-
-  /* Signals */
-  void	 (* tab_added)      (VinagreNotebook *notebook,
-			     VinagreTab      *tab);
-  void	 (* tab_removed)    (VinagreNotebook *notebook,
-			     VinagreTab      *tab);
-  void	 (* tab_detached)   (VinagreNotebook *notebook,
-			     VinagreTab      *tab);
-  void	 (* tabs_reordered) (VinagreNotebook *notebook);
-  void	 (* tab_close_request)
-			    (VinagreNotebook *notebook,
-			     VinagreTab      *tab);
 };
 
-/*
- * Public methods
- */
-GType		vinagre_notebook_get_type		(void) G_GNUC_CONST;
-
-GtkWidget      *vinagre_notebook_new			(VinagreWindow *window);
-
-void		vinagre_notebook_add_tab		(VinagreNotebook *nb,
-							 VinagreTab      *tab,
-							 gint           position);
+GType			vinagre_notebook_get_type		(void) G_GNUC_CONST;
+VinagreNotebook *	vinagre_notebook_new			(VinagreWindow *window);
 
-void		vinagre_notebook_remove_tab		(VinagreNotebook *nb,
-							 VinagreTab      *tab);
+void			vinagre_notebook_add_tab		(VinagreNotebook *nb,
+								 VinagreTab      *tab,
+								 gint           position);
+void			vinagre_notebook_close_tab		(VinagreNotebook *nb,
+								 VinagreTab      *tab);
+void			vinagre_notebook_close_all_tabs 	(VinagreNotebook *nb);
+void			vinagre_notebook_close_active_tab	(VinagreNotebook *nb);
 
-void		vinagre_notebook_remove_all_tabs 	(VinagreNotebook *nb);
+void			vinagre_notebook_show_hide_tabs		(VinagreNotebook *nb);
 
-void		vinagre_notebook_show_hide_tabs		(VinagreNotebook *nb);
+VinagreTab *		vinagre_notebook_get_active_tab		(VinagreNotebook *nb);
 G_END_DECLS
 
 #endif /* __VINAGRE_NOTEBOOK_H__ */
diff --git a/src/vinagre-tab.c b/src/vinagre-tab.c
index f4fbca0..a5828ac 100644
--- a/src/vinagre-tab.c
+++ b/src/vinagre-tab.c
@@ -1,8 +1,9 @@
 /*
  * vinagre-tab.c
+ * Abstract base class for all types of tabs: VNC, RDP, etc.
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,14 +23,12 @@
 #include <config.h>
 #endif
 
-#include <gdk/gdkkeysyms.h>
 #include <glib/gi18n.h>
 #include <glade/glade.h>
 #include <gnome-keyring.h>
-#include <vncdisplay.h>
 
-#include "vinagre-notebook.h"
 #include "vinagre-tab.h"
+#include "vinagre-notebook.h"
 #include "vinagre-utils.h"
 #include "vinagre-prefs.h"
 #include "view/autoDrawer.h"
@@ -38,7 +37,7 @@
 
 struct _VinagreTabPrivate
 {
-  GtkWidget         *vnc;
+  GtkWidget         *view;
   GtkWidget         *scroll;
   VinagreConnection *conn;
   VinagreNotebook   *nb;
@@ -46,15 +45,11 @@ struct _VinagreTabPrivate
   gboolean           save_credential;
   guint32            keyring_item_id;
   VinagreTabState    state;
-  gchar             *clipboard_str;
   GtkWidget         *layout;
   GtkWidget         *toolbar;
-  GtkWidget         *ro_button;
-  GtkWidget         *scaling_button;
-  gboolean           pointer_grab;
 };
 
-G_DEFINE_TYPE(VinagreTab, vinagre_tab, GTK_TYPE_VBOX)
+G_DEFINE_ABSTRACT_TYPE (VinagreTab, vinagre_tab, GTK_TYPE_VBOX)
 
 /* Signals */
 enum
@@ -62,6 +57,7 @@ enum
   TAB_CONNECTED,
   TAB_DISCONNECTED,
   TAB_INITIALIZED,
+  TAB_AUTH_FAILED,
   LAST_SIGNAL
 };
 
@@ -70,9 +66,7 @@ enum
 {
   PROP_0,
   PROP_CONN,
-  PROP_WINDOW,
-  PROP_ORIGINAL_WIDTH,
-  PROP_ORIGINAL_HEIGHT
+  PROP_WINDOW
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -82,26 +76,25 @@ vinagre_tab_window_state_cb (GtkWidget           *widget,
 			     GdkEventWindowState *event,
 			     VinagreTab          *tab)
 {
-  int vnc_w, vnc_h, screen_w, screen_h;
+  int view_w, view_h, screen_w, screen_h;
   GdkScreen *screen;
   GtkPolicyType h, v;
 
   if ((event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) == 0)
     return FALSE;
 
-  vnc_w = vnc_display_get_width (VNC_DISPLAY (tab->priv->vnc));
-  vnc_h = vnc_display_get_height (VNC_DISPLAY (tab->priv->vnc));
+  vinagre_tab_get_dimensions (tab, &view_w, &view_h);
 
   screen = gtk_widget_get_screen (GTK_WIDGET (tab));
   screen_w = gdk_screen_get_width (screen);
   screen_h = gdk_screen_get_height (screen);
 
-  if (vnc_w <= screen_w)
+  if (view_w <= screen_w)
     h = GTK_POLICY_NEVER;
   else
     h = GTK_POLICY_AUTOMATIC;
   
-  if (vnc_h <= screen_h)
+  if (view_h <= screen_h)
     v = GTK_POLICY_NEVER;
   else
     v = GTK_POLICY_AUTOMATIC;
@@ -142,12 +135,6 @@ vinagre_tab_get_property (GObject    *object,
       case PROP_WINDOW:
         g_value_set_object (value, tab->priv->window);
 	break;
-      case PROP_ORIGINAL_WIDTH:
-        g_value_set_int (value, vinagre_tab_get_original_width (tab));
-	break;
-      case PROP_ORIGINAL_HEIGHT:
-        g_value_set_int (value, vinagre_tab_get_original_height (tab));
-	break;
       default:
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 	break;			
@@ -165,7 +152,7 @@ vinagre_tab_set_property (GObject      *object,
   switch (prop_id)
     {
       case PROP_CONN:
-        tab->priv->conn = g_value_get_object (value);
+        tab->priv->conn = g_value_dup_object (value);
 	g_object_set_data (G_OBJECT (tab->priv->conn), VINAGRE_TAB_KEY, tab);
         break;
       case PROP_WINDOW:
@@ -182,16 +169,6 @@ vinagre_tab_set_property (GObject      *object,
 }
 
 static void
-vinagre_tab_finalize (GObject *object)
-{
-  VinagreTab *tab = VINAGRE_TAB (object);
-
-  g_free (tab->priv->clipboard_str);
-
-  G_OBJECT_CLASS (vinagre_tab_parent_class)->finalize (object);
-}
-
-static void
 vinagre_tab_dispose (GObject *object)
 {
   VinagreTab *tab = VINAGRE_TAB (object);
@@ -201,7 +178,6 @@ vinagre_tab_dispose (GObject *object)
       g_signal_handlers_disconnect_by_func (tab->priv->window,
   					    vinagre_tab_window_state_cb,
   					    tab);
-
       g_object_unref (tab->priv->conn);
       tab->priv->conn = NULL;
     }
@@ -209,16 +185,54 @@ vinagre_tab_dispose (GObject *object)
   G_OBJECT_CLASS (vinagre_tab_parent_class)->dispose (object);
 }
 
+void
+default_get_dimensions (VinagreTab *tab, int *w, int *h)
+{
+  *w = -1;
+  *h = -1;
+}
+
+const GSList *
+default_get_always_sensitive_actions (VinagreTab *tab)
+{
+  return NULL;
+}
+
+const GSList *
+default_get_connected_actions (VinagreTab *tab)
+{
+  return NULL;
+}
+
+const GSList *
+default_get_initialized_actions (VinagreTab *tab)
+{
+  return NULL;
+}
+
+gchar *
+default_get_extra_title (VinagreTab *tab)
+{
+  return NULL;
+}
+
 static void 
 vinagre_tab_class_init (VinagreTabClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = vinagre_tab_finalize;
   object_class->dispose  = vinagre_tab_dispose;
   object_class->get_property = vinagre_tab_get_property;
   object_class->set_property = vinagre_tab_set_property;
 
+  klass->impl_get_tooltip = NULL;
+  klass->impl_get_screenshot = NULL;
+  klass->impl_get_dimensions = default_get_dimensions;
+  klass->impl_get_always_sensitive_actions = default_get_always_sensitive_actions;
+  klass->impl_get_connected_actions = default_get_connected_actions;
+  klass->impl_get_initialized_actions = default_get_initialized_actions;
+  klass->impl_get_extra_title = default_get_extra_title;
+
   g_object_class_install_property (object_class,
 				   PROP_CONN,
 				   g_param_spec_object ("conn",
@@ -242,28 +256,6 @@ vinagre_tab_class_init (VinagreTabClass *klass)
 							G_PARAM_STATIC_NICK |
 							G_PARAM_STATIC_BLURB));
 
-  g_object_class_install_property (object_class,
-				   PROP_ORIGINAL_WIDTH,
-				   g_param_spec_int ("original-width",
-						     "Original width",
-						     "The original width of the remote screen",
-						     -1, G_MAXINT, 0,
-						      G_PARAM_READABLE |
-						      G_PARAM_STATIC_NAME |
-						      G_PARAM_STATIC_NICK |
-						      G_PARAM_STATIC_BLURB));
-
-  g_object_class_install_property (object_class,
-				   PROP_ORIGINAL_HEIGHT,
-				   g_param_spec_int ("original-height",
-						     "Original height",
-						     "The original height of the remote screen",
-						     -1, G_MAXINT, 0,
-						      G_PARAM_READABLE |
-						      G_PARAM_STATIC_NAME |
-						      G_PARAM_STATIC_NICK |
-						      G_PARAM_STATIC_BLURB));
-
   signals[TAB_CONNECTED] =
 		g_signal_new ("tab-connected",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -294,144 +286,21 @@ vinagre_tab_class_init (VinagreTabClass *klass)
 			      G_TYPE_NONE,
 			      0);
 
-  g_type_class_add_private (object_class, sizeof (VinagreTabPrivate));
-}
-
-static void
-open_vnc (VinagreTab *tab)
-{
-  gchar *port;
-  gint  shared;
-
-  vnc_display_set_force_size (VNC_DISPLAY(tab->priv->vnc),
-			      !vinagre_connection_get_scaling (tab->priv->conn));
-
-  port = g_strdup_printf ("%d", vinagre_connection_get_port (tab->priv->conn));
-
-  shared = vinagre_connection_get_shared (tab->priv->conn);
-  if (shared == -1)
-    g_object_get (vinagre_prefs_get_default (),
-		  "shared-flag", &shared,
-		  NULL);
-  vnc_display_set_shared_flag (VNC_DISPLAY (tab->priv->vnc),
-			       shared);
-
-  if (vnc_display_open_host (VNC_DISPLAY(tab->priv->vnc), vinagre_connection_get_host (tab->priv->conn), port))
-    gtk_widget_grab_focus (tab->priv->vnc);
-  else
-    vinagre_utils_show_error (NULL, _("Error connecting to host."), NULL);
-
-  g_free (port);
-}
-
-static void
-vnc_connected_cb (VncDisplay *vnc, VinagreTab *tab)
-{
-  /* Emits the signal saying that we have connected to the machine */
-  g_signal_emit (G_OBJECT (tab),
-		 signals[TAB_CONNECTED],
-		 0);
-}
-
-static void
-vnc_disconnected_cb (VncDisplay *vnc, VinagreTab *tab)
-{
-  /* Emits the signal saying that we have disconnected from the machine */
-  g_signal_emit (G_OBJECT (tab),
-		 signals[TAB_DISCONNECTED],
-		 0);
-}
-
-static void
-vnc_auth_failed_cb (VncDisplay *vnc, const gchar *msg, VinagreTab *tab)
-{
-  GString *message;
-  gchar   *name;
-
-  message = g_string_new (NULL);
-  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (tab));
-
-  g_string_printf (message, _("Authentication to host <i>%s</i> has failed"),
-		   name);
-  if (msg)
-  	g_string_append_printf (message, " (%s)", msg);
-  g_string_append_c (message, '.');
-
-  vinagre_utils_show_error (_("Authentication failed"), message->str, GTK_WINDOW (tab->priv->window));
-  g_string_free (message, TRUE);
-  g_free (name);
-
-  if (tab->priv->keyring_item_id > 0)
-    {
-      gnome_keyring_item_delete_sync (NULL, tab->priv->keyring_item_id);
-      tab->priv->keyring_item_id = 0;
-    }
-
-  vinagre_notebook_remove_tab (tab->priv->nb, tab);
-}
-
-static void
-vnc_auth_unsupported_cb (VncDisplay *vnc, guint auth_type, VinagreTab *tab)
-{
-  GString *message;
-  gchar   *name;
-
-  message = g_string_new (NULL);
-  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (tab));
-
-  g_string_printf (message, _("Authentication method to host <i>%s</i> is unsupported. (%u)"),
-		   name,
-		   auth_type);
-
-  vinagre_utils_show_error (_("Authentication unsupported"), message->str, GTK_WINDOW (tab->priv->window));
-  g_string_free (message, TRUE);
-  g_free (name);
-
-  vinagre_notebook_remove_tab (tab->priv->nb, tab);
-}
-
-/* text was actually requested */
-static void
-copy_cb (GtkClipboard     *clipboard,
-         GtkSelectionData *data,
-	 guint             info,
-	 VinagreTab       *tab)
-{
-  gtk_selection_data_set_text (data, tab->priv->clipboard_str, -1);
-}
-
-static void
-vnc_server_cut_text_cb (VncDisplay *vnc, const gchar *text, VinagreTab *tab)
-{
-  GtkClipboard *cb;
-  gsize a, b;
-  GtkTargetEntry targets[] = {
-				{"UTF8_STRING", 0, 0},
-				{"COMPOUND_TEXT", 0, 0},
-				{"TEXT", 0, 0},
-				{"STRING", 0, 0},
-			     };
-
-  if (!text)
-    return;
-
-  g_free (tab->priv->clipboard_str);
-  tab->priv->clipboard_str = g_convert (text, -1, "utf-8", "iso8859-1", &a, &b, NULL);
+  signals[TAB_AUTH_FAILED] =
+		g_signal_new ("tab-auth-failed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (VinagreTabClass, tab_auth_failed),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__STRING,
+			      G_TYPE_NONE,
+			      1,
+			      G_TYPE_STRING);
 
-  if (tab->priv->clipboard_str)
-    {
-      cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
-      gtk_clipboard_set_with_owner (cb,
-				    targets,
-				    G_N_ELEMENTS(targets),
-				    (GtkClipboardGetFunc) copy_cb,
-				    NULL,
-				    G_OBJECT (tab));
-    }
+  g_type_class_add_private (object_class, sizeof (VinagreTabPrivate));
 }
 
-static void
+void
 vinagre_tab_add_recent_used (VinagreTab *tab)
 {
   GtkRecentManager *manager;
@@ -532,280 +401,10 @@ vinagre_tab_find_credentials (VinagreTab *tab, gchar **username, gchar **passwor
 }
 
 static void
-vnc_initialized_cb (VncDisplay *vnc, VinagreTab *tab)
-{
-  GtkLabel *label;
-  gchar    *name;
-  gboolean scaling, view_only, fullscreen;
-
-  g_object_get (tab->priv->conn,
-		"view-only", &view_only,
-		"scaling", &scaling,
-		"fullscreen", &fullscreen,
-		NULL);
-
-  vinagre_tab_set_scaling (tab, scaling);
-  vinagre_tab_set_readonly (tab, view_only);
-  vnc_display_set_pointer_local (VNC_DISPLAY(tab->priv->vnc), TRUE);
-  vnc_display_set_keyboard_grab (VNC_DISPLAY(tab->priv->vnc), TRUE);
-  vnc_display_set_pointer_grab (VNC_DISPLAY(tab->priv->vnc), TRUE);
-
-  if (fullscreen)
-    vinagre_window_toggle_fullscreen (tab->priv->window);
-
-  vinagre_connection_set_desktop_name (tab->priv->conn,
-				       vnc_display_get_name (VNC_DISPLAY (tab->priv->vnc)));
-
-  name = vinagre_connection_get_best_name (tab->priv->conn);
-  label = g_object_get_data (G_OBJECT (tab), "label");
-  g_return_if_fail (label != NULL);
-  gtk_label_set_label (label, name);
-  g_free (name);
-
-  vinagre_window_set_title (tab->priv->window);
-  vinagre_tab_save_credential (tab);
-  vinagre_tab_add_recent_used (tab);
-
-  tab->priv->state = VINAGRE_TAB_STATE_CONNECTED;
-  vinagre_window_update_machine_menu_sensitivity (tab->priv->window);
-
-  /* Emits the signal saying that we have connected to the machine */
-  g_signal_emit (G_OBJECT (tab),
-		 signals[TAB_INITIALIZED],
-		 0);
-}
-
-typedef struct {
-  GtkWidget *uname, *pw, *button;
-} ControlOKButton;
-
-static void
-control_ok_button (GtkEditable *entry, ControlOKButton *data)
-{
-  gboolean enabled = TRUE;
-
-  if (GTK_WIDGET_VISIBLE (data->uname))
-    enabled = enabled && gtk_entry_get_text_length (GTK_ENTRY (data->uname)) > 0;
-
-  if (GTK_WIDGET_VISIBLE (data->pw))
-    enabled = enabled && gtk_entry_get_text_length (GTK_ENTRY (data->pw)) > 0;
-
-  gtk_widget_set_sensitive (data->button, enabled);
-}
-
-static gboolean
-ask_credential (VinagreTab *tab,
-		gboolean    need_username,
-		gboolean    need_password,
-		gchar     **username,
-		gchar     **password)
-{
-  GladeXML        *xml;
-  const char      *glade_file;
-  GtkWidget       *password_dialog, *host_label, *save_credential_check;
-  GtkWidget       *password_label, *username_label, *image;
-  gchar           *name, *label;
-  int             result;
-  ControlOKButton control;
-
-  glade_file = vinagre_utils_get_glade_filename ();
-  xml = glade_xml_new (glade_file, NULL, NULL);
-
-  password_dialog = glade_xml_get_widget (xml, "auth_required_dialog");
-  gtk_window_set_transient_for (GTK_WINDOW(password_dialog), GTK_WINDOW(tab->priv->window));
-
-  host_label = glade_xml_get_widget (xml, "host_label");
-  name = vinagre_connection_get_best_name (tab->priv->conn);
-  label = g_strdup_printf ("<i>%s</i>", name);
-  gtk_label_set_markup (GTK_LABEL (host_label), label);
-  g_free (name);
-  g_free (label);
-
-  control.uname  = glade_xml_get_widget (xml, "username_entry");
-  control.pw     = glade_xml_get_widget (xml, "password_entry");
-  control.button = glade_xml_get_widget (xml, "ok_button");
-  password_label = glade_xml_get_widget (xml, "password_label");
-  username_label = glade_xml_get_widget (xml, "username_label");
-  save_credential_check = glade_xml_get_widget (xml, "save_credential_check");
-
-  image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_BUTTON);
-  gtk_button_set_image (GTK_BUTTON (control.button), image);
-
-  g_signal_connect (control.uname, "changed", G_CALLBACK (control_ok_button), &control);
-  g_signal_connect (control.pw, "changed", G_CALLBACK (control_ok_button), &control);
-
-  if (need_username)
-    {
-      if (*username)
-        gtk_entry_set_text (GTK_ENTRY (control.uname), *username);
-    }
-  else
-    {
-      gtk_widget_hide (username_label);
-      gtk_widget_hide (control.uname);
-    }
-
-  if (need_password)
-    {
-      if (*password)
-        gtk_entry_set_text (GTK_ENTRY (control.pw), *password);
-    }
-  else
-    {
-      gtk_widget_hide (password_label);
-      gtk_widget_hide (control.pw);
-    }
-
-  result = gtk_dialog_run (GTK_DIALOG (password_dialog));
-  if (result == -5)
-    {
-      g_free (*username);
-      if (gtk_entry_get_text_length (GTK_ENTRY (control.uname)) > 0)
-	*username = g_strdup (gtk_entry_get_text (GTK_ENTRY (control.uname)));
-      else
-	*username = NULL;
-
-      g_free (*password);
-      if (gtk_entry_get_text_length (GTK_ENTRY (control.pw)) > 0)
-	*password = g_strdup (gtk_entry_get_text (GTK_ENTRY (control.pw)));
-      else
-	*password = NULL;
-
-      tab->priv->save_credential = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (save_credential_check));
-    }
-
-  gtk_widget_destroy (GTK_WIDGET (password_dialog));
-  g_object_unref (xml);
-
-  return result == -5;
-}
-
-static void
-vnc_authentication_cb (VncDisplay *vnc, GValueArray *credList, VinagreTab *tab)
-{
-  gchar *username, *password;
-  gboolean need_password, need_username;
-  int i;
-
-  if (credList == NULL)
-    return;
-
-  need_password = FALSE;
-  need_username = FALSE;
-  username = NULL;
-  password = NULL;
-
-  for (i = 0; i < credList->n_values; i++) {
-    switch (g_value_get_enum (&credList->values[i]))
-      {
-	case VNC_DISPLAY_CREDENTIAL_USERNAME:
-	  if (vinagre_connection_get_username (tab->priv->conn))
-	    {
-	      vnc_display_set_credential (vnc, VNC_DISPLAY_CREDENTIAL_USERNAME, vinagre_connection_get_username (tab->priv->conn));
-	      break;
-	    }
-	  need_username= TRUE;
-	  break;
-
-	case VNC_DISPLAY_CREDENTIAL_PASSWORD:
-	  if (vinagre_connection_get_password (tab->priv->conn))
-	    {
-	      vnc_display_set_credential (vnc, VNC_DISPLAY_CREDENTIAL_PASSWORD, vinagre_connection_get_password (tab->priv->conn));
-	      break;
-	    }
-	  need_password = TRUE;
-	  break;
-
-        case VNC_DISPLAY_CREDENTIAL_CLIENTNAME:
-          vnc_display_set_credential (vnc, VNC_DISPLAY_CREDENTIAL_CLIENTNAME, "vinagre");
-          break;
-      }
-  }
-
-  if (need_password || need_username)
-    {
-      vinagre_tab_find_credentials (tab, &username, &password);
-      if ( (need_username && !username) || (need_password && !password) )
-	{
-	  if (!ask_credential (tab, need_username, need_password, &username, &password))
-	    {
-	      vinagre_notebook_remove_tab (tab->priv->nb, tab);
-	      goto out;
-	    }
-	}
-
-      if (need_username)
-	{
-	  if (username)
-	    {
-	      vinagre_connection_set_username (tab->priv->conn, username);
-	      vnc_display_set_credential (vnc, VNC_DISPLAY_CREDENTIAL_USERNAME, username);
-	    }
-	  else
-	    {
-	      vinagre_notebook_remove_tab (tab->priv->nb, tab);
-	      vinagre_utils_show_error (_("Authentication error"),
-					_("A username is required in order to access this machine."),
-					GTK_WINDOW (tab->priv->window));
-	      goto out;
-	    }
-	}
-
-      if (need_password)
-	{
-	  if (password)
-	    {
-	      vinagre_connection_set_password (tab->priv->conn, password);
-	      vnc_display_set_credential (vnc, VNC_DISPLAY_CREDENTIAL_PASSWORD, password);
-	    }
-	  else
-	    {
-	      vinagre_notebook_remove_tab (tab->priv->nb, tab);
-	      vinagre_utils_show_error (_("Authentication error"),
-					_("A password is required in order to access this machine."),
-					GTK_WINDOW (tab->priv->window));
-	      goto out;
-	    }
-	}
-
-out:
-      g_free (username);
-      g_free (password);
-    }
-}
-
-static void
-vnc_pointer_grab_cb (VncDisplay *vnc, VinagreTab *tab)
-{
-  tab->priv->pointer_grab = TRUE;
-  vinagre_window_set_title (tab->priv->window);
-}
-
-static void
-vnc_pointer_ungrab_cb (VncDisplay *vnc, VinagreTab *tab)
-{
-  tab->priv->pointer_grab = FALSE;
-  vinagre_window_set_title (tab->priv->window);
-}
-
-static void
-vnc_bell_cb (VncDisplay *vnc, VinagreTab *tab)
-{
-  gdk_window_beep (GTK_WIDGET (tab->priv->window)->window);
-}
-
-static void
-vnc_desktop_resize_cb (VncDisplay *vnc, int x, int y, VinagreTab *tab)
-{
-  g_object_notify (G_OBJECT (tab), "original-width");
-  g_object_notify (G_OBJECT (tab), "original-height");
-}
-
-static void
 close_button_clicked (GtkToolButton *button,
 		      VinagreTab    *tab)
 {
-  vinagre_notebook_remove_tab (tab->priv->nb, tab);
+  vinagre_notebook_close_tab (tab->priv->nb, tab);
 }
 
 static void
@@ -830,40 +429,6 @@ screenshot_button_clicked (GtkToolButton *button,
 }
 
 static void
-cad_button_clicked (GtkToolButton *button,
-		    VinagreTab    *tab)
-{
-  vinagre_tab_send_ctrlaltdel (tab);
-}
-
-static void
-ro_button_clicked (GtkToggleToolButton *button,
-		   VinagreTab          *tab)
-{
-  GtkAction *action;
-
-  vinagre_tab_set_readonly (tab, gtk_toggle_tool_button_get_active (button));
-
-  action = gtk_action_group_get_action (vinagre_window_get_connected_action (tab->priv->window), "ViewReadOnly");
-  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
-				vinagre_tab_get_readonly (tab));
-}
-
-static void
-scaling_button_clicked (GtkToggleToolButton *button,
-			VinagreTab          *tab)
-{
-  GtkAction *action;
-
-  if (!vinagre_tab_set_scaling (tab, gtk_toggle_tool_button_get_active (button)))
-    gtk_toggle_tool_button_set_active (button, FALSE);
-
-  action = gtk_action_group_get_action (vinagre_window_get_connected_action (tab->priv->window), "ViewScaling");
-  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
-				vinagre_tab_get_scaling (tab));
-}
-
-static void
 setup_layout (VinagreTab *tab)
 {
   GtkWidget  *button;
@@ -882,6 +447,7 @@ setup_layout (VinagreTab *tab)
 
   /* Leave fullscreen */
   button = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_LEAVE_FULLSCREEN));
+  g_object_set (button, "is-important", TRUE, NULL);
   gtk_widget_show (GTK_WIDGET (button));
   gtk_toolbar_insert (GTK_TOOLBAR (tab->priv->toolbar), GTK_TOOL_ITEM (button), 0);
   g_signal_connect (button, "clicked", G_CALLBACK (fullscreen_button_clicked), tab);
@@ -901,26 +467,6 @@ setup_layout (VinagreTab *tab)
   gtk_widget_show (GTK_WIDGET (button));
   gtk_toolbar_insert (GTK_TOOLBAR (tab->priv->toolbar), GTK_TOOL_ITEM (button), 0);
 
-  /* Scaling */
-  button = GTK_WIDGET (gtk_toggle_tool_button_new ());
-  gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), _("Scaling"));
-  gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (button), _("Scaling"));
-  gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), "zoom-fit-best");
-  gtk_widget_show (GTK_WIDGET (button));
-  gtk_toolbar_insert (GTK_TOOLBAR (tab->priv->toolbar), GTK_TOOL_ITEM (button), 0);
-  g_signal_connect (button, "toggled", G_CALLBACK (scaling_button_clicked), tab);
-  tab->priv->scaling_button = button;
-
-  /* Read only */
-  button = GTK_WIDGET (gtk_toggle_tool_button_new ());
-  gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), _("Read only"));
-  gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (button), _("Read only"));
-  gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), "emblem-readonly");
-  gtk_widget_show (GTK_WIDGET (button));
-  gtk_toolbar_insert (GTK_TOOLBAR (tab->priv->toolbar), GTK_TOOL_ITEM (button), 0);
-  g_signal_connect (button, "toggled", G_CALLBACK (ro_button_clicked), tab);
-  tab->priv->ro_button = button;
-
   /* Screenshot */
   button = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
   gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), "applets-screenshooter");
@@ -930,15 +476,6 @@ setup_layout (VinagreTab *tab)
   gtk_widget_show (GTK_WIDGET (button));
   gtk_toolbar_insert (GTK_TOOLBAR (tab->priv->toolbar), GTK_TOOL_ITEM (button), 0);
 
-  /* Send Ctrl-alt-del */
-  button = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
-  gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), "preferences-desktop-keyboard-shortcuts");
-  gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), _("Send Ctrl-Alt-Del"));
-  gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (button), _("Send Ctrl-Alt-Del"));
-  g_signal_connect (button, "clicked", G_CALLBACK (cad_button_clicked), tab);
-  gtk_widget_show (GTK_WIDGET (button));
-  gtk_toolbar_insert (GTK_TOOLBAR (tab->priv->toolbar), GTK_TOOL_ITEM (button), 0);
-
   tab->priv->layout = ViewAutoDrawer_New ();
   ViewAutoDrawer_SetActive (VIEW_AUTODRAWER (tab->priv->layout), FALSE);
   ViewOvBox_SetOver (VIEW_OV_BOX (tab->priv->layout), tab->priv->toolbar);
@@ -948,14 +485,10 @@ setup_layout (VinagreTab *tab)
 static void
 vinagre_tab_init (VinagreTab *tab)
 {
-  GtkWidget *viewport;
-
   tab->priv = VINAGRE_TAB_GET_PRIVATE (tab);
   tab->priv->save_credential = FALSE;
   tab->priv->keyring_item_id = 0;
   tab->priv->state = VINAGRE_TAB_STATE_INITIALIZING;
-  tab->priv->clipboard_str = NULL;
-  tab->priv->pointer_grab = FALSE;
 
   /* Create the scrolled window */
   tab->priv->scroll = gtk_scrolled_window_new (NULL, NULL);
@@ -965,69 +498,6 @@ vinagre_tab_init (VinagreTab *tab)
   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (tab->priv->scroll),
 				       GTK_SHADOW_NONE);
 
-  /* Create the vnc widget */
-  tab->priv->vnc = vnc_display_new ();
-
-  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (tab->priv->scroll),
-					 tab->priv->vnc);
-  viewport = gtk_bin_get_child (GTK_BIN (tab->priv->scroll));
-  gtk_viewport_set_shadow_type(GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-connected",
-		    G_CALLBACK (vnc_connected_cb),
-		    tab);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-initialized",
-		    G_CALLBACK (vnc_initialized_cb),
-		    tab);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-disconnected",
-		    G_CALLBACK (vnc_disconnected_cb),
-		    tab);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-auth-credential",
-		    G_CALLBACK (vnc_authentication_cb),
-		    tab);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-pointer-grab",
-		    G_CALLBACK (vnc_pointer_grab_cb),
-		    tab);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-pointer-ungrab",
-		    G_CALLBACK (vnc_pointer_ungrab_cb),
-		    tab);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-auth-failure",
-		    G_CALLBACK (vnc_auth_failed_cb),
-		    tab);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-auth-unsupported",
-		    G_CALLBACK (vnc_auth_unsupported_cb),
-		    tab);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-server-cut-text",
-		    G_CALLBACK (vnc_server_cut_text_cb),
-		    tab);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-bell",
-		    G_CALLBACK (vnc_bell_cb),
-		    tab);
-
-  g_signal_connect (tab->priv->vnc,
-		    "vnc-desktop-resize",
-		    G_CALLBACK (vnc_desktop_resize_cb),
-		    tab);
-
   setup_layout (tab);
 
   gtk_box_pack_end (GTK_BOX(tab), tab->priv->layout, TRUE, TRUE, 0);
@@ -1037,33 +507,43 @@ vinagre_tab_init (VinagreTab *tab)
 GtkWidget *
 vinagre_tab_new (VinagreConnection *conn, VinagreWindow *window)
 {
-  VinagreTab *tab = g_object_new (VINAGRE_TYPE_TAB, 
-				   "conn", conn,
-				   "window", window,
-				   NULL);
-  open_vnc (tab);
-  return GTK_WIDGET (tab);
+  switch (vinagre_connection_get_protocol (conn))
+    {
+      case VINAGRE_CONNECTION_PROTOCOL_VNC: return GTK_WIDGET (vinagre_vnc_tab_new (conn, window));
+      default: g_assert_not_reached ();
+    }
 }
 
+gchar *
+vinagre_tab_get_tooltip (VinagreTab *tab)
+{
+  g_return_val_if_fail (VINAGRE_IS_TAB (tab), NULL);
+
+  return VINAGRE_TAB_GET_CLASS (tab)->impl_get_tooltip (tab);
+}
 
 gchar *
-vinagre_tab_get_tooltips (VinagreTab *tab)
+vinagre_tab_get_extra_title (VinagreTab *tab)
+{
+  g_return_val_if_fail (VINAGRE_IS_TAB (tab), NULL);
+
+  return VINAGRE_TAB_GET_CLASS (tab)->impl_get_extra_title (tab);
+}
+
+void
+vinagre_tab_get_dimensions (VinagreTab *tab, int *w, int *h)
 {
-  gchar *tip;
+  g_return_if_fail (VINAGRE_IS_TAB (tab));
 
+  VINAGRE_TAB_GET_CLASS (tab)->impl_get_dimensions (tab, w, h);
+}
+
+VinagreWindow *
+vinagre_tab_get_window (VinagreTab *tab)
+{
   g_return_val_if_fail (VINAGRE_IS_TAB (tab), NULL);
 
-  tip =  g_markup_printf_escaped (
-				  "<b>%s</b> %s\n\n"
-				  "<b>%s</b> %s\n"
-				  "<b>%s</b> %d\n"
-				  "<b>%s</b> %dx%d",
-				  _("Desktop Name:"), vnc_display_get_name (VNC_DISPLAY (tab->priv->vnc)),
-				  _("Host:"), vinagre_connection_get_host (tab->priv->conn),
-				  _("Port:"), vinagre_connection_get_port (tab->priv->conn),
-				  _("Dimensions:"), vnc_display_get_width (VNC_DISPLAY (tab->priv->vnc)), vnc_display_get_height (VNC_DISPLAY (tab->priv->vnc)));
-
-  return tip;
+  return tab->priv->window;
 }
 
 VinagreConnection *
@@ -1074,12 +554,26 @@ vinagre_tab_get_conn (VinagreTab *tab)
   return tab->priv->conn;
 }
 
+void
+vinagre_tab_add_view (VinagreTab *tab, GtkWidget *view)
+{
+  GtkWidget *viewport;
+
+  g_return_if_fail (VINAGRE_IS_TAB (tab));
+
+  tab->priv->view = view;
+  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (tab->priv->scroll),
+					 view);
+  viewport = gtk_bin_get_child (GTK_BIN (tab->priv->scroll));
+  gtk_viewport_set_shadow_type(GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
+}
+
 GtkWidget *
-vinagre_tab_get_vnc (VinagreTab *tab)
+vinagre_tab_get_view (VinagreTab *tab)
 {
   g_return_val_if_fail (VINAGRE_IS_TAB (tab), NULL);
 
-  return tab->priv->vnc;
+  return tab->priv->view;
 }
 
 void
@@ -1112,6 +606,105 @@ vinagre_tab_get_notebook (VinagreTab *tab)
   return tab->priv->nb;
 }
 
+VinagreTabState
+vinagre_tab_get_state (VinagreTab *tab)
+{
+  g_return_val_if_fail (VINAGRE_IS_TAB (tab), VINAGRE_TAB_STATE_INVALID);
+
+  return tab->priv->state;
+}
+
+void
+vinagre_tab_set_state (VinagreTab *tab, VinagreTabState state)
+{
+  tab->priv->state = state;
+}
+
+GtkWidget *
+vinagre_tab_get_toolbar (VinagreTab *tab)
+{
+  g_return_val_if_fail (VINAGRE_IS_TAB (tab), NULL);
+
+  return tab->priv->toolbar;
+}
+
+VinagreTab *
+vinagre_tab_get_from_connection (VinagreConnection *conn)
+{
+  gpointer res;
+	
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
+	
+  res = g_object_get_data (G_OBJECT (conn), VINAGRE_TAB_KEY);
+	
+  return (res != NULL) ? VINAGRE_TAB (res) : NULL;
+}
+
+gboolean
+vinagre_tab_find_credentials_in_keyring (VinagreTab *tab, gchar **username, gchar **password)
+{
+  GnomeKeyringNetworkPasswordData *found_item;
+  GnomeKeyringResult               result;
+  GList                           *matches;
+  
+  matches   = NULL;
+  *username = NULL;
+  *password = NULL;
+
+  result = gnome_keyring_find_network_password_sync (
+                vinagre_connection_get_username (tab->priv->conn),            /* user     */
+		NULL,                                                         /* domain   */
+		vinagre_connection_get_host (tab->priv->conn),                /* server   */
+		NULL,                                                         /* object   */
+		vinagre_connection_get_protocol_as_string (tab->priv->conn),  /* protocol */
+		"vnc-password",                                               /* authtype */
+		vinagre_connection_get_port (tab->priv->conn),                /* port     */
+		&matches);
+
+  if (result != GNOME_KEYRING_RESULT_OK || matches == NULL || matches->data == NULL)
+    return FALSE;
+
+  found_item = (GnomeKeyringNetworkPasswordData *) matches->data;
+
+  *username = g_strdup (found_item->user);
+  *password = g_strdup (found_item->password);
+  
+  tab->priv->keyring_item_id = found_item->item_id;
+
+  gnome_keyring_network_password_list_free (matches);
+
+  return TRUE;
+}
+
+void
+vinagre_tab_save_credentials_in_keyring (VinagreTab *tab)
+{
+  GnomeKeyringResult result;
+
+  result = gnome_keyring_set_network_password_sync (
+                NULL,                                                        /* default keyring */
+                vinagre_connection_get_username (tab->priv->conn),           /* user            */
+                NULL,                                                        /* domain          */
+                vinagre_connection_get_host (tab->priv->conn),               /* server          */
+                NULL,                                                        /* object          */
+                vinagre_connection_get_protocol_as_string (tab->priv->conn), /* protocol        */
+                "vnc-password",                                              /* authtype        */
+                vinagre_connection_get_port (tab->priv->conn),               /* port            */
+                vinagre_connection_get_password (tab->priv->conn),           /* password        */
+                &tab->priv->keyring_item_id);
+
+  if (result != GNOME_KEYRING_RESULT_OK)
+    vinagre_utils_show_error (_("Error saving the credentials on the keyring."),
+			      gnome_keyring_result_to_message (result),
+			      GTK_WINDOW (tab->priv->window));
+}
+
+void
+vinagre_tab_remove_from_notebook (VinagreTab *tab)
+{
+  vinagre_notebook_close_tab (tab->priv->nb, tab);
+}
+
 void
 vinagre_tab_take_screenshot (VinagreTab *tab)
 {
@@ -1123,7 +716,7 @@ vinagre_tab_take_screenshot (VinagreTab *tab)
 
   g_return_if_fail (VINAGRE_IS_TAB (tab));
 
-  pix = vnc_display_get_pixbuf (VNC_DISPLAY (tab->priv->vnc));
+  pix = VINAGRE_TAB_GET_CLASS (tab)->impl_get_screenshot (tab);
   if (!pix)
     {
       vinagre_utils_show_error (NULL,
@@ -1166,189 +759,45 @@ vinagre_tab_take_screenshot (VinagreTab *tab)
   g_free (name);
 }
 
-void
-vinagre_tab_send_ctrlaltdel (VinagreTab *tab)
-{
-  guint keys[] = { GDK_Control_L, GDK_Alt_L, GDK_Delete };
-
-  g_return_if_fail (VINAGRE_IS_TAB (tab));
-
-  vnc_display_send_keys_ex (VNC_DISPLAY (tab->priv->vnc), keys, sizeof (keys) / sizeof (keys[0]), VNC_DISPLAY_KEY_EVENT_CLICK);
-}
-
-void
-vinagre_tab_paste_text (VinagreTab *tab, const gchar *text)
-{
-  gchar *out;
-  size_t a, b;
-  g_return_if_fail (VINAGRE_IS_TAB (tab));
-
-  out = g_convert (text, -1, "iso8859-1", "utf-8", &a, &b, NULL);
-
-  if (out)
-    {
-      vnc_display_client_cut_text (VNC_DISPLAY (tab->priv->vnc), out);
-      g_free (out);
-    }
-}
-
-gboolean
-vinagre_tab_set_scaling (VinagreTab *tab, gboolean active) {
-  g_return_val_if_fail (VINAGRE_IS_TAB (tab), FALSE);
-
-  if (vnc_display_get_scaling (VNC_DISPLAY (tab->priv->vnc)) == active)
-    return TRUE;
-
-  vnc_display_set_force_size (VNC_DISPLAY(tab->priv->vnc), !active);
-  if (!vnc_display_set_scaling (VNC_DISPLAY (tab->priv->vnc), active))
-    {
-      vinagre_utils_show_error (NULL, _("Scaling is not supported on this installation.\n\nRead the README file (shipped with Vinagre) in order to know how to enable this feature."),
-				GTK_WINDOW (tab->priv->window));
-      return FALSE;
-    }
-
-  gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (tab->priv->scaling_button),
-				     active);
-
-  if (active)
-    gtk_widget_set_size_request (tab->priv->vnc, 0, 0);
-  else
-    gtk_widget_set_size_request (tab->priv->vnc,
-				 vnc_display_get_width (VNC_DISPLAY (tab->priv->vnc)),
-				 vnc_display_get_height (VNC_DISPLAY (tab->priv->vnc)));
-
-  return TRUE;
-}
-
-gboolean
-vinagre_tab_get_scaling (VinagreTab *tab) {
-  g_return_val_if_fail (VINAGRE_IS_TAB (tab), FALSE);
-
-  return vnc_display_get_scaling (VNC_DISPLAY (tab->priv->vnc));
-}
-
-void
-vinagre_tab_set_readonly (VinagreTab *tab, gboolean active) {
-  g_return_if_fail (VINAGRE_IS_TAB (tab));
-
-  vnc_display_set_read_only (VNC_DISPLAY (tab->priv->vnc), active);
-  gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (tab->priv->ro_button),
-				     active);
-
-}
-
-gboolean
-vinagre_tab_get_readonly (VinagreTab *tab) {
-  g_return_val_if_fail (VINAGRE_IS_TAB (tab), FALSE);
-
-  return vnc_display_get_read_only (VNC_DISPLAY (tab->priv->vnc));
-}
-
-VinagreTabState
-vinagre_tab_get_state (VinagreTab *tab)
+const GSList *
+vinagre_tab_get_always_sensitive_actions (VinagreTab *tab)
 {
-  g_return_val_if_fail (VINAGRE_IS_TAB (tab), VINAGRE_TAB_STATE_INVALID);
-
-  return tab->priv->state;
-}
-
-VinagreTab *
-vinagre_tab_get_from_connection (VinagreConnection *conn)
-{
-  gpointer res;
-	
-  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
-	
-  res = g_object_get_data (G_OBJECT (conn), VINAGRE_TAB_KEY);
-	
-  return (res != NULL) ? VINAGRE_TAB (res) : NULL;
-}
-
-gboolean
-vinagre_tab_is_pointer_grab (VinagreTab *tab)
-{
-  g_return_val_if_fail (VINAGRE_IS_TAB (tab), FALSE);
-
-  return tab->priv->pointer_grab;
-}
-
-gint
-vinagre_tab_get_original_height (VinagreTab *tab)
-{
-  g_return_val_if_fail (VINAGRE_IS_TAB (tab), -1);
+  g_return_val_if_fail (VINAGRE_IS_TAB (tab), NULL);
 
-  if (VNC_IS_DISPLAY (tab->priv->vnc))
-    return vnc_display_get_height (VNC_DISPLAY (tab->priv->vnc));
-  else
-    return -1;
+  VINAGRE_TAB_GET_CLASS (tab)->impl_get_always_sensitive_actions (tab);
 }
 
-gint
-vinagre_tab_get_original_width (VinagreTab *tab)
+const GSList *
+vinagre_tab_get_connected_actions (VinagreTab *tab)
 {
-  g_return_val_if_fail (VINAGRE_IS_TAB (tab), -1);
+  g_return_val_if_fail (VINAGRE_IS_TAB (tab), NULL);
 
-  if (VNC_IS_DISPLAY (tab->priv->vnc))
-    return vnc_display_get_width (VNC_DISPLAY (tab->priv->vnc));
-  else
-    return -1;
+  VINAGRE_TAB_GET_CLASS (tab)->impl_get_connected_actions (tab);
 }
 
-
-typedef struct _VinagrePrefSize {
-  gint width, height;
-  gulong sig_id;
-} VinagrePrefSize;
-
-static gboolean
-cb_unset_size (gpointer data)
+const GSList *
+vinagre_tab_get_initialized_actions (VinagreTab *tab)
 {
-  GtkWidget *widget = data;
-
-  gtk_widget_queue_resize_no_redraw (widget);
+  g_return_val_if_fail (VINAGRE_IS_TAB (tab), NULL);
 
-  return FALSE;
+  VINAGRE_TAB_GET_CLASS (tab)->impl_get_initialized_actions (tab);
 }
 
 static void
-cb_set_preferred_size (GtkWidget *widget, GtkRequisition *req,
-		       gpointer data)
-{
-  VinagrePrefSize *size = data;
-
-  req->width = size->width;
-  req->height = size->height;
-
-  g_signal_handler_disconnect (widget, size->sig_id);
-  g_free (size);
-  g_idle_add (cb_unset_size, widget);
-}
-
-void
-vinagre_widget_set_preferred_size (GtkWidget *widget, gint width,
-				 gint height)
+free_actions (gpointer data, gpointer user_data)
 {
-  VinagrePrefSize *size = g_new (VinagrePrefSize, 1);
+  VinagreTabUiAction *action = (VinagreTabUiAction *)data;
 
-  size->width = width;
-  size->height = height;
-  size->sig_id = g_signal_connect (widget, "size-request",
-				   G_CALLBACK (cb_set_preferred_size),
-				   size);
-
-  gtk_widget_queue_resize (widget);
+  g_strfreev (action->paths);
+  g_object_unref (action->action);
+  g_free (action);
 }
 
 void
-vinagre_tab_original_size (VinagreTab *tab)
+vinagre_tab_free_actions (GSList *actions)
 {
-  g_return_if_fail (VINAGRE_IS_TAB (tab));
-
-  gtk_window_unmaximize (GTK_WINDOW (tab->priv->window));
-  gtk_window_resize (GTK_WINDOW (tab->priv->window), 1, 1);
-  vinagre_widget_set_preferred_size (GTK_WIDGET (tab),
-				     vinagre_tab_get_original_width (tab),
-				     vinagre_tab_get_original_height (tab));
+  g_slist_foreach (actions, (GFunc) free_actions, NULL);
+  g_slist_free (actions);
 }
 
 /* vim: set ts=8: */
diff --git a/src/vinagre-tab.h b/src/vinagre-tab.h
index 315a159..bb2d25d 100644
--- a/src/vinagre-tab.h
+++ b/src/vinagre-tab.h
@@ -1,8 +1,9 @@
 /*
  * vinagre-tab.h
+ * Abstract base class for all types of tabs: VNC, RDP, etc.
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,52 +57,86 @@ struct _VinagreTab
   VinagreTabPrivate *priv;
 };
 
+typedef struct
+{
+  gchar     **paths; /* NULL-terminated array of strings */
+  GtkAction *action;
+} VinagreTabUiAction;
+
 struct _VinagreTabClass 
 {
   GtkVBoxClass parent_class;
 
   /* Signals */
-  void		(* tab_connected)		(VinagreTab *tab);
-  void		(* tab_disconnected)		(VinagreTab *tab);
-  void		(* tab_initialized)		(VinagreTab *tab);
+  void		(* tab_connected)			(VinagreTab *tab);
+  void		(* tab_disconnected)			(VinagreTab *tab);
+  void		(* tab_initialized)			(VinagreTab *tab);
+  void		(* tab_auth_failed)			(VinagreTab *tab, const gchar *msg);
+
+  /* Virtual functions */
+  void		(* impl_get_dimensions)			(VinagreTab *tab, int *w, int *h);
+  const GSList *(* impl_get_always_sensitive_actions)	(VinagreTab *tab);
+  const GSList *(* impl_get_connected_actions)		(VinagreTab *tab);
+  const GSList *(* impl_get_initialized_actions)	(VinagreTab *tab);
+  gchar *	(* impl_get_extra_title)		(VinagreTab *tab);
+
+  /* Abstract functions */
+  gchar *	(* impl_get_tooltip)			(VinagreTab *tab);
+  GdkPixbuf *	(* impl_get_screenshot)			(VinagreTab *tab);
 };
 
-GType 		  vinagre_tab_get_type		(void) G_GNUC_CONST;
+GType			vinagre_tab_get_type		(void) G_GNUC_CONST;
+
+GtkWidget *		vinagre_tab_new 		(VinagreConnection *conn,
+							 VinagreWindow     *window);
+
+VinagreConnection *	vinagre_tab_get_conn		(VinagreTab *tab);
+VinagreWindow *		vinagre_tab_get_window		(VinagreTab *tab);
 
-GtkWidget 	  *vinagre_tab_new 		(VinagreConnection *conn,
-						 VinagreWindow     *window);
+void			vinagre_tab_add_view		(VinagreTab *tab, GtkWidget *view);
+GtkWidget *		vinagre_tab_get_view		(VinagreTab *tab);
 
-VinagreConnection *vinagre_tab_get_conn		(VinagreTab *tab);
+void			vinagre_tab_set_title		(VinagreTab *tab,
+							 const char *title);
 
-GtkWidget         *vinagre_tab_get_vnc		(VinagreTab *tab);
+void			vinagre_tab_set_notebook	(VinagreTab *tab,
+							 VinagreNotebook *nb);
+VinagreNotebook *	vinagre_tab_get_notebook	(VinagreTab *tab);
 
-gchar             *vinagre_tab_get_tooltips     (VinagreTab *tab);
+VinagreTabState		vinagre_tab_get_state		(VinagreTab *tab);
+VinagreTab *		vinagre_tab_get_from_connection	(VinagreConnection *conn);
 
-void		  vinagre_tab_set_title		(VinagreTab *tab,
-						 const char *title);
+void			vinagre_tab_take_screenshot	(VinagreTab *tab);
+gchar *			vinagre_tab_get_tooltip		(VinagreTab *tab);
+void			vinagre_tab_get_dimensions	(VinagreTab *tab, int *w, int *h);
 
-void		  vinagre_tab_set_notebook	(VinagreTab *tab,
-						 VinagreNotebook *nb);
-VinagreNotebook   *vinagre_tab_get_notebook	(VinagreTab *tab);
+const GSList *		vinagre_tab_get_always_sensitive_actions(VinagreTab *tab);
+const GSList *		vinagre_tab_get_connected_actions	(VinagreTab *tab);
+const GSList *		vinagre_tab_get_initialized_actions	(VinagreTab *tab);
+GtkActionGroup *	vinagre_tab_get_action_group		(VinagreTab *tab);
 
-void		  vinagre_tab_take_screenshot	(VinagreTab *tab);
-void		  vinagre_tab_send_ctrlaltdel	(VinagreTab *tab);
-void		  vinagre_tab_paste_text	(VinagreTab *tab,
-						 const gchar *text);
+gchar *			vinagre_tab_get_extra_title	(VinagreTab *tab);
+GtkWidget *		vinagre_tab_get_toolbar		(VinagreTab *tab);
 
-gboolean	  vinagre_tab_set_scaling	(VinagreTab *tab, gboolean active);
-gboolean	  vinagre_tab_get_scaling	(VinagreTab *tab);
-void	          vinagre_tab_set_readonly	(VinagreTab *tab, gboolean active);
-gboolean	  vinagre_tab_get_readonly	(VinagreTab *tab);
+void			vinagre_tab_free_actions	(GSList *actions);
 
-gint		  vinagre_tab_get_original_width  (VinagreTab *tab);
-gint		  vinagre_tab_get_original_height (VinagreTab *tab);
-void		  vinagre_tab_original_size	  (VinagreTab *tab);
+/* Protected functions */
+void			vinagre_tab_save_credentials_in_keyring (VinagreTab *tab);
+gboolean		vinagre_tab_find_credentials_in_keyring	(VinagreTab *tab,
+								 gchar **username,
+								 gchar **password);
 
-VinagreTabState   vinagre_tab_get_state		(VinagreTab *tab);
-VinagreTab	  *vinagre_tab_get_from_connection (VinagreConnection *conn);
+void			vinagre_tab_remove_from_notebook	(VinagreTab *tab);
+void			vinagre_tab_add_recent_used		(VinagreTab *tab);
+void			vinagre_tab_set_state			(VinagreTab *tab,
+								 VinagreTabState state);
 
-gboolean	  vinagre_tab_is_pointer_grab	(VinagreTab *tab);
+void			vinagre_tab_add_actions			(VinagreTab *tab,
+								 const GtkActionEntry *entries,
+								 guint n_entries);
+void			vinagre_tab_add_toggle_actions		(VinagreTab *tab,
+								 const GtkToggleActionEntry *entries,
+								 guint n_entries);
 G_END_DECLS
 
 #endif  /* __VINAGRE_TAB_H__  */
diff --git a/src/vinagre-ui.h b/src/vinagre-ui.h
index 7865a0c..964c186 100644
--- a/src/vinagre-ui.h
+++ b/src/vinagre-ui.h
@@ -2,7 +2,7 @@
  * vinagre-ui.h
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@
 
 G_BEGIN_DECLS
 
-static const GtkActionEntry vinagre_always_sensitive_menu_entries[] =
+static const GtkActionEntry vinagre_always_sensitive_entries[] =
 {
   /* Toplevel */
   { "Machine", NULL, N_("_Machine") },
@@ -65,7 +65,22 @@ static const GtkActionEntry vinagre_always_sensitive_menu_entries[] =
     N_("About this application"), G_CALLBACK (vinagre_cmd_help_about) }
 };
 
-static const GtkActionEntry vinagre_menu_entries[] =
+static const GtkToggleActionEntry vinagre_always_sensitive_toggle_entries[] =
+{
+  { "ViewToolbar", NULL, N_("_Toolbar"), NULL,
+    N_("Show or hide the toolbar"),
+    G_CALLBACK (vinagre_cmd_view_show_toolbar), FALSE },
+
+  { "ViewStatusbar", NULL, N_("_Statusbar"), NULL,
+    N_("Show or hide the statusbar"),
+    G_CALLBACK (vinagre_cmd_view_show_statusbar), FALSE },
+
+  { "ViewSidePanel", NULL, N_("Side _Panel"), "F9",
+    N_("Show or hide the side panel"),
+    G_CALLBACK (vinagre_cmd_view_show_fav_panel), FALSE }
+};
+
+static const GtkActionEntry vinagre_machine_connected_entries[] =
 {
   /* Machine menu */
   { "MachineClose", GTK_STOCK_CLOSE, NULL, "<control>W",
@@ -79,47 +94,20 @@ static const GtkActionEntry vinagre_menu_entries[] =
 
 };
 
-static const GtkActionEntry vinagre_machine_connected_menu_entries[] =
+static const GtkActionEntry vinagre_machine_initialized_entries[] =
 {
   /* Machine menu */
   { "MachineTakeScreenshot", "applets-screenshooter", N_("Take screenshot"), NULL,
     N_("Take a screenshot of active connection"), G_CALLBACK (vinagre_cmd_machine_take_screenshot) },
 
-  { "MachineSendCtrlAltDel", "preferences-desktop-keyboard-shortcuts", N_("Send Ctrl-Alt-Del"), NULL,
-    N_("Send Ctrl+Alt+Del to active connection"), G_CALLBACK (vinagre_cmd_machine_send_ctrlaltdel) },
-
   /* View menu */
   { "ViewFullScreen", GTK_STOCK_FULLSCREEN, NULL, "F11",
-    N_("View the current machine in full screen"), G_CALLBACK (vinagre_cmd_view_fullscreen) },
-
-  { "ViewOriginalSize", "zoom-original", N_("_Original size"), NULL,
-    N_("Adjusts the window to the remote desktop's size"), G_CALLBACK (vinagre_cmd_view_original_size) },
-
-};
-
-static const GtkToggleActionEntry vinagre_machine_connected_toggle_menu_entries[] =
-{
-  { "ViewScaling", NULL, N_("S_caling"), NULL,
-    N_("Fit the remote screen into the current window size"),
-    G_CALLBACK (vinagre_cmd_view_scaling), FALSE },
-  { "ViewReadOnly", NULL, N_("_Read only"), NULL,
-    N_("Disable mouse and keyboard"),
-    G_CALLBACK (vinagre_cmd_view_readonly), FALSE }
+    N_("View the current machine in full screen"), G_CALLBACK (vinagre_cmd_view_fullscreen) }
 };
 
-static const GtkToggleActionEntry vinagre_always_sensitive_toggle_menu_entries[] =
+static const GtkToggleActionEntry vinagre_machine_initialized_toggle_entries[] =
 {
-  { "ViewToolbar", NULL, N_("_Toolbar"), NULL,
-    N_("Show or hide the toolbar"),
-    G_CALLBACK (vinagre_cmd_view_show_toolbar), FALSE },
-
-  { "ViewStatusbar", NULL, N_("_Statusbar"), NULL,
-    N_("Show or hide the statusbar"),
-    G_CALLBACK (vinagre_cmd_view_show_statusbar), FALSE },
-
-  { "ViewSidePanel", NULL, N_("Side _Panel"), "F9",
-    N_("Show or hide the side panel"),
-    G_CALLBACK (vinagre_cmd_view_show_fav_panel), FALSE }
+ 0,
 };
 
 G_END_DECLS
diff --git a/src/vinagre-utils.c b/src/vinagre-utils.c
index 2396302..c779816 100644
--- a/src/vinagre-utils.c
+++ b/src/vinagre-utils.c
@@ -471,4 +471,14 @@ vinagre_utils_help_about (GtkWindow *window)
   g_free (license_trans);
 }
 
+gboolean
+vinagre_utils_parse_boolean (const gchar* value)
+{
+  if (g_ascii_strcasecmp (value, "true") == 0 || strcmp (value, "1") == 0)
+    return TRUE;
+
+  return FALSE;
+}
+
+
 /* vim: set ts=8: */
diff --git a/src/vinagre-utils.h b/src/vinagre-utils.h
index 56491f3..a164fd1 100644
--- a/src/vinagre-utils.h
+++ b/src/vinagre-utils.h
@@ -70,5 +70,8 @@ void		vinagre_utils_get_current_viewport	(GdkScreen    *screen,
 
 void		vinagre_utils_help_contents		(GtkWindow *window);
 void		vinagre_utils_help_about		(GtkWindow *window);
+
+gboolean	vinagre_utils_parse_boolean		(const gchar* value);
+
 #endif  /* __VINAGRE_UTILS_H__  */
 /* vim: set ts=8: */
diff --git a/src/vinagre-vnc-connection.c b/src/vinagre-vnc-connection.c
new file mode 100644
index 0000000..f70b04b
--- /dev/null
+++ b/src/vinagre-vnc-connection.c
@@ -0,0 +1,341 @@
+/*
+ * vinagre-vnc-connection.c
+ * Child class of abstract VinagreConnection, specific to VNC protocol
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2009 - Jonh Wendell <wendell bani com br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+#include "vinagre-vnc-connection.h"
+
+struct _VinagreVncConnectionPrivate
+{
+  gchar    *desktop_name;
+  gboolean view_only;
+  gboolean scaling;
+  gint     shared;
+};
+
+enum
+{
+  PROP_0,
+  PROP_DESKTOP_NAME,
+  PROP_VIEW_ONLY,
+  PROP_SCALING,
+  PROP_SHARED,
+};
+
+#define VINAGRE_VNC_CONNECTION_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), VINAGRE_TYPE_VNC_CONNECTION, VinagreVncConnectionPrivate))
+G_DEFINE_TYPE (VinagreVncConnection, vinagre_vnc_connection, VINAGRE_TYPE_CONNECTION);
+
+static void
+vinagre_vnc_connection_init (VinagreVncConnection *conn)
+{
+  conn->priv = G_TYPE_INSTANCE_GET_PRIVATE (conn, VINAGRE_TYPE_VNC_CONNECTION, VinagreVncConnectionPrivate);
+
+  vinagre_connection_set_protocol (VINAGRE_CONNECTION (conn), VINAGRE_CONNECTION_PROTOCOL_VNC);
+  conn->priv->desktop_name = NULL;
+  conn->priv->view_only = FALSE;
+  conn->priv->scaling = FALSE;
+  conn->priv->shared = -1;
+}
+
+static void
+vinagre_vnc_connection_finalize (GObject *object)
+{
+  VinagreVncConnection *conn = VINAGRE_VNC_CONNECTION (object);
+
+  g_free (conn->priv->desktop_name);
+
+  G_OBJECT_CLASS (vinagre_vnc_connection_parent_class)->finalize (object);
+}
+
+static void
+vinagre_vnc_connection_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+  VinagreVncConnection *conn;
+
+  g_return_if_fail (VINAGRE_IS_VNC_CONNECTION (object));
+
+  conn = VINAGRE_VNC_CONNECTION (object);
+
+  switch (prop_id)
+    {
+      case PROP_DESKTOP_NAME:
+	vinagre_vnc_connection_set_desktop_name (conn, g_value_get_string (value));
+	break;
+
+      case PROP_VIEW_ONLY:
+	vinagre_vnc_connection_set_view_only (conn, g_value_get_boolean (value));
+	break;
+
+      case PROP_SCALING:
+	vinagre_vnc_connection_set_scaling (conn, g_value_get_boolean (value));
+	break;
+
+      case PROP_SHARED:
+	vinagre_vnc_connection_set_shared (conn, g_value_get_int (value));
+	break;
+
+      default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	break;
+    }
+}
+
+static void
+vinagre_vnc_connection_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+  VinagreVncConnection *conn;
+
+  g_return_if_fail (VINAGRE_IS_VNC_CONNECTION (object));
+
+  conn = VINAGRE_VNC_CONNECTION (object);
+
+  switch (prop_id)
+    {
+      case PROP_DESKTOP_NAME:
+	g_value_set_string (value, conn->priv->desktop_name);
+	break;
+
+      case PROP_VIEW_ONLY:
+	g_value_set_boolean (value, conn->priv->view_only);
+	break;
+
+      case PROP_SCALING:
+	g_value_set_boolean (value, conn->priv->scaling);
+	break;
+
+      case PROP_SHARED:
+	g_value_set_int (value, conn->priv->shared);
+	break;
+
+      default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	break;
+    }
+}
+
+static void
+vnc_fill_writer (VinagreConnection *conn, xmlTextWriter *writer)
+{
+  VinagreVncConnection *vnc_conn = VINAGRE_VNC_CONNECTION (conn);
+  VINAGRE_CONNECTION_CLASS (vinagre_vnc_connection_parent_class)->impl_fill_writer (conn, writer);
+
+  xmlTextWriterWriteFormatElement (writer, "view_only", "%d", vnc_conn->priv->view_only);
+  xmlTextWriterWriteFormatElement (writer, "scaling", "%d", vnc_conn->priv->scaling);
+}
+
+static void
+vnc_parse_item (VinagreConnection *conn, xmlNode *root)
+{
+  xmlNode *curr;
+  xmlChar *s_value;
+  VinagreVncConnection *vnc_conn = VINAGRE_VNC_CONNECTION (conn);
+
+  VINAGRE_CONNECTION_CLASS (vinagre_vnc_connection_parent_class)->impl_parse_item (conn, root);
+
+  for (curr = root->children; curr; curr = curr->next)
+    {
+      s_value = xmlNodeGetContent (curr);
+
+      if (!xmlStrcmp(curr->name, (const xmlChar *)"view_only"))
+	vinagre_vnc_connection_set_view_only (vnc_conn, vinagre_utils_parse_boolean (s_value));
+      else if (!xmlStrcmp(curr->name, (const xmlChar *)"scaling"))
+	vinagre_vnc_connection_set_scaling (vnc_conn, vinagre_utils_parse_boolean (s_value));
+
+      xmlFree (s_value);
+    }
+}
+
+static gchar *
+vnc_get_best_name (VinagreConnection *conn)
+{
+  VinagreVncConnection *vnc_conn = VINAGRE_VNC_CONNECTION (conn);
+
+  if (vinagre_connection_get_name (conn))
+    return g_strdup (vinagre_connection_get_name (conn));
+
+  if (vnc_conn->priv->desktop_name)
+    return g_strdup (vnc_conn->priv->desktop_name);
+
+  if (vinagre_connection_get_host (conn))
+    return vinagre_connection_get_string_rep (conn, FALSE);
+
+  return NULL;
+}
+
+static void
+vnc_fill_conn_from_file (VinagreConnection *conn, GKeyFile *file)
+{
+  gint shared;
+  GError *e = NULL;
+
+  shared = g_key_file_get_integer (file, "options", "shared", &e);
+  if (e)
+    {
+      g_error_free (e);
+      return;
+    }
+  else
+    if (shared == 0 || shared == 1)
+      vinagre_vnc_connection_set_shared (VINAGRE_VNC_CONNECTION (conn), shared);
+    else
+      g_message (_("Bad value for 'shared' flag: %d. It is supposed to be 0 or 1. Ignoring it."), shared);
+}
+
+static void
+vinagre_vnc_connection_class_init (VinagreVncConnectionClass *klass)
+{
+  GObjectClass* object_class = G_OBJECT_CLASS (klass);
+  VinagreConnectionClass* parent_class = VINAGRE_CONNECTION_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (VinagreVncConnectionPrivate));
+
+  object_class->finalize = vinagre_vnc_connection_finalize;
+  object_class->set_property = vinagre_vnc_connection_set_property;
+  object_class->get_property = vinagre_vnc_connection_get_property;
+
+  parent_class->impl_fill_writer = vnc_fill_writer;
+  parent_class->impl_parse_item  = vnc_parse_item;
+  parent_class->impl_get_best_name = vnc_get_best_name;
+  parent_class->impl_fill_conn_from_file = vnc_fill_conn_from_file;
+
+  g_object_class_install_property (object_class,
+                                   PROP_DESKTOP_NAME,
+                                   g_param_spec_string ("desktop-name",
+                                                        "desktop-name",
+	                                                "name of this connection as reported by the server",
+                                                        NULL,
+	                                                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_VIEW_ONLY,
+                                   g_param_spec_boolean ("view-only",
+                                                        "View-only connection",
+	                                                "Whether this connection is a view-only one",
+                                                        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_SCALING,
+                                   g_param_spec_boolean ("scaling",
+                                                        "Use scaling",
+	                                                "Whether to use scaling on this connection",
+                                                        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",
+	                                              "if the server should allow more than one client connected",
+                                                      -1,
+                                                      1,
+                                                      -1,
+	                                              G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT |
+                                                      G_PARAM_STATIC_NICK |
+                                                      G_PARAM_STATIC_NAME |
+                                                      G_PARAM_STATIC_BLURB));
+
+}
+
+VinagreConnection *
+vinagre_vnc_connection_new (void)
+{
+  return VINAGRE_CONNECTION (g_object_new (VINAGRE_TYPE_VNC_CONNECTION, NULL));
+}
+
+void
+vinagre_vnc_connection_set_desktop_name (VinagreVncConnection *conn,
+					 const gchar *desktop_name)
+{
+  g_return_if_fail (VINAGRE_IS_VNC_CONNECTION (conn));
+
+  g_free (conn->priv->desktop_name);
+  conn->priv->desktop_name = g_strdup (desktop_name);
+}
+const gchar *
+vinagre_vnc_connection_get_desktop_name (VinagreVncConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_VNC_CONNECTION (conn), NULL);
+
+  return conn->priv->desktop_name;
+}
+
+void
+vinagre_vnc_connection_set_shared (VinagreVncConnection *conn,
+				   gint value)
+{
+  g_return_if_fail (VINAGRE_IS_VNC_CONNECTION (conn));
+  g_return_if_fail (value >=-1 && value <=1);
+
+  conn->priv->shared = value;
+}
+gint
+vinagre_vnc_connection_get_shared (VinagreVncConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_VNC_CONNECTION (conn), -1);
+
+  return conn->priv->shared;
+}
+
+void
+vinagre_vnc_connection_set_view_only (VinagreVncConnection *conn,
+				      gboolean value)
+{
+  g_return_if_fail (VINAGRE_IS_VNC_CONNECTION (conn));
+
+  conn->priv->view_only = value;
+}
+gboolean
+vinagre_vnc_connection_get_view_only (VinagreVncConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_VNC_CONNECTION (conn), FALSE);
+
+  return conn->priv->view_only;
+}
+
+void
+vinagre_vnc_connection_set_scaling (VinagreVncConnection *conn,
+				    gboolean value)
+{
+  g_return_if_fail (VINAGRE_IS_VNC_CONNECTION (conn));
+
+  conn->priv->scaling = value;
+}
+gboolean
+vinagre_vnc_connection_get_scaling (VinagreVncConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_VNC_CONNECTION (conn), FALSE);
+
+  return conn->priv->scaling;
+}
+
+/* vim: set ts=8: */
diff --git a/src/vinagre-vnc-connection.h b/src/vinagre-vnc-connection.h
new file mode 100644
index 0000000..16f9e7a
--- /dev/null
+++ b/src/vinagre-vnc-connection.h
@@ -0,0 +1,75 @@
+/*
+ * vinagre-vnc-connection.h
+ * Child class of abstract VinagreConnection, specific to VNC protocol
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2009 - Jonh Wendell <wendell bani com br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __VINAGRE_VNC_CONNECTION_H__
+#define __VINAGRE_VNC_CONNECTION_H__
+
+#include "vinagre-connection.h"
+
+G_BEGIN_DECLS
+
+#define VINAGRE_TYPE_VNC_CONNECTION             (vinagre_vnc_connection_get_type ())
+#define VINAGRE_VNC_CONNECTION(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), VINAGRE_TYPE_VNC_CONNECTION, VinagreVncConnection))
+#define VINAGRE_VNC_CONNECTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), VINAGRE_TYPE_VNC_CONNECTION, VinagreVncConnectionClass))
+#define VINAGRE_IS_VNC_CONNECTION(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VINAGRE_TYPE_VNC_CONNECTION))
+#define VINAGRE_IS_VNC_CONNECTION_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), VINAGRE_TYPE_VNC_CONNECTION))
+#define VINAGRE_VNC_CONNECTION_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), VINAGRE_TYPE_VNC_CONNECTION, VinagreVncConnectionClass))
+
+typedef struct _VinagreVncConnectionClass   VinagreVncConnectionClass;
+typedef struct _VinagreVncConnection        VinagreVncConnection;
+typedef struct _VinagreVncConnectionPrivate VinagreVncConnectionPrivate;
+
+struct _VinagreVncConnectionClass
+{
+  VinagreConnectionClass parent_class;
+};
+
+struct _VinagreVncConnection
+{
+  VinagreConnection parent_instance;
+  VinagreVncConnectionPrivate *priv;
+};
+
+
+GType vinagre_vnc_connection_get_type (void) G_GNUC_CONST;
+
+VinagreConnection*  vinagre_vnc_connection_new (void);
+
+const gchar*	    vinagre_vnc_connection_get_desktop_name (VinagreVncConnection *conn);
+void		    vinagre_vnc_connection_set_desktop_name (VinagreVncConnection *conn,
+							     const gchar *desktop_name);
+
+gboolean	    vinagre_vnc_connection_get_view_only    (VinagreVncConnection *conn);
+void		    vinagre_vnc_connection_set_view_only    (VinagreVncConnection *conn,
+							     gboolean value);
+
+gboolean	    vinagre_vnc_connection_get_scaling      (VinagreVncConnection *conn);
+void		    vinagre_vnc_connection_set_scaling      (VinagreVncConnection *conn,
+							     gboolean value);
+
+gint		    vinagre_vnc_connection_get_shared       (VinagreVncConnection *conn);
+void		    vinagre_vnc_connection_set_shared       (VinagreVncConnection *conn,
+							     gint value);
+
+G_END_DECLS
+
+#endif /* __VINAGRE_VNC_CONNECTION_H__  */
+/* vim: set ts=8: */
diff --git a/src/vinagre-vnc-tab.c b/src/vinagre-vnc-tab.c
new file mode 100644
index 0000000..f611980
--- /dev/null
+++ b/src/vinagre-vnc-tab.c
@@ -0,0 +1,1000 @@
+/*
+ * vinagre-vnc-tab.c
+ * VNC Implementation for VinagreVncTab widget
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2009 - Jonh Wendell <wendell bani com br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+#include <glade/glade.h>
+#include <gnome-keyring.h>
+#include <vncdisplay.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "vinagre-vnc-tab.h"
+#include "vinagre-vnc-connection.h"
+#include "vinagre-utils.h"
+#include "vinagre-prefs.h"
+
+#define VINAGRE_VNC_TAB_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), VINAGRE_TYPE_VNC_TAB, VinagreVncTabPrivate))
+
+struct _VinagreVncTabPrivate
+{
+  GtkWidget  *vnc;
+  gboolean   pointer_grab;
+  gchar      *clipboard_str;
+  GSList     *connected_actions;
+  GSList     *initialized_actions;
+  GtkWidget  *viewonly_button;
+  GtkWidget  *scaling_button;
+};
+
+G_DEFINE_TYPE (VinagreVncTab, vinagre_vnc_tab, VINAGRE_TYPE_TAB)
+
+/* Properties */
+enum
+{
+  PROP_0,
+  PROP_ORIGINAL_WIDTH,
+  PROP_ORIGINAL_HEIGHT
+};
+
+static void
+vinagre_vnc_tab_get_property (GObject    *object,
+			  guint       prop_id,
+			  GValue     *value,
+			  GParamSpec *pspec)
+{
+  VinagreVncTab *tab = VINAGRE_VNC_TAB (object);
+
+  switch (prop_id)
+    {
+      case PROP_ORIGINAL_WIDTH:
+        g_value_set_int (value, vinagre_vnc_tab_get_original_width (tab));
+	break;
+      case PROP_ORIGINAL_HEIGHT:
+        g_value_set_int (value, vinagre_vnc_tab_get_original_height (tab));
+	break;
+      default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	break;			
+    }
+}
+
+static void
+view_scaling_cb (GtkAction *action, VinagreVncTab *vnc_tab)
+{
+  vinagre_vnc_tab_set_scaling (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,
+				gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+}
+
+static void
+send_ctrlaltdel_cb (GtkAction *action, VinagreVncTab *vnc_tab)
+{
+  vinagre_vnc_tab_send_ctrlaltdel (vnc_tab);
+}
+
+static void
+view_original_size_cb (GtkAction *action, VinagreVncTab *vnc_tab)
+{
+  vinagre_vnc_tab_original_size (vnc_tab);
+}
+
+const static GSList *
+vnc_get_connected_actions (VinagreTab *tab)
+{
+  VinagreVncTab *vnc_tab = VINAGRE_VNC_TAB (tab);
+
+  return vnc_tab->priv->connected_actions;
+}
+
+const static GSList *
+vnc_get_initialized_actions (VinagreTab *tab)
+{
+  VinagreVncTab *vnc_tab = VINAGRE_VNC_TAB (tab);
+
+  return vnc_tab->priv->initialized_actions;
+}
+
+static gchar *
+vnc_tab_get_tooltip (VinagreTab *tab)
+{
+  gchar *tip;
+  VinagreVncTab *vnc_tab = VINAGRE_VNC_TAB (tab);
+  VinagreConnection *conn = vinagre_tab_get_conn (tab);
+
+  return  g_markup_printf_escaped (
+				  "<b>%s</b> %s\n\n"
+				  "<b>%s</b> %s\n"
+				  "<b>%s</b> %d\n"
+				  "<b>%s</b> %dx%d",
+				  _("Desktop Name:"), vnc_display_get_name (VNC_DISPLAY (vnc_tab->priv->vnc)),
+				  _("Host:"), vinagre_connection_get_host (conn),
+				  _("Port:"), vinagre_connection_get_port (conn),
+				  _("Dimensions:"), vnc_display_get_width (VNC_DISPLAY (vnc_tab->priv->vnc)), vnc_display_get_height (VNC_DISPLAY (vnc_tab->priv->vnc)));
+}
+
+static GdkPixbuf *
+vnc_tab_get_screenshot (VinagreTab *tab)
+{
+  VinagreVncTab *vnc_tab = VINAGRE_VNC_TAB (tab);
+
+  return vnc_display_get_pixbuf (VNC_DISPLAY (vnc_tab->priv->vnc));
+}
+
+static void
+vinagre_vnc_tab_finalize (GObject *object)
+{
+  VinagreVncTab *vnc_tab = VINAGRE_VNC_TAB (object);
+
+  g_free (vnc_tab->priv->clipboard_str);
+
+  G_OBJECT_CLASS (vinagre_vnc_tab_parent_class)->finalize (object);
+}
+
+static void
+vinagre_vnc_tab_dispose (GObject *object)
+{
+  VinagreVncTab *vnc_tab = VINAGRE_VNC_TAB (object);
+
+  if (vnc_tab->priv->connected_actions)
+    {
+      vinagre_tab_free_actions (vnc_tab->priv->connected_actions);
+      vnc_tab->priv->connected_actions = NULL;
+    }
+
+  if (vnc_tab->priv->initialized_actions)
+    {
+      vinagre_tab_free_actions (vnc_tab->priv->initialized_actions);
+      vnc_tab->priv->initialized_actions = NULL;
+    }
+
+  G_OBJECT_CLASS (vinagre_vnc_tab_parent_class)->dispose (object);
+}
+
+static void 
+vinagre_vnc_tab_class_init (VinagreVncTabClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  VinagreTabClass* tab_class = VINAGRE_TAB_CLASS (klass);
+
+  object_class->finalize = vinagre_vnc_tab_finalize;
+  object_class->dispose = vinagre_vnc_tab_dispose;
+  object_class->get_property = vinagre_vnc_tab_get_property;
+
+  tab_class->impl_get_tooltip = vnc_tab_get_tooltip;
+  tab_class->impl_get_connected_actions = vnc_get_connected_actions;
+  tab_class->impl_get_initialized_actions = vnc_get_initialized_actions;
+  tab_class->impl_get_screenshot = vnc_tab_get_screenshot;
+
+  g_object_class_install_property (object_class,
+				   PROP_ORIGINAL_WIDTH,
+				   g_param_spec_int ("original-width",
+						     "Original width",
+						     "The original width of the remote screen",
+						     -1, G_MAXINT, 0,
+						      G_PARAM_READABLE |
+						      G_PARAM_STATIC_NAME |
+						      G_PARAM_STATIC_NICK |
+						      G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
+				   PROP_ORIGINAL_HEIGHT,
+				   g_param_spec_int ("original-height",
+						     "Original height",
+						     "The original height of the remote screen",
+						     -1, G_MAXINT, 0,
+						      G_PARAM_READABLE |
+						      G_PARAM_STATIC_NAME |
+						      G_PARAM_STATIC_NICK |
+						      G_PARAM_STATIC_BLURB));
+
+  g_type_class_add_private (object_class, sizeof (VinagreVncTabPrivate));
+}
+
+static void
+open_vnc (VinagreVncTab *vnc_tab)
+{
+  gchar      *host, *port_str;
+  gint       port, shared;
+  gboolean   scaling;
+  VncDisplay *vnc = VNC_DISPLAY (vnc_tab->priv->vnc);
+  VinagreTab *tab = VINAGRE_TAB (vnc_tab);
+
+  g_object_get (vinagre_tab_get_conn (tab),
+		"port", &port,
+		"host", &host,
+		"scaling", &scaling,
+		"shared", &shared,
+		NULL);
+
+  port_str = g_strdup_printf ("%d", port);
+  if (shared == -1)
+    g_object_get (vinagre_prefs_get_default (),
+		  "shared-flag", &shared,
+		  NULL);
+
+  vnc_display_set_shared_flag (vnc, shared);
+  vnc_display_set_force_size (vnc, !scaling);
+
+  if (vnc_display_open_host (vnc, host, port_str))
+    gtk_widget_grab_focus (GTK_WIDGET (vnc));
+  else
+    vinagre_utils_show_error (NULL,
+			      _("Error connecting to host."),
+			      GTK_WINDOW (vinagre_tab_get_window (tab)));
+
+  g_free (port_str);
+  g_free (host);
+}
+
+static void
+vnc_connected_cb (VncDisplay *vnc, VinagreVncTab *tab)
+{
+  g_signal_emit_by_name (G_OBJECT (tab), "tab-connected");
+}
+
+static void
+vnc_disconnected_cb (VncDisplay *vnc, VinagreVncTab *tab)
+{
+  g_signal_emit_by_name (G_OBJECT (tab), "tab-disconnected");
+}
+
+static void
+vnc_auth_failed_cb (VncDisplay *vnc, const gchar *msg, VinagreVncTab *vnc_tab)
+{
+  g_signal_emit_by_name (vnc_tab, "tab-auth-failed", msg);
+}
+
+static void
+vnc_auth_unsupported_cb (VncDisplay *vnc, guint auth_type, VinagreVncTab *vnc_tab)
+{
+  GString *message;
+  gchar   *name;
+  VinagreTab *tab = VINAGRE_TAB (vnc_tab);
+
+  message = g_string_new (NULL);
+  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (tab));
+
+  g_string_printf (message, _("Authentication method to host <i>%s</i> is unsupported. (%u)"),
+		   name,
+		   auth_type);
+
+  vinagre_utils_show_error (_("Authentication unsupported"),
+			    message->str,
+			    GTK_WINDOW (vinagre_tab_get_window (tab)));
+  g_string_free (message, TRUE);
+  g_free (name);
+
+  vinagre_tab_remove_from_notebook (tab);
+}
+
+/* text was actually requested */
+static void
+copy_cb (GtkClipboard     *clipboard,
+         GtkSelectionData *data,
+	 guint             info,
+	 VinagreVncTab    *vnc_tab)
+{
+  gtk_selection_data_set_text (data, vnc_tab->priv->clipboard_str, -1);
+}
+
+static void
+vnc_server_cut_text_cb (VncDisplay *vnc, const gchar *text, VinagreVncTab *vnc_tab)
+{
+  GtkClipboard *cb;
+  gsize a, b;
+  GtkTargetEntry targets[] = {
+				{"UTF8_STRING", 0, 0},
+				{"COMPOUND_TEXT", 0, 0},
+				{"TEXT", 0, 0},
+				{"STRING", 0, 0},
+			     };
+
+  if (!text)
+    return;
+
+  g_free (vnc_tab->priv->clipboard_str);
+  vnc_tab->priv->clipboard_str = g_convert (text, -1, "utf-8", "iso8859-1", &a, &b, NULL);
+
+  if (vnc_tab->priv->clipboard_str)
+    {
+      cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+      gtk_clipboard_set_with_owner (cb,
+				    targets,
+				    G_N_ELEMENTS(targets),
+				    (GtkClipboardGetFunc) copy_cb,
+				    NULL,
+				    G_OBJECT (vnc_tab));
+    }
+}
+
+static void
+vnc_initialized_cb (VncDisplay *vnc, VinagreVncTab *vnc_tab)
+{
+  GtkLabel *label;
+  gchar    *name;
+  gboolean scaling, view_only, fullscreen;
+  VinagreTab *tab = VINAGRE_TAB (vnc_tab);
+  VinagreConnection *conn = vinagre_tab_get_conn (tab);
+  VinagreWindow *window = vinagre_tab_get_window (tab);
+
+  g_object_get (conn,
+		"view-only", &view_only,
+		"scaling", &scaling,
+		"fullscreen", &fullscreen,
+		NULL);
+
+  vinagre_vnc_tab_set_scaling (vnc_tab, scaling);
+  vinagre_vnc_tab_set_viewonly (vnc_tab, view_only);
+  vnc_display_set_pointer_local (VNC_DISPLAY(vnc_tab->priv->vnc), TRUE);
+  vnc_display_set_keyboard_grab (VNC_DISPLAY(vnc_tab->priv->vnc), TRUE);
+  vnc_display_set_pointer_grab (VNC_DISPLAY(vnc_tab->priv->vnc), TRUE);
+
+  if (fullscreen)
+    vinagre_window_toggle_fullscreen (window);
+
+  vinagre_vnc_connection_set_desktop_name (VINAGRE_VNC_CONNECTION (conn),
+					   vnc_display_get_name (VNC_DISPLAY (vnc_tab->priv->vnc)));
+
+  name = vinagre_connection_get_best_name (conn);
+  label = g_object_get_data (G_OBJECT (tab), "label");
+  g_return_if_fail (label != NULL);
+  gtk_label_set_label (label, name);
+  g_free (name);
+
+  vinagre_tab_save_credentials_in_keyring (tab);
+  vinagre_tab_add_recent_used (tab);
+  vinagre_tab_set_state (tab, VINAGRE_TAB_STATE_CONNECTED);
+
+  g_signal_emit_by_name (G_OBJECT (tab), "tab-initialized");
+}
+
+typedef struct {
+  GtkWidget *uname, *pw, *button;
+} ControlOKButton;
+
+static void
+control_ok_button (GtkEditable *entry, ControlOKButton *data)
+{
+  gboolean enabled = TRUE;
+
+  if (GTK_WIDGET_VISIBLE (data->uname))
+    enabled = enabled && gtk_entry_get_text_length (GTK_ENTRY (data->uname)) > 0;
+
+  if (GTK_WIDGET_VISIBLE (data->pw))
+    enabled = enabled && gtk_entry_get_text_length (GTK_ENTRY (data->pw)) > 0;
+
+  gtk_widget_set_sensitive (data->button, enabled);
+}
+
+static gboolean
+ask_credential (VinagreVncTab *vnc_tab,
+		gboolean      need_username,
+		gboolean      need_password,
+		gchar         **username,
+		gchar         **password)
+{
+  GladeXML        *xml;
+  const char      *glade_file;
+  GtkWidget       *password_dialog, *host_label, *save_credential_check;
+  GtkWidget       *password_label, *username_label, *image;
+  gchar           *name, *label;
+  int             result;
+  ControlOKButton control;
+  VinagreTab      *tab = VINAGRE_TAB (vnc_tab);
+  VinagreConnection *conn = vinagre_tab_get_conn (tab);
+
+  glade_file = vinagre_utils_get_glade_filename ();
+  xml = glade_xml_new (glade_file, NULL, NULL);
+
+  password_dialog = glade_xml_get_widget (xml, "auth_required_dialog");
+  gtk_window_set_transient_for (GTK_WINDOW(password_dialog),
+				GTK_WINDOW(vinagre_tab_get_window (tab)));
+
+  host_label = glade_xml_get_widget (xml, "host_label");
+  name = vinagre_connection_get_best_name (conn);
+  label = g_strdup_printf ("<i>%s</i>", name);
+  gtk_label_set_markup (GTK_LABEL (host_label), label);
+  g_free (name);
+  g_free (label);
+
+  control.uname  = glade_xml_get_widget (xml, "username_entry");
+  control.pw     = glade_xml_get_widget (xml, "password_entry");
+  control.button = glade_xml_get_widget (xml, "ok_button");
+  password_label = glade_xml_get_widget (xml, "password_label");
+  username_label = glade_xml_get_widget (xml, "username_label");
+  save_credential_check = glade_xml_get_widget (xml, "save_credential_check");
+
+  image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_BUTTON);
+  gtk_button_set_image (GTK_BUTTON (control.button), image);
+
+  g_signal_connect (control.uname, "changed", G_CALLBACK (control_ok_button), &control);
+  g_signal_connect (control.pw, "changed", G_CALLBACK (control_ok_button), &control);
+
+  if (need_username)
+    {
+      if (*username)
+        gtk_entry_set_text (GTK_ENTRY (control.uname), *username);
+    }
+  else
+    {
+      gtk_widget_hide (username_label);
+      gtk_widget_hide (control.uname);
+    }
+
+  if (need_password)
+    {
+      if (*password)
+        gtk_entry_set_text (GTK_ENTRY (control.pw), *password);
+    }
+  else
+    {
+      gtk_widget_hide (password_label);
+      gtk_widget_hide (control.pw);
+    }
+
+  result = gtk_dialog_run (GTK_DIALOG (password_dialog));
+  if (result == -5)
+    {
+      g_free (*username);
+      if (gtk_entry_get_text_length (GTK_ENTRY (control.uname)) > 0)
+	*username = g_strdup (gtk_entry_get_text (GTK_ENTRY (control.uname)));
+      else
+	*username = NULL;
+
+      g_free (*password);
+      if (gtk_entry_get_text_length (GTK_ENTRY (control.pw)) > 0)
+	*password = g_strdup (gtk_entry_get_text (GTK_ENTRY (control.pw)));
+      else
+	*password = NULL;
+
+      //tab->priv->save_credential = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (save_credential_check));
+    }
+
+  gtk_widget_destroy (GTK_WIDGET (password_dialog));
+  g_object_unref (xml);
+
+  return result == -5;
+}
+
+static void
+vnc_authentication_cb (VncDisplay *vnc, GValueArray *credList, VinagreVncTab *vnc_tab)
+{
+  gchar *username, *password;
+  gboolean need_password, need_username;
+  int i;
+  VinagreTab *tab = VINAGRE_TAB (vnc_tab);
+  VinagreConnection *conn = vinagre_tab_get_conn (tab);
+  VinagreWindow *window = vinagre_tab_get_window (tab);
+
+  if (credList == NULL)
+    return;
+
+  need_password = FALSE;
+  need_username = FALSE;
+  username = NULL;
+  password = NULL;
+
+  for (i = 0; i < credList->n_values; i++) {
+    switch (g_value_get_enum (&credList->values[i]))
+      {
+	case VNC_DISPLAY_CREDENTIAL_USERNAME:
+	  if (vinagre_connection_get_username (conn))
+	    {
+	      vnc_display_set_credential (vnc, VNC_DISPLAY_CREDENTIAL_USERNAME, vinagre_connection_get_username (conn));
+	      break;
+	    }
+	  need_username= TRUE;
+	  break;
+
+	case VNC_DISPLAY_CREDENTIAL_PASSWORD:
+	  if (vinagre_connection_get_password (conn))
+	    {
+	      vnc_display_set_credential (vnc, VNC_DISPLAY_CREDENTIAL_PASSWORD, vinagre_connection_get_password (conn));
+	      break;
+	    }
+	  need_password = TRUE;
+	  break;
+
+        case VNC_DISPLAY_CREDENTIAL_CLIENTNAME:
+          vnc_display_set_credential (vnc, VNC_DISPLAY_CREDENTIAL_CLIENTNAME, "vinagre");
+          break;
+      }
+  }
+
+  if (need_password || need_username)
+    {
+      vinagre_tab_find_credentials_in_keyring (tab, &username, &password);
+      if ( (need_username && !username) || (need_password && !password) )
+	{
+	  if (!ask_credential (vnc_tab, need_username, need_password, &username, &password))
+	    {
+	      vinagre_tab_remove_from_notebook (tab);
+	      goto out;
+	    }
+	}
+
+      if (need_username)
+	{
+	  if (username)
+	    {
+	      vinagre_connection_set_username (conn, username);
+	      vnc_display_set_credential (vnc, VNC_DISPLAY_CREDENTIAL_USERNAME, username);
+	    }
+	  else
+	    {
+	      vinagre_tab_remove_from_notebook (tab);
+	      vinagre_utils_show_error (_("Authentication error"),
+					_("A username is required in order to access this machine."),
+					GTK_WINDOW (window));
+	      goto out;
+	    }
+	}
+
+      if (need_password)
+	{
+	  if (password)
+	    {
+	      vinagre_connection_set_password (conn, password);
+	      vnc_display_set_credential (vnc, VNC_DISPLAY_CREDENTIAL_PASSWORD, password);
+	    }
+	  else
+	    {
+	      vinagre_tab_remove_from_notebook (tab);
+	      vinagre_utils_show_error (_("Authentication error"),
+					_("A password is required in order to access this machine."),
+					GTK_WINDOW (window));
+	      goto out;
+	    }
+	}
+
+out:
+      g_free (username);
+      g_free (password);
+    }
+}
+
+static void
+vnc_pointer_grab_cb (VncDisplay *vnc, VinagreVncTab *vnc_tab)
+{
+  vnc_tab->priv->pointer_grab = TRUE;
+}
+
+static void
+vnc_pointer_ungrab_cb (VncDisplay *vnc, VinagreVncTab *vnc_tab)
+{
+  vnc_tab->priv->pointer_grab = FALSE;
+}
+
+static void
+vnc_bell_cb (VncDisplay *vnc, VinagreVncTab *vnc_tab)
+{
+  gdk_window_beep (GTK_WIDGET (vnc_tab)->window);
+}
+
+static void
+vnc_desktop_resize_cb (VncDisplay *vnc, int x, int y, VinagreVncTab *tab)
+{
+  g_object_notify (G_OBJECT (tab), "original-width");
+  g_object_notify (G_OBJECT (tab), "original-height");
+}
+
+static GSList *
+create_connected_actions (VinagreVncTab *tab)
+{
+  GSList *list = NULL;
+  VinagreTabUiAction *a;
+
+  /* View->Scaling */
+  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 ("VNCViewScaling",
+						 _("S_caling"),
+						 _("Fits the remote screen into the current window size"),
+						 NULL));
+  g_signal_connect (a->action, "activate", G_CALLBACK (view_scaling_cb), tab);
+  list = g_slist_append (list, a);
+
+  /* View->View Only */
+  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 ("VNCViewViewOnly",
+						 _("_View only"),
+						 _("Does not send mouse and keyboard events"),
+						 NULL));
+  g_signal_connect (a->action, "activate", G_CALLBACK (view_viewonly_cb), tab);
+  list = g_slist_append (list, a);
+
+  /* View->Original Size */
+  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_new ("VNCViewOriginalSize",
+			      _("_Original size"),
+			      _("Adjusts the window to the remote desktop's size"),
+			      "zoom-original");
+  gtk_action_set_icon_name (a->action, "zoom-original");
+  g_signal_connect (a->action, "activate", G_CALLBACK (view_original_size_cb), tab);
+  list = g_slist_append (list, a);
+
+  return list;
+}
+
+static GSList *
+create_initialized_actions (VinagreVncTab *tab)
+{
+  GSList *list = NULL;
+  VinagreTabUiAction *a;
+
+  /* Machine->Send CTRL-ALT-DEL */
+  a = g_new (VinagreTabUiAction, 1);
+  a->paths = g_new (gchar *, 3);
+  a->paths[0] = g_strdup ("/MenuBar/MachineMenu/MachineOps_1");
+  a->paths[1] = g_strdup ("/ToolBar");
+  a->paths[2] = NULL;
+  a->action = gtk_action_new ("VNCMachineSendCtrlAltDel",
+			      _("Send Ctrl-Alt-Del"),
+			      _("Sends Ctrl+Alt+Del to the remote machine"),
+			      "preferences-desktop-keyboard-shortcuts");
+  gtk_action_set_is_important (a->action, TRUE);
+  gtk_action_set_icon_name (a->action, "preferences-desktop-keyboard-shortcuts");
+  g_signal_connect (a->action, "activate", G_CALLBACK (send_ctrlaltdel_cb), tab);
+  list = g_slist_append (list, a);
+
+  return list;
+}
+
+static void
+viewonly_button_clicked (GtkToggleToolButton *button,
+			 VinagreVncTab       *vnc_tab)
+{
+  GtkAction *action;
+
+  vinagre_vnc_tab_set_viewonly (vnc_tab, gtk_toggle_tool_button_get_active (button));
+
+  action = gtk_action_group_get_action (vinagre_window_get_connected_action (vinagre_tab_get_window (VINAGRE_TAB (vnc_tab))),
+					"VNCViewReadOnly");
+  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+				vinagre_vnc_tab_get_viewonly (vnc_tab));
+}
+
+static void
+scaling_button_clicked (GtkToggleToolButton *button,
+			VinagreVncTab       *vnc_tab)
+{
+  GtkAction *action;
+
+  if (!vinagre_vnc_tab_set_scaling (vnc_tab, gtk_toggle_tool_button_get_active (button)))
+    gtk_toggle_tool_button_set_active (button, FALSE);
+
+  action = gtk_action_group_get_action (vinagre_window_get_connected_action (vinagre_tab_get_window (VINAGRE_TAB (vnc_tab))),
+					"VNCViewScaling");
+  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+				vinagre_vnc_tab_get_scaling (vnc_tab));
+}
+
+static void
+cad_button_clicked (GtkToolButton *button,
+		    VinagreVncTab *vnc_tab)
+{
+  vinagre_vnc_tab_send_ctrlaltdel (vnc_tab);
+}
+
+static void
+setup_toolbar (VinagreVncTab *vnc_tab)
+{
+  GtkWidget *toolbar = vinagre_tab_get_toolbar (VINAGRE_TAB (vnc_tab));
+  GtkWidget *button;
+
+  /* Scaling */
+  button = GTK_WIDGET (gtk_toggle_tool_button_new ());
+  gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), _("Scaling"));
+  gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (button), _("Scaling"));
+  gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), "zoom-fit-best");
+  gtk_widget_show (GTK_WIDGET (button));
+  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (button), 0);
+  g_signal_connect (button, "toggled", G_CALLBACK (scaling_button_clicked), vnc_tab);
+  vnc_tab->priv->scaling_button = button;
+
+  /* Read only */
+  button = GTK_WIDGET (gtk_toggle_tool_button_new ());
+  gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), _("Read only"));
+  gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (button), _("Read only"));
+  gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), "emblem-readonly");
+  gtk_widget_show (GTK_WIDGET (button));
+  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (button), 0);
+  g_signal_connect (button, "toggled", G_CALLBACK (viewonly_button_clicked), vnc_tab);
+  vnc_tab->priv->viewonly_button = button;
+
+  /* Send Ctrl-alt-del */
+  button = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
+  gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), "preferences-desktop-keyboard-shortcuts");
+  gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), _("Send Ctrl-Alt-Del"));
+  gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (button), _("Send Ctrl-Alt-Del"));
+  g_signal_connect (button, "clicked", G_CALLBACK (cad_button_clicked), vnc_tab);
+  gtk_widget_show (GTK_WIDGET (button));
+  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (button), 0);
+}
+
+static void
+vinagre_vnc_tab_init (VinagreVncTab *vnc_tab)
+{
+  GtkAction *action;
+
+  vnc_tab->priv = VINAGRE_VNC_TAB_GET_PRIVATE (vnc_tab);
+  vnc_tab->priv->clipboard_str = NULL;
+  vnc_tab->priv->connected_actions = create_connected_actions (vnc_tab);
+  vnc_tab->priv->initialized_actions = create_initialized_actions (vnc_tab);
+
+  /* Create the vnc widget */
+  vnc_tab->priv->vnc = vnc_display_new ();
+  vinagre_tab_add_view (VINAGRE_TAB (vnc_tab), vnc_tab->priv->vnc);
+
+  setup_toolbar (vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-connected",
+		    G_CALLBACK (vnc_connected_cb),
+		    vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-initialized",
+		    G_CALLBACK (vnc_initialized_cb),
+		    vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-disconnected",
+		    G_CALLBACK (vnc_disconnected_cb),
+		    vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-auth-credential",
+		    G_CALLBACK (vnc_authentication_cb),
+		    vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-pointer-grab",
+		    G_CALLBACK (vnc_pointer_grab_cb),
+		    vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-pointer-ungrab",
+		    G_CALLBACK (vnc_pointer_ungrab_cb),
+		    vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-auth-failure",
+		    G_CALLBACK (vnc_auth_failed_cb),
+		    vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-auth-unsupported",
+		    G_CALLBACK (vnc_auth_unsupported_cb),
+		    vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-server-cut-text",
+		    G_CALLBACK (vnc_server_cut_text_cb),
+		    vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-bell",
+		    G_CALLBACK (vnc_bell_cb),
+		    vnc_tab);
+
+  g_signal_connect (vnc_tab->priv->vnc,
+		    "vnc-desktop-resize",
+		    G_CALLBACK (vnc_desktop_resize_cb),
+		    vnc_tab);
+
+  gtk_widget_show_all (GTK_WIDGET (vnc_tab));
+}
+
+GtkWidget *
+vinagre_vnc_tab_new (VinagreConnection *conn, VinagreWindow *window)
+{
+  VinagreVncTab *tab = g_object_new (VINAGRE_TYPE_VNC_TAB, 
+				     "conn", conn,
+				     "window", window,
+				     NULL);
+  open_vnc (tab);
+  return GTK_WIDGET (tab);
+}
+
+
+void
+vinagre_vnc_tab_send_ctrlaltdel (VinagreVncTab *tab)
+{
+  guint keys[] = { GDK_Control_L, GDK_Alt_L, GDK_Delete };
+
+  g_return_if_fail (VINAGRE_IS_VNC_TAB (tab));
+
+  vnc_display_send_keys_ex (VNC_DISPLAY (tab->priv->vnc), keys, sizeof (keys) / sizeof (keys[0]), VNC_DISPLAY_KEY_EVENT_CLICK);
+}
+
+void
+vinagre_vnc_tab_paste_text (VinagreVncTab *tab, const gchar *text)
+{
+  gchar *out;
+  size_t a, b;
+  g_return_if_fail (VINAGRE_IS_VNC_TAB (tab));
+
+  out = g_convert (text, -1, "iso8859-1", "utf-8", &a, &b, NULL);
+
+  if (out)
+    {
+      vnc_display_client_cut_text (VNC_DISPLAY (tab->priv->vnc), out);
+      g_free (out);
+    }
+}
+
+gboolean
+vinagre_vnc_tab_set_scaling (VinagreVncTab *tab, gboolean active) {
+  g_return_val_if_fail (VINAGRE_IS_VNC_TAB (tab), FALSE);
+
+  if (vnc_display_get_scaling (VNC_DISPLAY (tab->priv->vnc)) == active)
+    return TRUE;
+
+  vnc_display_set_force_size (VNC_DISPLAY(tab->priv->vnc), !active);
+  if (!vnc_display_set_scaling (VNC_DISPLAY (tab->priv->vnc), active))
+    {
+      vinagre_utils_show_error (NULL, _("Scaling is not supported on this installation.\n\nRead the README file (shipped with Vinagre) in order to know how to enable this feature."),
+				GTK_WINDOW (vinagre_tab_get_window (VINAGRE_TAB (tab))));
+      return FALSE;
+    }
+
+  gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (tab->priv->scaling_button),
+				     active);
+
+  if (active)
+    gtk_widget_set_size_request (tab->priv->vnc, 0, 0);
+  else
+    gtk_widget_set_size_request (tab->priv->vnc,
+				 vnc_display_get_width (VNC_DISPLAY (tab->priv->vnc)),
+				 vnc_display_get_height (VNC_DISPLAY (tab->priv->vnc)));
+
+  return TRUE;
+}
+
+gboolean
+vinagre_vnc_tab_get_scaling (VinagreVncTab *tab) {
+  g_return_val_if_fail (VINAGRE_IS_VNC_TAB (tab), FALSE);
+
+  return vnc_display_get_scaling (VNC_DISPLAY (tab->priv->vnc));
+}
+
+void
+vinagre_vnc_tab_set_viewonly (VinagreVncTab *tab, gboolean active) {
+  g_return_if_fail (VINAGRE_IS_VNC_TAB (tab));
+
+  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
+vinagre_vnc_tab_get_viewonly (VinagreVncTab *tab) {
+  g_return_val_if_fail (VINAGRE_IS_VNC_TAB (tab), FALSE);
+
+  return vnc_display_get_read_only (VNC_DISPLAY (tab->priv->vnc));
+}
+
+gboolean
+vinagre_vnc_tab_is_pointer_grab (VinagreVncTab *tab)
+{
+  g_return_val_if_fail (VINAGRE_IS_VNC_TAB (tab), FALSE);
+
+  return tab->priv->pointer_grab;
+}
+
+gint
+vinagre_vnc_tab_get_original_height (VinagreVncTab *tab)
+{
+  g_return_val_if_fail (VINAGRE_IS_VNC_TAB (tab), -1);
+
+  if (VNC_IS_DISPLAY (tab->priv->vnc))
+    return vnc_display_get_height (VNC_DISPLAY (tab->priv->vnc));
+  else
+    return -1;
+}
+
+gint
+vinagre_vnc_tab_get_original_width (VinagreVncTab *tab)
+{
+  g_return_val_if_fail (VINAGRE_IS_VNC_TAB (tab), -1);
+
+  if (VNC_IS_DISPLAY (tab->priv->vnc))
+    return vnc_display_get_width (VNC_DISPLAY (tab->priv->vnc));
+  else
+    return -1;
+}
+
+
+typedef struct _VinagrePrefSize {
+  gint width, height;
+  gulong sig_id;
+} VinagrePrefSize;
+
+static gboolean
+cb_unset_size (gpointer data)
+{
+  GtkWidget *widget = data;
+
+  gtk_widget_queue_resize_no_redraw (widget);
+
+  return FALSE;
+}
+
+static void
+cb_set_preferred_size (GtkWidget *widget, GtkRequisition *req,
+		       gpointer data)
+{
+  VinagrePrefSize *size = data;
+
+  req->width = size->width;
+  req->height = size->height;
+
+  g_signal_handler_disconnect (widget, size->sig_id);
+  g_free (size);
+  g_idle_add (cb_unset_size, widget);
+}
+
+void
+vinagre_widget_set_preferred_size (GtkWidget *widget, gint width,
+				 gint height)
+{
+  VinagrePrefSize *size = g_new (VinagrePrefSize, 1);
+
+  size->width = width;
+  size->height = height;
+  size->sig_id = g_signal_connect (widget, "size-request",
+				   G_CALLBACK (cb_set_preferred_size),
+				   size);
+
+  gtk_widget_queue_resize (widget);
+}
+
+void
+vinagre_vnc_tab_original_size (VinagreVncTab *tab)
+{
+/*
+  g_return_if_fail (VINAGRE_IS_VNC_TAB (tab));
+
+  gtk_window_unmaximize (GTK_WINDOW (tab->priv->window));
+  gtk_window_resize (GTK_WINDOW (tab->priv->window), 1, 1);
+  vinagre_widget_set_preferred_size (GTK_WIDGET (tab),
+				     vinagre_vnc_tab_get_original_width (tab),
+				     vinagre_vnc_tab_get_original_height (tab));
+*/
+}
+
+/* vim: set ts=8: */
diff --git a/src/vinagre-vnc-tab.h b/src/vinagre-vnc-tab.h
new file mode 100644
index 0000000..9c83488
--- /dev/null
+++ b/src/vinagre-vnc-tab.h
@@ -0,0 +1,75 @@
+/*
+ * vinagre-vnc-tab.h
+ * VNC Tab
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2009 - Jonh Wendell <wendell bani com br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __VINAGRE_VNC_TAB_H__
+#define __VINAGRE_VNC_TAB_H__
+
+#include "vinagre-tab.h"
+
+G_BEGIN_DECLS
+
+#define VINAGRE_TYPE_VNC_TAB              (vinagre_vnc_tab_get_type())
+#define VINAGRE_VNC_TAB(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), VINAGRE_TYPE_VNC_TAB, VinagreVncTab))
+#define VINAGRE_VNC_TAB_CONST(obj)        (G_TYPE_CHECK_INSTANCE_CAST((obj), VINAGRE_TYPE_VNC_TAB, VinagreVncTab const))
+#define VINAGRE_VNC_TAB_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), VINAGRE_TYPE_VNC_TAB, VinagreVncTabClass))
+#define VINAGRE_IS_VNC_TAB(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), VINAGRE_TYPE_VNC_TAB))
+#define VINAGRE_IS_VNC_TAB_CLASS(klass)...(G_TYPE_CHECK_CLASS_TYPE ((klass), VINAGRE_TYPE_VNC_TAB))
+#define VINAGRE_VNC_TAB_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), VINAGRE_TYPE_VNC_TAB, VinagreVncTabClass))
+
+typedef struct _VinagreVncTabPrivate VinagreVncTabPrivate;
+typedef struct _VinagreVncTab        VinagreVncTab;
+typedef struct _VinagreVncTabClass   VinagreVncTabClass;
+
+
+struct _VinagreVncTab 
+{
+  VinagreTab tab;
+  VinagreVncTabPrivate *priv;
+};
+
+struct _VinagreVncTabClass 
+{
+  VinagreTabClass parent_class;
+};
+
+GType		vinagre_vnc_tab_get_type		(void) G_GNUC_CONST;
+
+GtkWidget *	vinagre_vnc_tab_new 			(VinagreConnection *conn,
+							 VinagreWindow     *window);
+
+void		vinagre_vnc_tab_send_ctrlaltdel		(VinagreVncTab *tab);
+void		vinagre_vnc_tab_paste_text		(VinagreVncTab *tab,
+							 const gchar   *text);
+
+gboolean	vinagre_vnc_tab_set_scaling		(VinagreVncTab *tab, gboolean active);
+gboolean	vinagre_vnc_tab_get_scaling		(VinagreVncTab *tab);
+void		vinagre_vnc_tab_set_viewonly		(VinagreVncTab *tab, gboolean active);
+gboolean	vinagre_vnc_tab_get_viewonly		(VinagreVncTab *tab);
+
+gint		vinagre_vnc_tab_get_original_width	(VinagreVncTab *tab);
+gint		vinagre_vnc_tab_get_original_height	(VinagreVncTab *tab);
+void		vinagre_vnc_tab_original_size		(VinagreVncTab *tab);
+
+gboolean	vinagre_vnc_tab_is_pointer_grab		(VinagreVncTab *tab);
+G_END_DECLS
+
+#endif  /* __VINAGRE_VNC_TAB_H__  */
+/* vim: set ts=8: */
diff --git a/src/vinagre-window-private.h b/src/vinagre-window-private.h
index cfae73a..aaa2ed5 100644
--- a/src/vinagre-window-private.h
+++ b/src/vinagre-window-private.h
@@ -23,6 +23,7 @@
 
 #include "vinagre-window.h"
 #include "vinagre-bookmarks-entry.h"
+#include "vinagre-notebook.h"
 
 G_BEGIN_DECLS
 
@@ -30,7 +31,7 @@ G_BEGIN_DECLS
 
 struct _VinagreWindowPrivate
 {
-  GtkWidget       *notebook;
+  VinagreNotebook *notebook;
   GtkWidget       *fav_panel;
   GtkWidget       *statusbar;	
   guint           generic_message_cid;
@@ -40,9 +41,11 @@ struct _VinagreWindowPrivate
 
   /* Menus & Toolbars */
   GtkUIManager   *manager;
-  GtkActionGroup *action_group;
+
   GtkActionGroup *always_sensitive_action_group;
   GtkActionGroup *machine_connected_action_group;
+  GtkActionGroup *machine_initialized_action_group;
+
   GtkActionGroup *bookmarks_list_action_group;
   GtkActionGroup *recent_action_group;
   GtkAction      *recent_action;
@@ -53,7 +56,6 @@ struct _VinagreWindowPrivate
   GtkWidget       *toolbar;
   GtkWidget       *menubar;
 
-  GtkWidget       *active_tab;
   VinagreBookmarksEntry *fav_entry_selected;
 	
   gint            width;
@@ -66,7 +68,6 @@ struct _VinagreWindowPrivate
   gboolean        statusbar_visible;
   gboolean        fav_panel_visible;
 
-  gulong	  signal_notebook;
   gulong	  signal_clipboard;
 };
 
diff --git a/src/vinagre-window.c b/src/vinagre-window.c
index 85d940e..f880718 100644
--- a/src/vinagre-window.c
+++ b/src/vinagre-window.c
@@ -2,7 +2,7 @@
  * vinagre-window.c
  * This file is part of vinagre
  *
- * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -66,16 +66,9 @@ vinagre_window_dispose (GObject *object)
       window->priv->manager = NULL;
     }
 
-  if (window->priv->signal_notebook != 0)
-    {
-      g_signal_handler_disconnect (window->priv->notebook,
-				   window->priv->signal_notebook);
-      window->priv->signal_notebook = 0;
-    }
-
   if (window->priv->signal_clipboard != 0)
     {
-      GtkClipboard  *cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);;
+      GtkClipboard  *cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
 
       g_signal_handler_disconnect (cb,
 				   window->priv->signal_clipboard);
@@ -350,16 +343,17 @@ create_menu_bar_and_toolbar (VinagreWindow *window,
   gtk_window_add_accel_group (GTK_WINDOW (window),
 			      gtk_ui_manager_get_accel_group (manager));
 
+  /* Normal actions */
   action_group = gtk_action_group_new ("VinagreWindowAlwaysSensitiveActions");
   gtk_action_group_set_translation_domain (action_group, NULL);
   gtk_action_group_add_actions (action_group,
-				vinagre_always_sensitive_menu_entries,
-				G_N_ELEMENTS (vinagre_always_sensitive_menu_entries),
+				vinagre_always_sensitive_entries,
+				G_N_ELEMENTS (vinagre_always_sensitive_entries),
 				window);
   
   gtk_action_group_add_toggle_actions (action_group,
-				       vinagre_always_sensitive_toggle_menu_entries,
-				       G_N_ELEMENTS (vinagre_always_sensitive_toggle_menu_entries),
+				       vinagre_always_sensitive_toggle_entries,
+				       G_N_ELEMENTS (vinagre_always_sensitive_toggle_entries),
 				       window);
 
   gtk_ui_manager_insert_action_group (manager, action_group, 0);
@@ -369,42 +363,37 @@ create_menu_bar_and_toolbar (VinagreWindow *window,
   action = gtk_action_group_get_action (action_group, "MachineConnect");
   g_object_set (action, "is_important", TRUE, NULL);
 
-  action_group = gtk_action_group_new ("VinagreWindowActions");
+  /* Machine connected actions */
+  action_group = gtk_action_group_new ("VinagreWindowMachineConnectedActions");
   gtk_action_group_set_translation_domain (action_group, NULL);
   gtk_action_group_add_actions (action_group,
-				vinagre_menu_entries,
-				G_N_ELEMENTS (vinagre_menu_entries),
+				vinagre_machine_connected_entries,
+				G_N_ELEMENTS (vinagre_machine_connected_entries),
 				window);
-
+  gtk_action_group_set_sensitive (action_group, FALSE);
   gtk_ui_manager_insert_action_group (manager, action_group, 0);
   g_object_unref (action_group);
-  window->priv->action_group = action_group;
+  window->priv->machine_connected_action_group = action_group;
 
   action = gtk_action_group_get_action (action_group, "MachineClose");
   g_object_set (action, "is_important", TRUE, NULL);
 
-  /* Machine connected actions */
-  action_group = gtk_action_group_new ("VinagreWindowMachineConnectedActions");
+  /* Machine initialized actions */
+  action_group = gtk_action_group_new ("VinagreWindowMachineInitializedActions");
   gtk_action_group_set_translation_domain (action_group, NULL);
   gtk_action_group_add_actions (action_group,
-				vinagre_machine_connected_menu_entries,
-				G_N_ELEMENTS (vinagre_machine_connected_menu_entries),
+				vinagre_machine_initialized_entries,
+				G_N_ELEMENTS (vinagre_machine_initialized_entries),
 				window);
-  gtk_action_group_add_toggle_actions  (action_group,
-					vinagre_machine_connected_toggle_menu_entries,
-					G_N_ELEMENTS (vinagre_machine_connected_toggle_menu_entries),
-					window);
-
+  gtk_action_group_set_sensitive (action_group, FALSE);
   gtk_ui_manager_insert_action_group (manager, action_group, 0);
   g_object_unref (action_group);
-  window->priv->machine_connected_action_group = action_group;
+  window->priv->machine_initialized_action_group = action_group;
 
   action = gtk_action_group_get_action (action_group, "ViewFullScreen");
   g_object_set (action, "is_important", TRUE, NULL);
   action = gtk_action_group_get_action (action_group, "MachineTakeScreenshot");
   g_object_set (action, "is_important", TRUE, NULL);
-  action = gtk_action_group_get_action (action_group, "MachineSendCtrlAltDel");
-  g_object_set (action, "is_important", TRUE, NULL);
 
   /* now load the UI definition */
   gtk_ui_manager_add_ui_from_file (manager, vinagre_utils_get_ui_xml_filename (), &error);
@@ -483,21 +472,6 @@ create_menu_bar_and_toolbar (VinagreWindow *window,
   show_hide_accels (window);
 }
 
-void
-vinagre_window_update_machine_menu_sensitivity (VinagreWindow *window)
-{
-  gboolean active;
-
-  g_return_if_fail (VINAGRE_IS_WINDOW (window));
-
-  active = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook)) > 0;
-  gtk_action_group_set_sensitive (window->priv->action_group, active);
-
-  active = (window->priv->active_tab) &&
-	   (vinagre_tab_get_state (VINAGRE_TAB (window->priv->active_tab)) == VINAGRE_TAB_STATE_CONNECTED);
-  gtk_action_group_set_sensitive (window->priv->machine_connected_action_group, active);
-}
-
 static void
 fav_panel_size_allocate (GtkWidget     *widget,
 			 GtkAllocation *allocation,
@@ -782,149 +756,20 @@ create_statusbar (VinagreWindow *window,
 		    0);
 }
 
-void
-vinagre_window_set_title (VinagreWindow *window)
-{
-  gchar *title, *name, *grab;
-
-  if (window->priv->active_tab == NULL)
-    {
-      gtk_window_set_title (GTK_WINDOW (window), g_get_application_name ());
-      return;
-    }
-
-  if (vinagre_tab_is_pointer_grab (VINAGRE_TAB (window->priv->active_tab)))
-    grab = g_strdup_printf (" (%s)", _("Press Ctrl+Alt to release the cursor"));
-  else
-    grab = g_strdup ("");
-
-  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (VINAGRE_TAB (window->priv->active_tab)));
-  title = g_strdup_printf ("%s%s - %s",
-			   name,
-			   grab,
-			   g_get_application_name ());
-  gtk_window_set_title (GTK_WINDOW (window), title);
-  g_free (title);
-  g_free (name);
-  g_free (grab);
-}
-
-static void
-update_toggle_machine_items (VinagreWindow *window)
-{
-  GtkAction *action;
-
-  g_return_if_fail (VINAGRE_IS_WINDOW (window));
-
-  if (window->priv->active_tab == NULL)
-    {
-      action = gtk_action_group_get_action (window->priv->machine_connected_action_group, "ViewScaling");
-      gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
-
-      action = gtk_action_group_get_action (window->priv->machine_connected_action_group, "ViewReadOnly");
-      gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
-
-      return;
-    }
-
-  action = gtk_action_group_get_action (window->priv->machine_connected_action_group, "ViewScaling");
-  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
-				vinagre_tab_get_scaling (VINAGRE_TAB (window->priv->active_tab)));
-
-  action = gtk_action_group_get_action (window->priv->machine_connected_action_group, "ViewReadOnly");
-  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
-				vinagre_tab_get_readonly (VINAGRE_TAB (window->priv->active_tab)));
-
-}
-
-static void
-vinagre_window_page_removed (GtkNotebook   *notebook,
-			     GtkWidget     *child,
-			     guint         page_num,
-			     VinagreWindow *window)
-{
-  GtkNotebook *nb;
-
-  g_return_if_fail (VINAGRE_IS_WINDOW (window));
-
-  nb = GTK_NOTEBOOK (window->priv->notebook);
-
-  window->priv->active_tab = gtk_notebook_get_nth_page (nb,
-							gtk_notebook_get_current_page (nb));
-
-  if (!window->priv->active_tab && window->priv->fullscreen)
-    vinagre_window_toggle_fullscreen (window);
-
-  vinagre_window_set_title (window);
-  update_toggle_machine_items (window);
-  vinagre_window_update_machine_menu_sensitivity (window);
-}
-
-static void
-vinagre_window_page_added (GtkNotebook  *notebook,
-			   GtkWidget     *child,
-			   guint         page_num,
-			   VinagreWindow *window)
-{
-  g_return_if_fail (VINAGRE_IS_WINDOW (window));
-
-  window->priv->active_tab = child;
-
-  vinagre_window_set_title (window);
-  update_toggle_machine_items (window);
-  vinagre_window_update_machine_menu_sensitivity (window);
-}
-
-static void 
-vinagre_window_switch_page (GtkNotebook     *notebook, 
-			    GtkNotebookPage *pg,
-			    gint            page_num, 
-			    VinagreWindow   *window)
-{
-  GtkWidget *tab;
-
-  g_return_if_fail (VINAGRE_IS_WINDOW (window));
-
-  tab = gtk_notebook_get_nth_page (notebook, page_num);
-  if (tab == window->priv->active_tab)
-    return;
-
-  window->priv->active_tab = tab;
-
-  vinagre_window_set_title (window);
-  update_toggle_machine_items (window);
-  vinagre_window_update_machine_menu_sensitivity (window);
-}
-
 static void
 create_notebook (VinagreWindow *window)
 {
   window->priv->notebook = vinagre_notebook_new (window);
 
   gtk_paned_pack2 (GTK_PANED (window->priv->hpaned), 
-  		   window->priv->notebook,
+  		   GTK_WIDGET (window->priv->notebook),
   		   TRUE, 
   		   FALSE);
 
-  window->priv->signal_notebook =
-   g_signal_connect_after (window->priv->notebook,
-		          "page-removed",
-		          G_CALLBACK (vinagre_window_page_removed),
-		          window);
-
-  g_signal_connect_after (window->priv->notebook,
-		          "page-added",
-		          G_CALLBACK (vinagre_window_page_added),
-		          window);
-
-  g_signal_connect (window->priv->notebook,
-		    "switch_page",
-		    G_CALLBACK (vinagre_window_switch_page),
-		    window);
-
-  gtk_widget_show (window->priv->notebook);
+  gtk_widget_show (GTK_WIDGET (window->priv->notebook));
 }
 
+/*
 static void
 vinagre_window_clipboard_cb (GtkClipboard *cb, GdkEvent *event, VinagreWindow *window)
 {
@@ -940,7 +785,7 @@ vinagre_window_clipboard_cb (GtkClipboard *cb, GdkEvent *event, VinagreWindow *w
   if (!text)
     return;
 
-  vinagre_tab_paste_text (VINAGRE_TAB (window->priv->active_tab), text);
+//  vinagre_tab_paste_text (VINAGRE_TAB (window->priv->active_tab), text);
   g_free (text);
 }
 
@@ -955,6 +800,7 @@ vinagre_window_init_clipboard (VinagreWindow *window)
 						     G_CALLBACK (vinagre_window_clipboard_cb),
 						     window);
 }
+*/
 
 static void
 vinagre_window_init (VinagreWindow *window)
@@ -964,10 +810,8 @@ vinagre_window_init (VinagreWindow *window)
   gtk_window_set_default_icon_name ("vinagre");
 
   window->priv = VINAGRE_WINDOW_GET_PRIVATE (window);
-  window->priv->active_tab = NULL;
   window->priv->fav_entry_selected = NULL;
   window->priv->fullscreen = FALSE;
-  window->priv->signal_notebook = 0;
 
   main_box = gtk_vbox_new (FALSE, 0);
   gtk_container_add (GTK_CONTAINER (window), main_box);
@@ -998,7 +842,7 @@ vinagre_window_init (VinagreWindow *window)
   gtk_widget_grab_focus (window->priv->hpaned);
 
   init_widgets_visibility (window);
-  vinagre_window_update_machine_menu_sensitivity (window);
+//  vinagre_window_merge_tab_ui (window);
 
   vinagre_window_update_bookmarks_list_menu (window);
   g_signal_connect_swapped (vinagre_bookmarks_get_default (),
@@ -1011,10 +855,10 @@ vinagre_window_init (VinagreWindow *window)
                             G_CALLBACK (vinagre_window_update_bookmarks_list_menu),
                             window);
 #endif
-  vinagre_window_init_clipboard (window);
+  //vinagre_window_init_clipboard (window);
 }
 
-GtkWidget *
+VinagreNotebook *
 vinagre_window_get_notebook (VinagreWindow *window)
 {
   g_return_val_if_fail (VINAGRE_IS_WINDOW (window), NULL);
@@ -1023,25 +867,13 @@ vinagre_window_get_notebook (VinagreWindow *window)
 }
 
 void
-vinagre_window_close_tab (VinagreWindow *window,
-			  VinagreTab    *tab)
-{
-  g_return_if_fail (VINAGRE_IS_WINDOW (window));
-  g_return_if_fail (VINAGRE_IS_TAB (tab));
-	
-  vinagre_notebook_remove_tab (VINAGRE_NOTEBOOK (window->priv->notebook),
-			       tab);
-}
-
-void
 vinagre_window_close_all_tabs (VinagreWindow *window)
 {
   g_return_if_fail (VINAGRE_IS_WINDOW (window));
 
-  vinagre_notebook_remove_all_tabs (VINAGRE_NOTEBOOK (window->priv->notebook));
+  vinagre_notebook_close_all_tabs (VINAGRE_NOTEBOOK (window->priv->notebook));
 }
 
-
 void
 vinagre_window_set_active_tab (VinagreWindow *window,
 			       VinagreTab    *tab)
@@ -1108,15 +940,15 @@ vinagre_window_get_menubar (VinagreWindow *window)
 }
 
 GtkActionGroup *
-vinagre_window_get_main_action (VinagreWindow *window)
+vinagre_window_get_initialized_action (VinagreWindow *window)
 {
   g_return_val_if_fail (VINAGRE_IS_WINDOW (window), NULL);
 
-  return window->priv->action_group;
+  return window->priv->machine_initialized_action_group;
 }
 
 GtkActionGroup *
-vinagre_window_get_sensitive_action (VinagreWindow *window)
+vinagre_window_get_always_sensitive_action (VinagreWindow *window)
 {
   g_return_val_if_fail (VINAGRE_IS_WINDOW (window), NULL);
 
@@ -1144,8 +976,7 @@ vinagre_window_close_active_tab	(VinagreWindow *window)
 {
   g_return_if_fail (VINAGRE_IS_WINDOW (window));
 
-  vinagre_window_close_tab (window,
-			    VINAGRE_TAB (window->priv->active_tab));
+  vinagre_notebook_close_active_tab (window->priv->notebook);
 }
 
 VinagreTab *
@@ -1153,7 +984,7 @@ vinagre_window_get_active_tab (VinagreWindow *window)
 {
   g_return_val_if_fail (VINAGRE_IS_WINDOW (window), NULL);
 
-  return VINAGRE_TAB (window->priv->active_tab);
+  return vinagre_notebook_get_active_tab (window->priv->notebook);
 }
 
 GtkUIManager *
@@ -1208,7 +1039,8 @@ vinagre_window_conn_exists (VinagreWindow *window, VinagreConnection *conn)
       c = VINAGRE_CONNECTION (l->data);
 
       if (!strcmp (vinagre_connection_get_host (conn), vinagre_connection_get_host (c)) &&
-	  vinagre_connection_get_port (conn) == vinagre_connection_get_port (c))
+	  vinagre_connection_get_port (conn) == vinagre_connection_get_port (c) &&
+	  vinagre_connection_get_protocol (conn) == vinagre_connection_get_protocol (c))
 	{
 	  tab = g_object_get_data (G_OBJECT (c), VINAGRE_TAB_KEY);
 	  break;
diff --git a/src/vinagre-window.h b/src/vinagre-window.h
index ae0fa2a..435ddf0 100644
--- a/src/vinagre-window.h
+++ b/src/vinagre-window.h
@@ -2,7 +2,7 @@
  * vinagre-window.h
  * This file is part of vinagre
  *
- * Copyright (C) 2007 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2009 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -55,9 +55,6 @@ GType 		 vinagre_window_get_type 		(void) G_GNUC_CONST;
 
 VinagreWindow   *vinagre_window_new			(void);
 
-VinagreTab	*vinagre_window_create_tab		(VinagreWindow         *window,
-							 gboolean              jump_to);
-							 
 void		 vinagre_window_close_tab		(VinagreWindow         *window,
 							 VinagreTab            *tab);
 void		 vinagre_window_close_active_tab	(VinagreWindow         *window);
@@ -76,9 +73,9 @@ GtkWidget	*vinagre_window_get_statusbar		(VinagreWindow         *window);
 GtkWidget	*vinagre_window_get_toolbar		(VinagreWindow         *window);
 GtkWidget	*vinagre_window_get_menubar		(VinagreWindow         *window);
 GtkWidget	*vinagre_window_get_fav_panel		(VinagreWindow         *window);
-GtkWidget	*vinagre_window_get_notebook		(VinagreWindow	       *window);
-GtkActionGroup	*vinagre_window_get_main_action		(VinagreWindow         *window);
-GtkActionGroup	*vinagre_window_get_sensitive_action	(VinagreWindow         *window);
+VinagreNotebook	*vinagre_window_get_notebook		(VinagreWindow	       *window);
+GtkActionGroup	*vinagre_window_get_initialized_action	(VinagreWindow         *window);
+GtkActionGroup	*vinagre_window_get_always_sensitive_action (VinagreWindow     *window);
 GtkActionGroup	*vinagre_window_get_connected_action	(VinagreWindow         *window);
 
 void		vinagre_window_update_bookmarks_list_menu (VinagreWindow       *window);
@@ -88,9 +85,8 @@ GtkUIManager	*vinagre_window_get_ui_manager		(VinagreWindow         *window);
 gboolean	vinagre_window_is_fullscreen		(VinagreWindow         *window);
 
 void		vinagre_window_toggle_fullscreen	(VinagreWindow *window);
-void		vinagre_window_set_title		(VinagreWindow *window);
 
-void		vinagre_window_update_machine_menu_sensitivity (VinagreWindow	*window);
+void		vinagre_window_merge_tab_ui (VinagreWindow	*window);
 
 GList 		*vinagre_window_get_connections		(VinagreWindow *window);
 VinagreTab	*vinagre_window_conn_exists		(VinagreWindow *window,



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