[vinagre] First step (in a total of XX) towards plugin support.



commit 4c4e628a59049ef12f3a0189b43189a6bebf0773
Author: Jonh Wendell <jwendell gnome org>
Date:   Sat Jul 11 01:46:14 2009 +0100

    First step (in a total of XX) towards plugin support.
    
    Things aren't compiling. Just committed because I don't want to loose
    the work I've done so far. Tomorrow I continue, it's 2 am dude...

 configure.ac                                      |    9 +-
 plugins/vnc/Makefile.am                           |   12 +-
 {vinagre => plugins/vnc}/vinagre-vnc-connection.c |   10 +-
 {vinagre => plugins/vnc}/vinagre-vnc-connection.h |    2 +-
 plugins/vnc/vinagre-vnc-plugin.c                  |  113 +++++++++-
 vinagre/Makefile.am                               |    3 -
 vinagre/vinagre-bookmarks-migration.c             |   35 ++--
 vinagre/vinagre-bookmarks-ui.c                    |    3 +-
 vinagre/vinagre-bookmarks.c                       |   36 +++-
 vinagre/vinagre-bookmarks.h                       |   12 +-
 vinagre/vinagre-connection.c                      |  251 +++++++--------------
 vinagre/vinagre-connection.h                      |   21 +--
 vinagre/vinagre-enums.c                           |   21 --
 vinagre/vinagre-enums.h                           |    4 -
 vinagre/vinagre-plugin.c                          |  100 ++++++++-
 vinagre/vinagre-plugin.h                          |   20 ++-
 vinagre/vinagre-plugins-engine.c                  |   77 +++++--
 vinagre/vinagre-plugins-engine.h                  |   39 ++--
 18 files changed, 468 insertions(+), 300 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index f726690..e16be18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -72,10 +72,17 @@ PKG_CHECK_MODULES(VINAGRE, \
   gconf-2.0 >= $GCONF_REQUIRED \
   gthread-2.0 >= $GTHREAD_REQUIRED \
   gnome-keyring-1 \
-  gtk-vnc-1.0 >= $GTK_VNC_REQUIRED)
+)
 AC_SUBST(VINAGRE_CFLAGS)
 AC_SUBST(VINAGRE_LIBS)
 
+PKG_CHECK_MODULES(VNC, \
+  gtk-vnc-1.0 >= $GTK_VNC_REQUIRED \
+  libxml-2.0
+)
+AC_SUBST(VNC_CFLAGS)
+AC_SUBST(VNC_LIBS)
+
 # Check for telepathy
 AC_ARG_ENABLE(telepathy,
               AS_HELP_STRING([--enable-telepathy=@<:@no/yes/auto@:>@],
diff --git a/plugins/vnc/Makefile.am b/plugins/vnc/Makefile.am
index 9f4206b..fd163c7 100644
--- a/plugins/vnc/Makefile.am
+++ b/plugins/vnc/Makefile.am
@@ -3,18 +3,20 @@ plugindir = $(VINAGRE_PLUGINS_LIBS_DIR)
 
 INCLUDES = \
 	-I$(top_srcdir) 				\
-	$(VINAGRE_CFLAGS) 				\
+	$(VNC_CFLAGS) 				\
 	$(WARN_CFLAGS)					\
 	$(DISABLE_DEPRECATED_CFLAGS)	
 
 plugin_LTLIBRARIES = libvnc.la
 
-libvnc_la_SOURCES = \
-	vinagre-vnc-plugin.h	\
-	vinagre-vnc-plugin.c
+libvnc_la_SOURCES = 			\
+	vinagre-vnc-plugin.h		\
+	vinagre-vnc-plugin.c		\
+	vinagre-vnc-connection.h	\
+	vinagre-vnc-connection.c
 
 libvnc_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
-libvnc_la_LIBADD  = $(VINAGRE_LIBS)
+libvnc_la_LIBADD  = $(VNC_LIBS)
 
 #uidir = $(VINAGRE_PLUGINS_DATA_DIR)/vnc
 #ui_DATA = vnc.ui
diff --git a/vinagre/vinagre-vnc-connection.c b/plugins/vnc/vinagre-vnc-connection.c
similarity index 97%
rename from vinagre/vinagre-vnc-connection.c
rename to plugins/vnc/vinagre-vnc-connection.c
index f70b04b..8ecca4c 100644
--- a/vinagre/vinagre-vnc-connection.c
+++ b/plugins/vnc/vinagre-vnc-connection.c
@@ -20,6 +20,7 @@
  */
 
 #include <glib/gi18n.h>
+#include <vinagre/vinagre-utils.h>
 #include "vinagre-vnc-connection.h"
 
 struct _VinagreVncConnectionPrivate
@@ -47,7 +48,6 @@ 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;
@@ -136,8 +136,8 @@ 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);
+  xmlTextWriterWriteFormatElement (writer, (const xmlChar *)"view_only", "%d", vnc_conn->priv->view_only);
+  xmlTextWriterWriteFormatElement (writer, (const xmlChar *)"scaling", "%d", vnc_conn->priv->scaling);
 }
 
 static void
@@ -154,9 +154,9 @@ vnc_parse_item (VinagreConnection *conn, xmlNode *root)
       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));
+	vinagre_vnc_connection_set_view_only (vnc_conn, vinagre_utils_parse_boolean ((const gchar *)s_value));
       else if (!xmlStrcmp(curr->name, (const xmlChar *)"scaling"))
-	vinagre_vnc_connection_set_scaling (vnc_conn, vinagre_utils_parse_boolean (s_value));
+	vinagre_vnc_connection_set_scaling (vnc_conn, vinagre_utils_parse_boolean ((const gchar *)s_value));
 
       xmlFree (s_value);
     }
diff --git a/vinagre/vinagre-vnc-connection.h b/plugins/vnc/vinagre-vnc-connection.h
similarity index 98%
rename from vinagre/vinagre-vnc-connection.h
rename to plugins/vnc/vinagre-vnc-connection.h
index 16f9e7a..347abe5 100644
--- a/vinagre/vinagre-vnc-connection.h
+++ b/plugins/vnc/vinagre-vnc-connection.h
@@ -22,7 +22,7 @@
 #ifndef __VINAGRE_VNC_CONNECTION_H__
 #define __VINAGRE_VNC_CONNECTION_H__
 
-#include "vinagre-connection.h"
+#include <vinagre/vinagre-connection.h>
 
 G_BEGIN_DECLS
 
diff --git a/plugins/vnc/vinagre-vnc-plugin.c b/plugins/vnc/vinagre-vnc-plugin.c
index debc532..cb755a5 100644
--- a/plugins/vnc/vinagre-vnc-plugin.c
+++ b/plugins/vnc/vinagre-vnc-plugin.c
@@ -23,6 +23,7 @@
 #endif
 
 #include "vinagre-vnc-plugin.h"
+#include "vinagre-vnc-connection.h"
 
 #include <string.h>
 #include <glib/gi18n-lib.h>
@@ -32,7 +33,7 @@
 #include <vinagre/vinagre-debug.h>
 #include <vinagre/vinagre-utils.h>
 
-#define VINAGRE_SORT_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), VINAGRE_TYPE_SORT_PLUGIN, VinagreVncPluginPrivate))
+#define VINAGRE_VNC_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), VINAGRE_TYPE_VNC_PLUGIN, VinagreVncPluginPrivate))
 
 VINAGRE_PLUGIN_REGISTER_TYPE(VinagreVncPlugin, vinagre_vnc_plugin)
 
@@ -65,6 +66,113 @@ impl_get_context_group (VinagrePlugin *plugin)
   return vnc_display_get_option_group ();
 }
 
+static const gchar *
+impl_get_protocol (VinagrePlugin *plugin)
+{
+  return "vnc";
+}
+
+static VinagreConnection *
+impl_new_connection (VinagrePlugin *plugin)
+{
+  return vinagre_vnc_connection_new ();
+}
+
+static VinagreConnection *
+impl_new_connection_from_file (VinagrePlugin *plugin,
+			       const gchar   *data,
+			       gboolean       use_bookmarks,
+			       gchar        **error_msg)
+{
+  GKeyFile          *file;
+  GError            *error;
+  gboolean           loaded;
+  gchar             *host, *actual_host, *protocol;
+  gint               port;
+  VinagreConnection *conn;
+
+  *error_msg = NULL;
+  conn = NULL;
+  host = NULL;
+  protocol = NULL;
+
+  file = g_key_file_new ();
+  loaded = g_key_file_load_from_data (file,
+				      data,
+				      -1,
+				      0,
+				      &error);
+  if (!loaded)
+    {
+      if (error)
+	{
+	  *error_msg = g_strdup (error->message);
+	  g_error_free (error);
+	}
+      else
+	*error_msg = g_strdup (_("Could not parse the file."));
+
+      goto the_end;
+    }
+
+  if (!g_key_file_has_group (file, "connection"))
+    {
+      *error_msg = g_strdup (_("The file is not a VNC one: Missing the group \"connection\"."));
+      goto the_end;
+    }
+
+  if (!g_key_file_has_key (file, "connection", "host", NULL))
+    {
+      *error_msg = g_strdup (_("The file is not a VNC one: Missing the key \"host\"."));
+      goto the_end;
+    }
+
+  host = g_key_file_get_string (file, "connection", "host", NULL);
+  port = g_key_file_get_integer (file, "connection", "port", NULL);
+  if (!port)
+    {
+      if (!vinagre_connection_split_string (host, &protocol, &actual_host, &port, error_msg))
+	goto the_end;
+
+      g_free (host);
+      host = actual_host;
+    }
+
+  if (use_bookmarks)
+    conn = vinagre_bookmarks_exists (vinagre_bookmarks_get_default (), "vnc", host, port);
+  if (!conn)
+    {
+      gchar *s_value;
+      gint shared;
+
+      conn = vinagre_vnc_connection_new ();
+      vinagre_connection_set_host (conn, host);
+      vinagre_connection_set_port (conn, port);
+
+      s_value = g_key_file_get_string  (file, "connection", "username", NULL);
+      vinagre_connection_set_username (conn, s_value);
+      g_free (s_value);
+
+      s_value = g_key_file_get_string  (file, "connection", "password", NULL);
+      vinagre_connection_set_password (conn, s_value);
+      g_free (s_value);
+
+      shared = g_key_file_get_integer (file, "options", "shared", NULL);
+      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);
+    }
+
+the_end:
+
+  g_free (host);
+  g_free (protocol);
+  g_key_file_free (file);
+  return conn;
+
+}
+
 static void
 vinagre_vnc_plugin_init (VinagreVncPlugin *plugin)
 {
@@ -91,5 +199,8 @@ vinagre_vnc_plugin_class_init (VinagreVncPluginClass *klass)
   plugin_class->deactivate = impl_deactivate;
   plugin_class->update_ui  = impl_update_ui;
   plugin_class->get_context_group = impl_get_context_group;
+  plugin_class->get_protocol  = impl_get_protocol;
+  plugin_class->new_connection = impl_new_connection;
+  plugin_class->new_connection_from_file = impl_new_connection_from_file;
 }
 /* vim: set ts=8: */
diff --git a/vinagre/Makefile.am b/vinagre/Makefile.am
index 781ada1..4cc011a 100644
--- a/vinagre/Makefile.am
+++ b/vinagre/Makefile.am
@@ -47,7 +47,6 @@ INST_H_FILES = \
   vinagre-tab.h \
   vinagre-ui.h \
   vinagre-utils.h \
-  vinagre-vnc-connection.h \
   vinagre-vnc-tab.h \
   vinagre-window.h \
   $(NULL)
@@ -87,7 +86,6 @@ libvinagre_la_SOURCES = \
   vinagre-prefs.c \
   vinagre-tab.c \
   vinagre-utils.c \
-  vinagre-vnc-connection.c \
   vinagre-vnc-tab.c \
   vinagre-window.c \
   $(NOINST_H_FILES) \
@@ -154,7 +152,6 @@ 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/vinagre/vinagre-bookmarks-migration.c b/vinagre/vinagre-bookmarks-migration.c
index 17c84f1..3114c8e 100644
--- a/vinagre/vinagre-bookmarks-migration.c
+++ b/vinagre/vinagre-bookmarks-migration.c
@@ -33,6 +33,8 @@
 #include "vinagre-connection.h"
 #include "vinagre-bookmarks-migration.h"
 #include "vinagre-bookmarks.h"
+#include "vinagre-plugin.h"
+#include "vinagre-plugins-engine.h"
 
 static void
 fill_xml (GSList *list, xmlTextWriter *writer)
@@ -153,6 +155,15 @@ create_list (GKeyFile *kf)
   GSList *entries;
   gchar **conns;
   gsize   length, i;
+  VinagrePlugin *plugin;
+
+  plugin = g_hash_table_lookup (vinagre_plugin_engine_get_plugins_by_protocol (vinagre_plugins_engine_get_default ()),
+				"vnc");
+  if (!plugin)
+    {
+      g_warning (_("Error while migrating bookmarks: VNC plugin is not activated"));
+      return NULL;
+    }
 
   entries = NULL;
   conns = g_key_file_get_groups (kf, &length);
@@ -167,29 +178,25 @@ create_list (GKeyFile *kf)
       if (!s_value)
         continue;
 
-      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);
-
+      conn = vinagre_plugin_new_connection (plugin);
       i_value = g_key_file_get_integer (kf, conns[i], "port", NULL);
       if (i_value == 0)
         i_value = 5900;
-      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);
 
-      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);
+      g_object_set (conn,
+		    "name", conns[i],
+		    "host", s_value,
+		    "port", i_value,
+		    "view-only", g_key_file_get_boolean (kf, conns[i], "view_only", NULL),
+		    "fullscreen", g_key_file_get_boolean (kf, conns[i], "fullscreen", NULL),
+		    "scaling", g_key_file_get_boolean (kf, conns[i], "scaling", NULL),
+		    NULL);
 
       entries = g_slist_insert_sorted  (entries,
 					vinagre_bookmarks_entry_new_conn (conn),
 					(GCompareFunc)vinagre_bookmarks_entry_compare);
       g_object_unref (conn);
+      g_free (s_value);
     }
 
   g_strfreev (conns);
diff --git a/vinagre/vinagre-bookmarks-ui.c b/vinagre/vinagre-bookmarks-ui.c
index ed1cd8c..d457d23 100644
--- a/vinagre/vinagre-bookmarks-ui.c
+++ b/vinagre/vinagre-bookmarks-ui.c
@@ -119,7 +119,7 @@ show_dialog_conn (VinagreBookmarks      *book,
 		  VinagreBookmarksEntry *entry,
 		  gboolean               is_add)
 {
-  gchar             *str, *host, *error_str;
+  gchar             *str, *host, *error_str, *protocol;
   gint               port;
   GladeXML          *xml;
   GtkWidget         *dialog, *host_entry, *name_entry;
@@ -127,7 +127,6 @@ 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",
diff --git a/vinagre/vinagre-bookmarks.c b/vinagre/vinagre-bookmarks.c
index d773bfc..d2b69e8 100644
--- a/vinagre/vinagre-bookmarks.c
+++ b/vinagre/vinagre-bookmarks.c
@@ -28,6 +28,8 @@
 #include "vinagre-bookmarks-entry.h"
 #include "vinagre-bookmarks-migration.h"
 #include "vinagre-connection.h"
+#include "vinagre-plugin.h"
+#include "vinagre-plugins-engine.h"
 
 struct _VinagreBookmarksPrivate
 {
@@ -145,10 +147,10 @@ vinagre_bookmarks_class_init (VinagreBookmarksClass *klass)
 }
 
 static VinagreConnection *
-find_conn_by_host (GSList *entries,
-		   VinagreConnectionProtocol protocol,
+find_conn_by_host (GSList      *entries,
+		   const gchar *protocol,
 		   const gchar *host,
-		   gint port)
+		   gint         port)
 {
   GSList *l;
   VinagreConnection *conn;
@@ -171,7 +173,7 @@ find_conn_by_host (GSList *entries,
 	    conn = vinagre_bookmarks_entry_get_conn (entry);
 	    if ( (g_str_equal (host, vinagre_connection_get_host (conn))) &&
 		 (port == vinagre_connection_get_port (conn)) &&
-		 (protocol == vinagre_connection_get_protocol (conn)) )
+		 (g_str_equal (protocol, vinagre_connection_get_protocol (conn))) )
 	      return g_object_ref (conn);
 	    break;
 
@@ -184,9 +186,9 @@ find_conn_by_host (GSList *entries,
 
 VinagreConnection *
 vinagre_bookmarks_exists (VinagreBookmarks *book,
-                          VinagreConnectionProtocol protocol,
-                          const gchar *host,
-                          gint port)
+                          const gchar      *protocol,
+                          const gchar      *host,
+                          gint              port)
 {
   VinagreConnection *conn = NULL;
   GSList *l, *next;
@@ -238,7 +240,8 @@ vinagre_bookmarks_parse_item (xmlNode *root)
   VinagreConnection     *conn;
   xmlNode               *curr;
   xmlChar               *s_value;
-  VinagreConnectionProtocol protocol = VINAGRE_CONNECTION_PROTOCOL_VNC;
+  gchar                 *protocol = NULL;
+  VinagrePlugin         *plugin;
 
   /* Loop to discover the protocol */
   for (curr = root->children; curr; curr = curr->next)
@@ -247,12 +250,23 @@ vinagre_bookmarks_parse_item (xmlNode *root)
         continue;
 
       s_value = xmlNodeGetContent (curr);
-      protocol = vinagre_connection_protocol_by_name ((const gchar *)s_value);
+      protocol = g_strdup ((const gchar *)s_value);
       xmlFree (s_value);
       break;
     }
 
-  conn = vinagre_connection_new (protocol);
+  if (!protocol)
+    protocol = g_strdup ("vnc");
+
+  plugin = g_hash_table_lookup (vinagre_plugin_engine_get_plugins_by_protocol (vinagre_plugins_engine_get_default ()),
+				protocol);
+  if (!plugin)
+    {
+      g_warning (_("The protocol %s is not supported."), protocol);
+      goto out;
+    }
+
+  conn = vinagre_plugin_new_connection (plugin);
   vinagre_connection_parse_item (conn, root);
 
   if (vinagre_connection_get_host (conn))
@@ -260,6 +274,8 @@ vinagre_bookmarks_parse_item (xmlNode *root)
 
   g_object_unref (conn);
 
+out:
+  g_free (protocol);
   return entry;
 }
 
diff --git a/vinagre/vinagre-bookmarks.h b/vinagre/vinagre-bookmarks.h
index 2aabf08..37acd6d 100644
--- a/vinagre/vinagre-bookmarks.h
+++ b/vinagre/vinagre-bookmarks.h
@@ -24,8 +24,8 @@
 #include <glib.h>
 #include <glib-object.h>
 
-#include "vinagre-connection.h"
-#include "vinagre-bookmarks-entry.h"
+#include <vinagre/vinagre-connection.h>
+#include <vinagre/vinagre-bookmarks-entry.h>
 
 G_BEGIN_DECLS
 
@@ -57,8 +57,6 @@ struct _VinagreBookmarks
   VinagreBookmarksPrivate *priv;
 };
 
-#include "vinagre-window.h"
-
 GType vinagre_bookmarks_get_type (void) G_GNUC_CONST;
 
 VinagreBookmarks   *vinagre_bookmarks_get_default  (void);
@@ -71,9 +69,9 @@ gboolean           vinagre_bookmarks_remove_entry  (VinagreBookmarks      *book,
                                                     VinagreBookmarksEntry *entry);
 
 VinagreConnection  *vinagre_bookmarks_exists       (VinagreBookmarks *book,
-                                                    VinagreConnectionProtocol protocol,
-                                                    const gchar *host,
-                                                    gint port);
+                                                    const gchar      *protocol,
+                                                    const gchar      *host,
+                                                    gint              port);
 
 VinagreBookmarksEntry *vinagre_bookmarks_name_exists (VinagreBookmarks      *book,
                                                       VinagreBookmarksEntry *parent,
diff --git a/vinagre/vinagre-connection.c b/vinagre/vinagre-connection.c
index 748600c..550bd5f 100644
--- a/vinagre/vinagre-connection.c
+++ b/vinagre/vinagre-connection.c
@@ -26,11 +26,12 @@
 #include "vinagre-connection.h"
 #include "vinagre-enums.h"
 #include "vinagre-bookmarks.h"
-#include "vinagre-vnc-connection.h"
+#include "vinagre-plugin.h"
+#include "vinagre-plugins-engine.h"
 
 struct _VinagreConnectionPrivate
 {
-  VinagreConnectionProtocol protocol;
+  gchar *protocol;
   gchar *host;
   gint   port;
   gchar *username;
@@ -53,9 +54,6 @@ enum
   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_ABSTRACT_TYPE (VinagreConnection, vinagre_connection, G_TYPE_OBJECT);
 
@@ -64,7 +62,7 @@ vinagre_connection_init (VinagreConnection *conn)
 {
   conn->priv = G_TYPE_INSTANCE_GET_PRIVATE (conn, VINAGRE_TYPE_CONNECTION, VinagreConnectionPrivate);
 
-  conn->priv->protocol = VINAGRE_CONNECTION_PROTOCOL_INVALID;
+  conn->priv->protocol = NULL;
   conn->priv->host = NULL;
   conn->priv->port = 0;
   conn->priv->password = NULL;
@@ -78,6 +76,7 @@ vinagre_connection_finalize (GObject *object)
 {
   VinagreConnection *conn = VINAGRE_CONNECTION (object);
 
+  g_free (conn->priv->protocol);
   g_free (conn->priv->host);
   g_free (conn->priv->username);
   g_free (conn->priv->password);
@@ -98,7 +97,7 @@ vinagre_connection_set_property (GObject *object, guint prop_id, const GValue *v
   switch (prop_id)
     {
       case PROP_PROTOCOL:
-	vinagre_connection_set_protocol (conn, g_value_get_enum (value));
+	vinagre_connection_set_protocol (conn, g_value_get_string (value));
 	break;
 
       case PROP_HOST:
@@ -144,7 +143,7 @@ vinagre_connection_get_property (GObject *object, guint prop_id, GValue *value,
   switch (prop_id)
     {
       case PROP_PROTOCOL:
-	g_value_set_enum (value, conn->priv->protocol);
+	g_value_set_string (value, conn->priv->protocol);
 	break;
 
       case PROP_HOST:
@@ -216,8 +215,9 @@ default_parse_item (VinagreConnection *conn, xmlNode *root)
       xmlFree (s_value);
     }
 
-  if (conn->priv->port <= 0)
-    vinagre_connection_set_port (conn, vinagre_connection_default_port [conn->priv->protocol-1]);
+// TODO:
+//  if (conn->priv->port <= 0)
+//    vinagre_connection_set_port (conn, vinagre_connection_default_port [conn->priv->protocol-1]);
 
 }
 
@@ -251,16 +251,15 @@ vinagre_connection_class_init (VinagreConnectionClass *klass)
 
   g_object_class_install_property (object_class,
                                    PROP_PROTOCOL,
-                                   g_param_spec_enum ("protocol",
-                                                      "protocol",
-	                                              "connection protocol",
-                                                      VINAGRE_TYPE_CONNECTION_PROTOCOL,
-	                                              VINAGRE_CONNECTION_PROTOCOL_VNC,
-	                                              G_PARAM_READWRITE |
-                                                      G_PARAM_CONSTRUCT |
-                                                      G_PARAM_STATIC_NICK |
-                                                      G_PARAM_STATIC_NAME |
-                                                      G_PARAM_STATIC_BLURB));
+                                   g_param_spec_string ("protocol",
+                                                        "protocol",
+	                                                "connection protocol",
+                                                        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_HOST,
@@ -361,39 +360,19 @@ vinagre_connection_class_init (VinagreConnectionClass *klass)
 
 void
 vinagre_connection_set_protocol (VinagreConnection *conn,
-			         VinagreConnectionProtocol protocol)
+			         const gchar       *protocol)
 {
   g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
 
-  conn->priv->protocol = protocol;
+  g_free (conn->priv->protocol);
+  conn->priv->protocol = g_strdup (protocol);
 }
-VinagreConnectionProtocol
-vinagre_connection_get_protocol (VinagreConnection *conn)
-{
-  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn),
-                        VINAGRE_CONNECTION_PROTOCOL_INVALID);
-
-  return conn->priv->protocol;
-}
-
 const gchar *
-vinagre_connection_get_protocol_as_string (VinagreConnection *conn)
+vinagre_connection_get_protocol (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;
+  return conn->priv->protocol;
 }
 
 void
@@ -499,6 +478,7 @@ vinagre_connection_get_name (VinagreConnection *conn)
 GdkPixbuf *
 vinagre_connection_get_icon (VinagreConnection *conn)
 {
+/*
   GdkPixbuf         *pixbuf;
   GtkIconTheme      *icon_theme;
   gchar             *icon_name;
@@ -517,31 +497,23 @@ vinagre_connection_get_icon (VinagreConnection *conn)
 
   g_free (icon_name);
   return pixbuf;
-}
-
-VinagreConnectionProtocol
-protocol_by_name (const gchar *protocol)
-{
-  gint i;
-
-  for (i=1; i<VINAGRE_CONNECTION_PROTOCOL_INVALID; i++)
-    if (g_strcmp0 (vinagre_connection_protos[i-1], protocol) == 0)
-      return i;
-
-  return VINAGRE_CONNECTION_PROTOCOL_INVALID;
+*/
+ // TODO:
+  return NULL;
 }
 
 gboolean
 vinagre_connection_split_string (const gchar *uri,
-				 VinagreConnectionProtocol *protocol,
-				 gchar **host,
-				 gint *port,
-				 gchar **error_msg)
+				 gchar       **protocol,
+				 gchar       **host,
+				 gint         *port,
+				 gchar       **error_msg)
 {
   gchar **server, **url;
   gint    lport;
   gchar  *lhost;
   gchar   ipv6_host[255] = {0,};
+  VinagrePlugin *plugin;
 
   *error_msg = NULL;
   *host = NULL;
@@ -550,22 +522,25 @@ vinagre_connection_split_string (const gchar *uri,
   url = g_strsplit (uri, "://", 2);
   if (g_strv_length (url) == 2)
     {
-      *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]);
-	  g_strfreev (url);
-	  return FALSE;
-	}
+      *protocol = g_strdup (url[0]);
       lhost = url[1];
     }
   else
     {
-      *protocol = VINAGRE_CONNECTION_PROTOCOL_VNC;
+      *protocol = g_strdup ("vnc");
       lhost = (gchar *) uri;
     }
 
+  plugin = g_hash_table_lookup (vinagre_plugin_engine_get_plugins_by_protocol (vinagre_plugins_engine_get_default ()),
+				*protocol);
+  if (!plugin)
+    {
+      *error_msg = g_strdup_printf (_("The protocol %s is not supported."), *protocol);
+      g_free (*protocol);
+      g_strfreev (url);
+      return FALSE;
+    }
+
   if (lhost[0] == '[')
     {
       int i;
@@ -581,14 +556,14 @@ vinagre_connection_split_string (const gchar *uri,
   if (g_strrstr (lhost, "::") != NULL)
     {
       server = g_strsplit (lhost, "::", 2);
-      lport = server[1] ? atoi (server[1]) : vinagre_connection_default_port [*protocol-1];
+      lport = server[1] ? atoi (server[1]) : vinagre_plugin_get_default_port (plugin);
     }
   else
     {
       server = g_strsplit (lhost, ":", 2);
-      lport = server[1] ? atoi (server[1]) : vinagre_connection_default_port [*protocol-1];
+      lport = server[1] ? atoi (server[1]) : vinagre_plugin_get_default_port (plugin);
 
-      if ((*protocol == VINAGRE_CONNECTION_PROTOCOL_VNC) && (lport < 1024))
+      if ((g_str_equal (*protocol, "vnc")) && (lport < 1024))
         lport += 5900;
     }
 
@@ -607,9 +582,9 @@ VinagreConnection *
 vinagre_connection_new_from_string (const gchar *uri, gchar **error_msg, gboolean use_bookmarks)
 {
   VinagreConnection *conn = NULL;
-  VinagreConnectionProtocol protocol;
   gint    port;
-  gchar  *host;
+  gchar  *host, *protocol;
+  VinagrePlugin *plugin;
 
   if (!vinagre_connection_split_string (uri, &protocol, &host, &port, error_msg))
     return NULL;
@@ -621,7 +596,9 @@ vinagre_connection_new_from_string (const gchar *uri, gchar **error_msg, gboolea
 				     port);
   if (!conn)
     {
-      conn = vinagre_connection_new (protocol);
+      plugin = g_hash_table_lookup (vinagre_plugin_engine_get_plugins_by_protocol (vinagre_plugins_engine_get_default ()),
+				    protocol);
+      conn = vinagre_plugin_new_connection (plugin);
       vinagre_connection_set_host (conn, host);
       vinagre_connection_set_port (conn, port);
     }
@@ -633,32 +610,26 @@ vinagre_connection_new_from_string (const gchar *uri, gchar **error_msg, gboolea
 VinagreConnection *
 vinagre_connection_new_from_file (const gchar *uri, gchar **error_msg, gboolean use_bookmarks)
 {
-  GKeyFile          *file;
-  GError            *error;
-  gboolean           loaded;
   VinagreConnection *conn;
-  gchar             *host, *actual_host, *data;
-  gint               port;
-  int                file_size;
+  gchar             *data;
   GFile             *file_a;
-  VinagreConnectionProtocol protocol;
+  GError            *error;
+  GHashTable        *plugins;
+  GHashTableIter     iter;
+  gpointer           plugin;
 
   *error_msg = NULL;
-  host = NULL;
   data = NULL;
   conn = NULL;
   error = NULL;
-  file = NULL;
-  conn = NULL;
 
   file_a = g_file_new_for_commandline_arg (uri);
-  loaded = g_file_load_contents (file_a,
-				 NULL,
-				 &data,
-				 &file_size,
-				 NULL,
-				 &error);
-  if (!loaded)
+  if (!g_file_load_contents (file_a,
+			     NULL,
+			     &data,
+			     NULL,
+			     NULL,
+			     &error));
     {
       if (error)
 	{
@@ -671,72 +642,26 @@ vinagre_connection_new_from_file (const gchar *uri, gchar **error_msg, gboolean
       goto the_end;
     }
 
-  file = g_key_file_new ();
-  loaded = g_key_file_load_from_data (file,
-				      data,
-				      file_size,
-				      0,
-				      &error);
-  if (!loaded)
-    {
-      if (error)
-	{
-	  *error_msg = g_strdup (error->message);
-	  g_error_free (error);
-	}
-      else
-	*error_msg = g_strdup (_("Could not parse the file."));
-
-      goto the_end;
-    }
-
-  host = g_key_file_get_string (file, "connection", "host", NULL);
-  port = g_key_file_get_integer (file, "connection", "port", NULL);
-  if (host)
+  plugins = vinagre_plugin_engine_get_plugins_by_protocol (vinagre_plugins_engine_get_default ());
+  g_hash_table_iter_init (&iter, plugins);
+  while (g_hash_table_iter_next (&iter, NULL, &plugin))
     {
-      if (!port)
-	{
-	  if (!vinagre_connection_split_string (host, &protocol, &actual_host, &port, error_msg))
-	    goto the_end;
-
-	  g_free (host);
-	  host = actual_host;
-	}
-
-      if (use_bookmarks)
-        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 (protocol);
-	  vinagre_connection_set_host (conn, host);
-	  vinagre_connection_set_port (conn, port);
-
-	  username = g_key_file_get_string  (file, "connection", "username", NULL);
-	  vinagre_connection_set_username (conn, username);
-	  g_free (username);
-
-	  password = g_key_file_get_string  (file, "connection", "password", NULL);
-	  vinagre_connection_set_password (conn, password);
-	  g_free (password);
-
-	  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);
+      conn = vinagre_plugin_new_connection_from_file (VINAGRE_PLUGIN (plugin),
+						      data,
+						      use_bookmarks,
+						      error_msg);
+      g_free (*error_msg);
+      *error_msg = NULL;
+      if (conn)
+	break;
     }
-  else
-    *error_msg = g_strdup (_("Could not find the host address in the file."));
 
 the_end:
   g_free (data);
   g_object_unref (file_a);
-  if (file)
-    g_key_file_free (file);
+
+  if (!conn)
+    *error_msg = g_strdup (_("The file was not recognized by any of the plugins."));
 
   return conn;
 }
@@ -748,6 +673,7 @@ vinagre_connection_get_string_rep (VinagreConnection *conn,
   GString *uri;
   gchar *result;
   gboolean is_ipv6;
+  VinagrePlugin *plugin;
 
   g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
 
@@ -755,7 +681,7 @@ vinagre_connection_get_string_rep (VinagreConnection *conn,
 
   if (has_protocol)
     {
-      uri = g_string_new (vinagre_connection_protos [conn->priv->protocol-1]);
+      uri = g_string_new (conn->priv->protocol);
       g_string_append (uri, "://");
     }
   else
@@ -767,8 +693,11 @@ vinagre_connection_get_string_rep (VinagreConnection *conn,
   if (is_ipv6)
     g_string_append_c (uri, ']');
 
-  if (vinagre_connection_default_port [conn->priv->protocol-1] != conn->priv->port)
-    g_string_append_printf (uri, "::%d", conn->priv->port);
+  plugin = g_hash_table_lookup (vinagre_plugin_engine_get_plugins_by_protocol (vinagre_plugins_engine_get_default ()),
+				conn->priv->protocol);
+  if (plugin)
+    if (vinagre_plugin_get_default_port (plugin) != conn->priv->port)
+      g_string_append_printf (uri, "::%d", conn->priv->port);
 
   result = uri->str;
   g_string_free (uri, FALSE);
@@ -776,16 +705,6 @@ 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)
diff --git a/vinagre/vinagre-connection.h b/vinagre/vinagre-connection.h
index 2c92e6a..765f852 100644
--- a/vinagre/vinagre-connection.h
+++ b/vinagre/vinagre-connection.h
@@ -39,13 +39,6 @@ typedef struct _VinagreConnectionClass   VinagreConnectionClass;
 typedef struct _VinagreConnection        VinagreConnection;
 typedef struct _VinagreConnectionPrivate VinagreConnectionPrivate;
 
-typedef enum
-{
-  VINAGRE_CONNECTION_PROTOCOL_VNC = 1,
-  VINAGRE_CONNECTION_PROTOCOL_RDP,
-  VINAGRE_CONNECTION_PROTOCOL_INVALID
-} VinagreConnectionProtocol;
-
 struct _VinagreConnectionClass
 {
   GObjectClass	parent_class;
@@ -66,13 +59,9 @@ struct _VinagreConnection
 
 GType vinagre_connection_get_type (void) G_GNUC_CONST;
 
-VinagreConnection *vinagre_connection_new (VinagreConnectionProtocol protocol);
-VinagreConnectionProtocol vinagre_connection_protocol_by_name (const gchar *protocol);
-
-VinagreConnectionProtocol vinagre_connection_get_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_protocol	(VinagreConnection *conn);
+void		    vinagre_connection_set_protocol	(VinagreConnection *conn,
+							 const gchar       *protocol);
 
 const gchar*	    vinagre_connection_get_host		(VinagreConnection *conn);
 void		    vinagre_connection_set_host		(VinagreConnection *conn,
@@ -102,9 +91,9 @@ VinagreConnection*  vinagre_connection_new_from_string	(const gchar *url, gchar
 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 **protocol,
 							 gchar **host,
-							 gint *port,
+							 gint   *port,
 							 gchar **error_msg);
 
 gchar*		    vinagre_connection_get_string_rep	(VinagreConnection *conn,
diff --git a/vinagre/vinagre-enums.c b/vinagre/vinagre-enums.c
index df69d8b..ec12b80 100644
--- a/vinagre/vinagre-enums.c
+++ b/vinagre/vinagre-enums.c
@@ -5,26 +5,5 @@
 #include "vinagre-enums.h"
 
 
-/* enumerations from "../vinagre/vinagre-connection.h" */
-#include "../vinagre/vinagre-connection.h"
-static const GEnumValue _vinagre_connection_protocol_values[] = {
-  { VINAGRE_CONNECTION_PROTOCOL_VNC, "VINAGRE_CONNECTION_PROTOCOL_VNC", "vnc" },
-  { VINAGRE_CONNECTION_PROTOCOL_RDP, "VINAGRE_CONNECTION_PROTOCOL_RDP", "rdp" },
-  { VINAGRE_CONNECTION_PROTOCOL_INVALID, "VINAGRE_CONNECTION_PROTOCOL_INVALID", "invalid" },
-  { 0, NULL, NULL }
-};
-
-GType
-vinagre_connection_protocol_get_type (void)
-{
-  static GType type = 0;
-
-  if (!type)
-    type = g_enum_register_static ("VinagreConnectionProtocol", _vinagre_connection_protocol_values);
-
-  return type;
-}
-
-
 /* Generated data ends here */
 
diff --git a/vinagre/vinagre-enums.h b/vinagre/vinagre-enums.h
index eb1f3be..8432377 100644
--- a/vinagre/vinagre-enums.h
+++ b/vinagre/vinagre-enums.h
@@ -6,10 +6,6 @@
 
 G_BEGIN_DECLS
 
-
-/* --- ../vinagre/vinagre-connection.h --- */
-#define VINAGRE_TYPE_CONNECTION_PROTOCOL vinagre_connection_protocol_get_type()
-GType vinagre_connection_protocol_get_type (void);
 G_END_DECLS
 
 #endif /* __VINAGRE_ENUMS_H__ */
diff --git a/vinagre/vinagre-plugin.c b/vinagre/vinagre-plugin.c
index 29128e4..8d594cd 100644
--- a/vinagre/vinagre-plugin.c
+++ b/vinagre/vinagre-plugin.c
@@ -38,8 +38,8 @@ typedef struct _VinagrePluginPrivate VinagrePluginPrivate;
 
 struct _VinagrePluginPrivate
 {
-	gchar *install_dir;
-	gchar *data_dir_name;
+  gchar *install_dir;
+  gchar *data_dir_name;
 };
 
 #define VINAGRE_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), VINAGRE_TYPE_PLUGIN, VinagrePluginPrivate))
@@ -64,6 +64,33 @@ default_context_group (VinagrePlugin *plugin)
   return NULL;
 }
 
+static const gchar *
+default_get_protocol (VinagrePlugin *plugin)
+{
+  return NULL;
+}
+
+static VinagreConnection *
+default_new_connection (VinagrePlugin *plugin)
+{
+  return NULL;
+}
+
+static VinagreConnection *
+default_new_connection_from_file (VinagrePlugin *plugin,
+				  const gchar   *data,
+				  gboolean       use_bookmarks,
+				  gchar        **error_msg)
+{
+  return NULL;
+}
+
+static gint
+default_get_default_port (VinagrePlugin *plugin)
+{
+  return -1;
+}
+
 static gboolean
 is_configurable (VinagrePlugin *plugin)
 {
@@ -131,6 +158,10 @@ vinagre_plugin_class_init (VinagrePluginClass *klass)
 	klass->deactivate = dummy;
 	klass->update_ui = dummy;
 	klass->get_context_group = default_context_group;
+	klass->get_protocol = default_get_protocol;
+	klass->get_default_port = default_get_default_port;
+	klass->new_connection = default_new_connection;
+	klass->new_connection_from_file = default_new_connection_from_file;
 	
 	klass->create_configure_dialog = create_configure_dialog;
 	klass->is_configurable = is_configurable;
@@ -343,3 +374,68 @@ vinagre_plugin_get_context_group (VinagrePlugin *plugin)
 	
   return VINAGRE_PLUGIN_GET_CLASS (plugin)->get_context_group (plugin);
 }
+
+/**
+ * vinagre_plugin_get_protocol
+ * @plugin: a #VinagrePlugin
+ *
+ *
+ * Returns: a protocol, like "vnc" or "rdp"
+ */
+const gchar *
+vinagre_plugin_get_protocol (VinagrePlugin *plugin)
+{
+  g_return_val_if_fail (VINAGRE_IS_PLUGIN (plugin), NULL);
+	
+  return VINAGRE_PLUGIN_GET_CLASS (plugin)->get_protocol (plugin);
+}
+
+/**
+ * vinagre_plugin_new_connection
+ * @plugin: a #VinagrePlugin
+ *
+ *
+ * Returns: a subclass of the Connection class
+ */
+VinagreConnection *
+vinagre_plugin_new_connection (VinagrePlugin *plugin)
+{
+  g_return_val_if_fail (VINAGRE_IS_PLUGIN (plugin), NULL);
+	
+  return VINAGRE_PLUGIN_GET_CLASS (plugin)->new_connection (plugin);
+}
+
+/**
+ * vinagre_plugin_new_connection_from_file
+ * @plugin: a #VinagrePlugin
+ *
+ *
+ * Returns: a subclass of the Connection class
+ */
+VinagreConnection *
+vinagre_plugin_new_connection_from_file (VinagrePlugin *plugin,
+					 const gchar   *data,
+					 gboolean       use_bookmarks,
+					 gchar        **error_msg)
+{
+  g_return_val_if_fail (VINAGRE_IS_PLUGIN (plugin), NULL);
+	
+  return VINAGRE_PLUGIN_GET_CLASS (plugin)->new_connection_from_file (plugin, data, use_bookmarks, error_msg);
+}
+
+/**
+ * vinagre_plugin_get_default_port
+ * @plugin: a #VinagrePlugin
+ *
+ *
+ * Returns: the default port (ex: 5900 for vnc)
+ */
+gint
+vinagre_plugin_get_default_port (VinagrePlugin *plugin)
+{
+  g_return_val_if_fail (VINAGRE_IS_PLUGIN (plugin), -1);
+	
+  return VINAGRE_PLUGIN_GET_CLASS (plugin)->get_default_port (plugin);
+}
+
+/* vim: set ts=8: */
diff --git a/vinagre/vinagre-plugin.h b/vinagre/vinagre-plugin.h
index 549cbb1..13bb464 100644
--- a/vinagre/vinagre-plugin.h
+++ b/vinagre/vinagre-plugin.h
@@ -71,7 +71,16 @@ struct _VinagrePluginClass
 
   GtkWidget 	*(*create_configure_dialog)	(VinagrePlugin *plugin);
 
-  GOptionGroup *(*get_context_group)		(VinagrePlugin *plugin);
+
+  /* Virtual methods specific to 'engine' plugins */
+  GOptionGroup	*(*get_context_group)		(VinagrePlugin *plugin);
+  const gchar	*(*get_protocol)		(VinagrePlugin *plugin);
+  gint		(*get_default_port)		(VinagrePlugin *plugin);
+  VinagreConnection *(*new_connection)		(VinagrePlugin *plugin);
+  VinagreConnection *(*new_connection_from_file)(VinagrePlugin *plugin,
+						 const gchar   *data,
+						 gboolean       use_bookmarks,
+						 gchar        **error_msg);
 
   /* Plugins should not override this, it's handled automatically by
      the VinagrePluginClass */
@@ -103,7 +112,14 @@ void 		 vinagre_plugin_update_ui		(VinagrePlugin *plugin,
 gboolean	 vinagre_plugin_is_configurable		(VinagrePlugin *plugin);
 GtkWidget	*vinagre_plugin_create_configure_dialog	(VinagrePlugin *plugin);
 
-GOptionGroup *	 vinagre_plugin_get_context_group	(VinagrePlugin *plugin);
+GOptionGroup	*vinagre_plugin_get_context_group	(VinagrePlugin *plugin);
+const gchar	*vinagre_plugin_get_protocol		(VinagrePlugin *plugin);
+gint		 vinagre_plugin_get_default_port	(VinagrePlugin *plugin);
+VinagreConnection *vinagre_plugin_new_connection	(VinagrePlugin *plugin);
+VinagreConnection *vinagre_plugin_new_connection_from_file (VinagrePlugin *plugin,
+							    const gchar   *data,
+							    gboolean       use_bookmarks,
+							    gchar        **error_msg);
 
 /**
  * VINAGRE_PLUGIN_REGISTER_TYPE_WITH_CODE(PluginName, plugin_name, CODE):
diff --git a/vinagre/vinagre-plugins-engine.c b/vinagre/vinagre-plugins-engine.c
index 6582a10..5ca4a85 100644
--- a/vinagre/vinagre-plugins-engine.c
+++ b/vinagre/vinagre-plugins-engine.c
@@ -63,6 +63,7 @@ struct _VinagrePluginsEnginePrivate
 {
   GSList *plugin_list;
   GHashTable *loaders;
+  GHashTable *protocols;
 
   gboolean activate_from_prefs;
 };
@@ -274,31 +275,32 @@ activate_engine_plugins (VinagrePluginsEngine *engine)
 static void
 vinagre_plugins_engine_init (VinagrePluginsEngine *engine)
 {
-	vinagre_debug (DEBUG_PLUGINS);
+  vinagre_debug (DEBUG_PLUGINS);
 
-	if (!g_module_supported ())
-	{
-		g_warning ("vinagre is not able to initialize the plugins engine.");
-		return;
-	}
+  if (!g_module_supported ())
+    {
+      g_warning ("vinagre is not able to initialize the plugins engine.");
+      return;
+    }
 
-	engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine,
-						    VINAGRE_TYPE_PLUGINS_ENGINE,
-						    VinagrePluginsEnginePrivate);
+  engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine,
+					      VINAGRE_TYPE_PLUGINS_ENGINE,
+					      VinagrePluginsEnginePrivate);
 
-	load_all_plugins (engine);
+  load_all_plugins (engine);
 
-	/* make sure that the first reactivation will read active plugins
-	   from the prefs */
-	engine->priv->activate_from_prefs = TRUE;
+  /* make sure that the first reactivation will read active plugins
+     from the prefs */
+  engine->priv->activate_from_prefs = TRUE;
 
-	/* mapping from loadername -> loader object */
-	engine->priv->loaders = g_hash_table_new_full (hash_lowercase,
-						       equal_lowercase,
-						       (GDestroyNotify)g_free,
-						       (GDestroyNotify)loader_destroy);
+  /* mapping from loadername -> loader object */
+  engine->priv->loaders = g_hash_table_new_full (hash_lowercase,
+						 equal_lowercase,
+						 (GDestroyNotify)g_free,
+						 (GDestroyNotify)loader_destroy);
 
-	activate_engine_plugins (engine);
+  engine->priv->protocols = g_hash_table_new (g_str_hash, g_str_equal);
+  activate_engine_plugins (engine);
 }
 
 static void
@@ -337,6 +339,8 @@ vinagre_plugins_engine_finalize (GObject *object)
 	/* unref the loaders */	
 	g_hash_table_destroy (engine->priv->loaders);
 
+	g_hash_table_destroy (engine->priv->protocols);
+
 	/* and finally free the infos */
 	for (item = engine->priv->plugin_list; item; item = item->next)
 	{
@@ -598,13 +602,26 @@ vinagre_plugins_engine_activate_plugin_real (VinagrePluginsEngine *engine,
 					     VinagrePluginInfo    *info)
 {
   const GList *wins;
+  const gchar *protocol;
+  VinagrePluginInfo *plugin_protocol;
 
   if (!load_plugin (engine, info))
     return;
 
   if (vinagre_plugin_info_is_engine (info))
     {
+      protocol = vinagre_plugin_get_protocol (info->plugin);
+      plugin_protocol = g_hash_table_lookup (engine->priv->protocols, protocol);
+      if (plugin_protocol)
+	{
+	  g_warning ("The protocol %s was already registered by the plugin %s",
+		     protocol,
+		     vinagre_plugin_info_get_name (plugin_protocol));
+	  return;
+	}
+
       vinagre_plugin_activate (info->plugin, NULL);
+      g_hash_table_insert (engine->priv->protocols, (gpointer)protocol, info->plugin);
       return;
     }
 
@@ -660,9 +677,18 @@ vinagre_plugins_engine_deactivate_plugin_real (VinagrePluginsEngine *engine,
       !vinagre_plugin_info_is_available (info))
     return;
 
-  wins = vinagre_app_get_windows (vinagre_app_get_default ());
-  for (; wins != NULL; wins = wins->next)
-    call_plugin_deactivate (info->plugin, VINAGRE_WINDOW (wins->data));
+  if (vinagre_plugin_info_is_engine (info))
+    {
+      g_hash_table_remove (engine->priv->protocols,
+			   vinagre_plugin_get_protocol (info->plugin));
+      vinagre_plugin_deactivate (info->plugin, NULL);
+    }
+  else
+    {
+      wins = vinagre_app_get_windows (vinagre_app_get_default ());
+      for (; wins != NULL; wins = wins->next)
+	call_plugin_deactivate (info->plugin, VINAGRE_WINDOW (wins->data));
+    }
 
   /* first unref the plugin (the loader still has one) */
   g_object_unref (info->plugin);
@@ -867,4 +893,11 @@ vinagre_plugins_engine_rescan_plugins (VinagrePluginsEngine *engine)
 	
 	load_all_plugins (engine);
 }
+
+GHashTable *
+vinagre_plugin_engine_get_plugins_by_protocol (VinagrePluginsEngine *engine)
+{
+  return engine->priv->protocols;
+}
+
 /* vim: set ts=8: */
diff --git a/vinagre/vinagre-plugins-engine.h b/vinagre/vinagre-plugins-engine.h
index fd89946..96f5a9b 100644
--- a/vinagre/vinagre-plugins-engine.h
+++ b/vinagre/vinagre-plugins-engine.h
@@ -22,9 +22,10 @@
 #define __VINAGRE_PLUGINS_ENGINE_H__
 
 #include <glib.h>
-#include "vinagre-window.h"
-#include "vinagre-plugin-info.h"
-#include "vinagre-plugin.h"
+#include <vinagre/vinagre-window.h>
+#include <vinagre/vinagre-plugin-info.h>
+#include <vinagre/vinagre-plugin.h>
+#include <vinagre/vinagre-connection.h>
 
 G_BEGIN_DECLS
 
@@ -69,27 +70,29 @@ VinagrePluginInfo	*vinagre_plugins_engine_get_plugin_info		(VinagrePluginsEngine
 									 const gchar        *name);
 
 /* plugin load and unloading (overall, for all windows) */
-gboolean 	 vinagre_plugins_engine_activate_plugin 	(VinagrePluginsEngine *engine,
-								 VinagrePluginInfo    *info);
-gboolean 	 vinagre_plugins_engine_deactivate_plugin	(VinagrePluginsEngine *engine,
-								 VinagrePluginInfo    *info);
+gboolean 		 vinagre_plugins_engine_activate_plugin 	(VinagrePluginsEngine *engine,
+									 VinagrePluginInfo    *info);
+gboolean 		 vinagre_plugins_engine_deactivate_plugin	(VinagrePluginsEngine *engine,
+									 VinagrePluginInfo    *info);
 
-void	 	 vinagre_plugins_engine_configure_plugin	(VinagrePluginsEngine *engine,
-								 VinagrePluginInfo    *info,
-								 GtkWindow            *parent);
+void		 	 vinagre_plugins_engine_configure_plugin	(VinagrePluginsEngine *engine,
+									 VinagrePluginInfo    *info,
+									 GtkWindow            *parent);
 
 /* plugin activation/deactivation per window, private to VinagreWindow */
-void 		 vinagre_plugins_engine_activate_plugins 	 (VinagrePluginsEngine *engine,
-								  VinagreWindow        *window);
-void 		 vinagre_plugins_engine_deactivate_plugins	 (VinagrePluginsEngine *engine,
-								  VinagreWindow        *window);
-void		 vinagre_plugins_engine_update_plugins_ui	 (VinagrePluginsEngine *engine,
-								  VinagreWindow        *window);
+void 			 vinagre_plugins_engine_activate_plugins 	 (VinagrePluginsEngine *engine,
+									  VinagreWindow        *window);
+void 			 vinagre_plugins_engine_deactivate_plugins	 (VinagrePluginsEngine *engine,
+									  VinagreWindow        *window);
+void			 vinagre_plugins_engine_update_plugins_ui	 (VinagrePluginsEngine *engine,
+									  VinagreWindow        *window);
 
 /* private for gconf notification */
-void		 vinagre_plugins_engine_active_plugins_changed	(VinagrePluginsEngine *engine);
+void			 vinagre_plugins_engine_active_plugins_changed	(VinagrePluginsEngine *engine);
 
-void		 vinagre_plugins_engine_rescan_plugins		(VinagrePluginsEngine *engine);
+void			 vinagre_plugins_engine_rescan_plugins		(VinagrePluginsEngine *engine);
+
+GHashTable		*vinagre_plugin_engine_get_plugins_by_protocol	(VinagrePluginsEngine *engine);
 
 G_END_DECLS
 



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