gedit r6528 - in branches/new_plugins/gedit: . dbus



Author: jessevdk
Date: Thu Sep 11 18:22:45 2008
New Revision: 6528
URL: http://svn.gnome.org/viewvc/gedit?rev=6528&view=rev

Log:
Replaced bacon connection with proper dbus one. The dbus connection uses the gedit message
system and the before implemented dbus glue to send a open/present/new_document message over
dbus. A standalone option is also added which runs gedit as a standalone process. Other
reasons for gedit to run standalone are: error initializing dbus, error initializing dbus
service


Removed:
   branches/new_plugins/gedit/bacon-message-connection.c
   branches/new_plugins/gedit/bacon-message-connection.h
   branches/new_plugins/gedit/update-from-bacon.sh
Modified:
   branches/new_plugins/gedit/Makefile.am
   branches/new_plugins/gedit/dbus/gedit-dbus.c
   branches/new_plugins/gedit/dbus/gedit-dbus.h
   branches/new_plugins/gedit/gedit-commands-messages.c
   branches/new_plugins/gedit/gedit-message.c
   branches/new_plugins/gedit/gedit-message.h
   branches/new_plugins/gedit/gedit.c

Modified: branches/new_plugins/gedit/Makefile.am
==============================================================================
--- branches/new_plugins/gedit/Makefile.am	(original)
+++ branches/new_plugins/gedit/Makefile.am	Thu Sep 11 18:22:45 2008
@@ -110,7 +110,6 @@
 
 libgedit_la_SOURCES = 			\
 	$(BUILT_SOURCES)		\
-	$(BACON_FILES)			\
 	gedit-app.c			\
 	gedit-commands-documents.c	\
 	gedit-commands-edit.c		\
@@ -199,8 +198,3 @@
 	rm -f $(DESTDIR)$(bindir)/gnome-text-editor
 	ln -s gedit $(DESTDIR)$(bindir)/gnome-text-editor
 
-BACON_DIR=$(srcdir)/../../libbacon/src/
-BACON_FILES=bacon-message-connection.h bacon-message-connection.c
-
-regenerate-built-sources:
-	BACONFILES="$(BACON_FILES)" BACONDIR="$(BACON_DIR)" $(top_srcdir)/gedit/update-from-bacon.sh

Modified: branches/new_plugins/gedit/dbus/gedit-dbus.c
==============================================================================
--- branches/new_plugins/gedit/dbus/gedit-dbus.c	(original)
+++ branches/new_plugins/gedit/dbus/gedit-dbus.c	Thu Sep 11 18:22:45 2008
@@ -98,22 +98,20 @@
 }
 
 gboolean
-gedit_dbus_initialize ()
+gedit_dbus_initialize (GError **error)
 {
-	GError *error = NULL;
 	DBusGProxy *bus_proxy;
 	DBusGConnection *gbus;
 	guint request_name_result;
 	GeditMessageBus *bus;
 	
-	gbus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	if (error)
+		*error = NULL;
+	
+	gbus = dbus_g_bus_get (DBUS_BUS_SESSION, error);
 	
 	if (!gbus)
-	{
-		g_warning ("Could not connect to session bus: %s", error->message);
-		g_error_free (error);
 		return FALSE;
-	}
 
 	/* Register unique name */
 	bus_proxy = dbus_g_proxy_new_for_name (gbus, 
@@ -121,20 +119,23 @@
 					       "/org/freedesktop/DBus",
 					       "org.freedesktop.DBus");
 	
-	if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error,
-			  G_TYPE_STRING, "org.gnome.gedit",
-			  G_TYPE_UINT, 0,
-			  G_TYPE_INVALID,
-			  G_TYPE_UINT, &request_name_result,
-			  G_TYPE_INVALID))
+	if (!dbus_g_proxy_call (bus_proxy, "RequestName", error,
+			  	G_TYPE_STRING, "org.gnome.gedit",
+			  	G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
+			  	G_TYPE_INVALID,
+			  	G_TYPE_UINT, &request_name_result,
+			  	G_TYPE_INVALID))
 	{
-		g_warning ("Failed to get name for connection: %s:", error->message);
-		g_error_free (error);
 		return FALSE;
 	}
 	
-	/* FIXME: check return value and do something when we are queued etc */
-	
+	if (request_name_result == DBUS_REQUEST_NAME_REPLY_EXISTS)
+	{
+		/* there is already a master gedit process */
+		return FALSE;
+	}
+
+	/* we are the master gedit process */	
 	dbus_g_connection_register_g_object (gbus, "/org/gnome/gedit", g_object_new (GEDIT_TYPE_DBUS, NULL));
 		
 	/* CHECK: maybe add a reference to the bus? */

Modified: branches/new_plugins/gedit/dbus/gedit-dbus.h
==============================================================================
--- branches/new_plugins/gedit/dbus/gedit-dbus.h	(original)
+++ branches/new_plugins/gedit/dbus/gedit-dbus.h	Thu Sep 11 18:22:45 2008
@@ -43,7 +43,7 @@
 			       GHashTable            *message,
 			       DBusGMethodInvocation *invocation);
 
-gboolean gedit_dbus_initialize (void);
+gboolean gedit_dbus_initialize (GError **error);
 
 G_END_DECLS
 

Modified: branches/new_plugins/gedit/gedit-commands-messages.c
==============================================================================
--- branches/new_plugins/gedit/gedit-commands-messages.c	(original)
+++ branches/new_plugins/gedit/gedit-commands-messages.c	Thu Sep 11 18:22:45 2008
@@ -55,21 +55,12 @@
 	return display != NULL ? display : gdk_display_open (name);
 }
 
-static void
-on_message_commands_open (GeditMessageBus *bus, 
-			  GeditMessage    *message,
-			  gpointer         userdata)
+static GeditWindow *
+get_window_from_message (GeditMessage *message)
 {
-	GStrv uris = NULL;
-	gchar *encoding_charset = NULL;
-	gint line_position = 0;
 	gboolean new_window = FALSE;
-	const GeditEncoding *encoding = NULL;
-	GeditWindow *window;
 	GeditApp *app;
-	GSList *uri_list = NULL;
-	GStrv ptr;
-	guint32 startup_timestamp = 0;
+	const gchar *invalid_key;
 	
 	/* optional parameters, used to specify correct workspace/viewport */
 	GdkScreen *screen = NULL;
@@ -79,31 +70,21 @@
 	gint viewport_y = -1;
 	gchar *display_name = NULL;
 
-	gedit_message_get (message,
-			   "uris", &uris,
-			   "encoding", &encoding_charset,
-			   "line_position", &line_position,
-			   "new_window", &new_window,
-			   "screen_number", &screen_number,
-			   "workspace", &workspace,
-			   "viewport_x", &viewport_x,
-			   "viewport_y", &viewport_y,
-			   "display_name", &display_name,
-			   "startup_timestamp", &startup_timestamp,
-			   NULL);
-
-	if (uris == NULL)
-		return;
-	
-	if (*uris == NULL)
+	if (!gedit_message_get_type_safe (message,
+				          &invalid_key,
+				          "new_window", G_TYPE_BOOLEAN, &new_window,
+				          "screen_number", G_TYPE_INT, &screen_number,
+				          "workspace", G_TYPE_INT, &workspace,
+				          "viewport_x", G_TYPE_INT, &viewport_x,
+				          "viewport_y", G_TYPE_INT, &viewport_y,
+				          "display_name", G_TYPE_STRING, &display_name,
+				          NULL))
 	{
-		g_strfreev (uris);
-		return;
+		g_warning ("Message contains invalid value for key `%s'", invalid_key);
+		g_free (display_name);
+		return NULL;
 	}
 
-	if (encoding_charset != NULL)
-		encoding = gedit_encoding_get_from_charset (encoding_charset);
-
 	app = gedit_app_get_default ();
 	
 	/* get correct screen using the display_name and screen_number */
@@ -116,15 +97,101 @@
 	}
 	
 	if (new_window)
-		window = gedit_app_create_window (app, screen);
+		return gedit_app_create_window (app, screen);
 	else if (screen != NULL)
-		window = _gedit_app_get_window_in_viewport (app,
-							    screen,
-							    workspace == -1 ? 0 : workspace,
-							    viewport_x == -1 ? 0 : viewport_x,
-							    viewport_y == -1 ? 0 : viewport_y);
+		return _gedit_app_get_window_in_viewport (app,
+							  screen,
+							  workspace == -1 ? 0 : workspace,
+							  viewport_x == -1 ? 0 : viewport_x,
+							  viewport_y == -1 ? 0 : viewport_y);
 	else
-		window = gedit_app_get_active_window (app);
+		return gedit_app_get_active_window (app);
+}
+
+static void
+set_interaction_time_and_present (GeditWindow *window,
+				  guint32      startup_timestamp)
+{
+	/* set the proper interaction time on the window.
+	 * Fall back to roundtripping to the X server when we
+	 * don't have the timestamp, e.g. when launched from
+	 * terminal. We also need to make sure that the window
+	 * has been realized otherwise it will not work. lame.
+	 */
+	if (!GTK_WIDGET_REALIZED (window))
+		gtk_widget_realize (GTK_WIDGET (window));
+
+	if (startup_timestamp <= 0)
+		startup_timestamp = gdk_x11_get_server_time (GTK_WIDGET (window)->window);
+
+	gdk_x11_window_set_user_time (GTK_WIDGET (window)->window,
+				      startup_timestamp);
+
+	gtk_window_present (GTK_WINDOW (window));
+}
+
+static void
+on_message_commands_open (GeditMessageBus *bus, 
+			  GeditMessage    *message,
+			  gpointer         userdata)
+{
+	GStrv uris = NULL;
+	gchar *encoding_charset = NULL;
+	gint line_position = 0;
+	const GeditEncoding *encoding = NULL;
+	GSList *uri_list = NULL;
+	const gchar *invalid_key;
+	GStrv ptr;
+	guint32 startup_timestamp = 0;
+	GeditWindow *window;
+
+	if (gedit_message_has_key (message, "uris") && 
+	    gedit_message_type_check (message, NULL, G_TYPE_STRV, "uris", NULL))
+	{
+		/* good, this is what we want, list of uris */
+		gedit_message_get (message, "uris", &uris, NULL);
+		
+	}
+	else if (gedit_message_has_key (message, "uri") &&
+	         gedit_message_type_check (message, NULL, G_TYPE_STRING, "uri", NULL))
+	{
+		/* single uri is also supported, we put it in uris */
+		uris = g_new0 (gchar *, 2);
+		gedit_message_get (message, "uri", uris, NULL);
+	}
+	
+	/* check if we got at least one uri */
+	if (uris == NULL || *uris == NULL)
+	{
+		g_strfreev (uris);
+		return;
+	}
+	
+	window = get_window_from_message (message);
+	
+	if (window == NULL)
+	{
+		g_strfreev (uris);
+		return;
+	}
+	
+	/* get all the other parameters */
+	if (!gedit_message_get_type_safe (message,
+				          &invalid_key,
+				          "encoding", G_TYPE_STRING, &encoding_charset,
+				          "line_position", G_TYPE_INT, &line_position,
+				          "startup_timestamp", G_TYPE_UINT, &startup_timestamp,
+				          NULL))
+	{
+		g_warning ("Message commands.open contains invalid value for key `%s'", invalid_key);
+
+		g_strfreev (uris);
+		g_free (encoding_charset);
+		return;
+	}
+
+	if (encoding_charset != NULL)
+		encoding = gedit_encoding_get_from_charset (encoding_charset);
 
 	ptr = uris;
 	
@@ -144,22 +211,91 @@
 	 * terminal. We also need to make sure that the window
 	 * has been realized otherwise it will not work. lame.
 	 */
-	if (!GTK_WIDGET_REALIZED (window))
-		gtk_widget_realize (GTK_WIDGET (window));
-
-	if (startup_timestamp <= 0)
-		startup_timestamp = gdk_x11_get_server_time (GTK_WIDGET (window)->window);
-
-	gdk_x11_window_set_user_time (GTK_WIDGET (window)->window,
-				      startup_timestamp);
-
-	gtk_window_present (GTK_WINDOW (window));
+	set_interaction_time_and_present (window, startup_timestamp);
 
 	g_strfreev (uris);
 	g_free (encoding_charset);
+
 	g_slist_free (uri_list);
 }
 
+static void
+on_message_commands_new_document (GeditMessageBus *bus,
+				  GeditMessage    *message,
+				  gpointer         userdata)
+{
+	GeditWindow *window;
+	const gchar *invalid_key;
+	guint32 startup_timestamp = 0;
+	
+	window = get_window_from_message (message);
+	
+	if (window == NULL)
+		return;
+
+	if (!gedit_message_get_type_safe (message,
+				          &invalid_key,
+				          "startup_timestamp", G_TYPE_UINT, &startup_timestamp,
+				          NULL))
+	{
+		g_warning ("Message contains invalid value for key `%s'", invalid_key);
+		return;
+	}
+	
+	gedit_window_create_tab (window, TRUE);
+	
+	/* set the proper interaction time on the window.
+	 * Fall back to roundtripping to the X server when we
+	 * don't have the timestamp, e.g. when launched from
+	 * terminal. We also need to make sure that the window
+	 * has been realized otherwise it will not work. lame.
+	 */
+	set_interaction_time_and_present (window, startup_timestamp);
+}
+
+static void
+on_message_commands_present (GeditMessageBus *bus,
+			     GeditMessage    *message,
+			     gpointer         userdata)
+{
+	GeditWindow *window;
+	const gchar *invalid_key;
+	guint32 startup_timestamp = 0;
+	gboolean new_document = FALSE;
+	GeditDocument *doc;
+
+	window = get_window_from_message (message);
+	
+	if (window == NULL)
+		return;
+
+	if (!gedit_message_get_type_safe (message,
+				          &invalid_key,
+				          "new_document", G_TYPE_BOOLEAN, &new_document,
+				          "startup_timestamp", G_TYPE_UINT, &startup_timestamp,
+				          NULL))
+	{
+		g_warning ("Message contains invalid value for key `%s'", invalid_key);
+		return;
+	}
+	
+	
+	doc = gedit_window_get_active_document (window);
+
+	if (doc == NULL ||
+	    !gedit_document_is_untouched (doc) ||
+	    new_document)
+		gedit_window_create_tab (window, TRUE);
+	
+	/* set the proper interaction time on the window.
+	 * Fall back to roundtripping to the X server when we
+	 * don't have the timestamp, e.g. when launched from
+	 * terminal. We also need to make sure that the window
+	 * has been realized otherwise it will not work. lame.
+	 */
+	set_interaction_time_and_present (window, startup_timestamp);
+}
+
 void
 _gedit_commands_messages_register ()
 {
@@ -168,5 +304,18 @@
 	/* register message handlers on the message bus */
 	bus = gedit_message_bus_get_default ();
 	
-	BUS_CONNECT ("commands", "open", on_message_commands_open);
+	/* open list of uris, or single uri */
+	BUS_CONNECT ("core", "open", on_message_commands_open);
+	
+	/* alias "open_uris", "open_uri", "load", "load_uris", "load_uri" */
+	BUS_CONNECT ("core", "open_uris", on_message_commands_open);
+	BUS_CONNECT ("core", "open_uri", on_message_commands_open);
+	BUS_CONNECT ("core", "load", on_message_commands_open);
+	BUS_CONNECT ("core", "load_uris", on_message_commands_open);
+	BUS_CONNECT ("core", "load_uri", on_message_commands_open);
+	
+	/* new document message, used by gedit startup */
+	BUS_CONNECT ("core", "new_document", on_message_commands_new_document);
+	
+	BUS_CONNECT ("core", "present", on_message_commands_present);
 }

Modified: branches/new_plugins/gedit/gedit-message.c
==============================================================================
--- branches/new_plugins/gedit/gedit-message.c	(original)
+++ branches/new_plugins/gedit/gedit-message.c	Thu Sep 11 18:22:45 2008
@@ -576,3 +576,104 @@
 	
 	return container != NULL;
 }
+
+gboolean
+gedit_message_type_check (GeditMessage  *message,
+			  const gchar  **invalid_key,
+			  ...)
+{
+	const gchar *key;
+	va_list var_args;
+	gboolean ret = TRUE;
+	
+	g_return_val_if_fail (GEDIT_IS_MESSAGE (message), FALSE);
+	va_start (var_args, invalid_key);
+
+	while ((key = va_arg (var_args, const gchar *)) != NULL)
+	{
+		/* lookup the key */
+		GValue *container = value_lookup (message, key);
+		GType gtype;
+		
+		if (!container)
+		{
+			/* skip type */
+			va_arg (var_args, gpointer);
+			continue;
+		}
+		
+		gtype = va_arg (var_args, GType);
+		
+		if (!g_type_is_a (G_VALUE_TYPE (container), gtype) && 
+		    !g_value_type_transformable (G_VALUE_TYPE (container), gtype))
+		{
+			if (invalid_key)
+				*invalid_key = key;
+
+			ret = FALSE;
+			break;
+		}
+	}
+
+	va_end (var_args);
+	return ret;
+}
+
+gboolean
+gedit_message_get_type_safe (GeditMessage  *message,
+			     const gchar  **invalid_key,
+			     ...)
+{
+	const gchar *key;
+	va_list var_args;
+	gboolean ret = TRUE;
+	
+	g_return_val_if_fail (GEDIT_IS_MESSAGE (message), FALSE);
+	va_start (var_args, invalid_key);
+
+	while ((key = va_arg (var_args, const gchar *)) != NULL)
+	{
+		/* lookup the key */
+		GValue *container = value_lookup (message, key);
+		GType gtype;
+		GValue value = {0,};
+		gchar *error = NULL;
+		
+		if (!container)
+		{
+			/* skip type and container */
+			va_arg (var_args, gpointer);
+			va_arg (var_args, gpointer);
+			continue;
+		}
+		
+		gtype = va_arg (var_args, GType);
+		g_value_init (&value, gtype);
+
+		if (!set_value_real (&value, container))
+		{
+			if (invalid_key)
+				*invalid_key = key;
+
+			ret = FALSE;
+			break;
+		}
+		
+		G_VALUE_LCOPY (&value, var_args, 0, &error);
+		
+		if (error != NULL)
+		{
+			if (invalid_key)
+				*invalid_key = key;
+			
+			ret = FALSE;
+			g_free (error);
+			break;
+		}
+		
+		g_value_unset (&value);
+	}
+	
+	va_end (var_args);
+	return ret;
+}

Modified: branches/new_plugins/gedit/gedit-message.h
==============================================================================
--- branches/new_plugins/gedit/gedit-message.h	(original)
+++ branches/new_plugins/gedit/gedit-message.h	Thu Sep 11 18:22:45 2008
@@ -76,6 +76,12 @@
 					 const gchar	 *key);
 
 GHashTable *gedit_message_get_hash	(GeditMessage	 *message);
+gboolean gedit_message_type_check	(GeditMessage	 *message,
+					 const gchar    **invalid_key,
+					 ...) G_GNUC_NULL_TERMINATED;
+gboolean gedit_message_get_type_safe	(GeditMessage	 *message,
+					 const gchar   **invalid_key,
+					 ...) G_GNUC_NULL_TERMINATED;
 
 G_END_DECLS
 

Modified: branches/new_plugins/gedit/gedit.c
==============================================================================
--- branches/new_plugins/gedit/gedit.c	(original)
+++ branches/new_plugins/gedit/gedit.c	Thu Sep 11 18:22:45 2008
@@ -52,7 +52,6 @@
 #include "gedit-utils.h"
 #include "gedit-window.h"
 
-#include "bacon-message-connection.h"
 #include "eggsmclient.h"
 #include "gedit-message-bus.h"
 
@@ -60,17 +59,12 @@
 #include "dbus/gedit-dbus.h"
 #endif
 
-static guint32 startup_timestamp = 0;
-static BaconMessageConnection *connection;
-
 /* command line */
-static gint line_position = 0;
 static gchar *encoding_charset = NULL;
-static const GeditEncoding *encoding;
 static gboolean new_window_option = FALSE;
 static gboolean new_document_option = FALSE;
 static gchar **remaining_args = NULL;
-static GSList *file_list = NULL;
+static gboolean standalone_option = FALSE;
 
 static const GOptionEntry options [] =
 {
@@ -83,6 +77,9 @@
 	{ "new-document", '\0', 0, G_OPTION_ARG_NONE, &new_document_option,
 	  N_("Create a new document in an existing instance of gedit"), NULL },
 
+	{ "standalone", '\0', 0, G_OPTION_ARG_NONE, &standalone_option,
+	  N_("Start gedit as a separate standalone process"), NULL },
+
 	{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &remaining_args,
 	  NULL, N_("[FILE...]") }, /* collects file arguments */
 
@@ -90,50 +87,43 @@
 };
 
 static void
-gedit_get_command_line_data (void)
+gedit_get_command_line_data (GSList **files,
+			     gint    *line_position)
 {
-	if (remaining_args)
-	{
-		gint i;
+	gint i;
+
+	*files = NULL;
+	*line_position = 0;
 
-		for (i = 0; remaining_args[i]; i++) 
+	if (!remaining_args)
+		return;
+
+	for (i = 0; remaining_args[i]; i++) 
+	{
+		if (*remaining_args[i] == '+')
 		{
-			if (*remaining_args[i] == '+')
-			{
-				if (*(remaining_args[i] + 1) == '\0')
-					/* goto the last line of the document */
-					line_position = G_MAXINT;
-				else
-					line_position = atoi (remaining_args[i] + 1);
-			}
+			if (*(remaining_args[i] + 1) == '\0')
+				/* goto the last line of the document */
+				*line_position = G_MAXINT;
 			else
-			{
-				gchar *canonical_uri;
-				
-				canonical_uri = gedit_utils_make_canonical_uri_from_shell_arg (remaining_args[i]);
-				
-				if (canonical_uri != NULL)
-					file_list = g_slist_prepend (file_list, 
-								     canonical_uri);
-				else
-					g_print (_("%s: malformed file name or URI.\n"),
-						 remaining_args[i]);
-			} 
+				*line_position = atoi (remaining_args[i] + 1);
 		}
-
-		file_list = g_slist_reverse (file_list);
+		else
+		{
+			gchar *canonical_uri;
+			
+			canonical_uri = gedit_utils_make_canonical_uri_from_shell_arg (remaining_args[i]);
+			
+			if (canonical_uri != NULL)
+				*files = g_slist_prepend (*files, 
+							  canonical_uri);
+			else
+				g_print (_("%s: malformed file name or URI.\n"),
+					 remaining_args[i]);
+		} 
 	}
 
-	if (encoding_charset)
-	{
-		encoding = gedit_encoding_get_from_charset (encoding_charset);
-		if (encoding == NULL)
-			g_print (_("%s: invalid encoding.\n"),
-				 encoding_charset);
-
-		g_free (encoding_charset);
-		encoding_charset = NULL;
-	}
+	*files = g_slist_reverse (*files);
 }
 
 static guint32
@@ -172,276 +162,136 @@
 	return (retval > 0) ? retval : 0;
 }
 
-static GdkDisplay *
-display_open_if_needed (const gchar *name)
-{
-	GSList *displays;
-	GSList *l;
-	GdkDisplay *display = NULL;
-
-	displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
-
-	for (l = displays; l != NULL; l = l->next)
-	{
-		if (strcmp (gdk_display_get_name ((GdkDisplay *) l->data), name) == 0)
-		{
-			display = l->data;
-			break;
-		}
-	}
-
-	g_slist_free (displays);
-
-	return display != NULL ? display : gdk_display_open (name);
-}
-
-/* serverside */
-static void
-on_message_received (const char *message,
-		     gpointer    data)
-{
-	gchar **commands;
-	gchar **params;
-	gint workspace;
-	gint viewport_x;
-	gint viewport_y;
-	gchar *display_name;
-	gint screen_number;
-	gint i;
-	GeditApp *app;
-	GeditWindow *window;
-	GdkDisplay *display;
-	GdkScreen *screen;
-
-	g_return_if_fail (message != NULL);
-
-	gedit_debug_message (DEBUG_APP, "Received message:\n%s\n", message);
-
-	commands = g_strsplit (message, "\v", -1);
-
-	/* header */
-	params = g_strsplit (commands[0], "\t", 6);
-	startup_timestamp = atoi (params[0]);
-	display_name = params[1];
-	screen_number = atoi (params[2]);
-	workspace = atoi (params[3]);
-	viewport_x = atoi (params[4]);
-	viewport_y = atoi (params[5]);
-
-	display = display_open_if_needed (display_name);
-	if (display == NULL)
-	{
-		g_warning ("Could not open display %s\n", display_name);
-		g_strfreev (params);
-		goto out;
-	}
-
-	screen = gdk_display_get_screen (display, screen_number);
-
-	g_strfreev (params);
-
-	/* body */
-	for (i = 1; commands[i] != NULL; i++)
-	{
-		params = g_strsplit (commands[i], "\t", -1);
-
-		if (strcmp (params[0], "NEW-WINDOW") == 0)
-		{
-			new_window_option = TRUE;
-		}
-		else if (strcmp (params[0], "NEW-DOCUMENT") == 0)
-		{
-			new_document_option = TRUE;
-		}
-		else if (strcmp (params[0], "OPEN-URIS") == 0)
-		{
-			gint n_uris, j;
-			gchar **uris;
-
-			line_position = atoi (params[1]);
-			if (params[2] != '\0');
-				encoding = gedit_encoding_get_from_charset (params[2]);
-
-			n_uris = atoi (params[3]);
-			uris = g_strsplit (params[4], " ", n_uris);
-
-			for (j = 0; j < n_uris; j++)
-				file_list = g_slist_prepend (file_list, uris[j]);
-			file_list = g_slist_reverse (file_list);
-
-			/* the list takes ownerhip of the strings,
-			 * only free the array */
-			g_free (uris);
-		}
-		else
-		{
-			g_warning ("Unexpected bacon command");
-		}
-
-		g_strfreev (params);
-	}
-
-	/* execute the commands */
-
-	app = gedit_app_get_default ();
-
-	if (new_window_option)
-	{
-		window = gedit_app_create_window (app, screen);
-	}
-	else
-	{
-		/* get a window in the current workspace (if exists) and raise it */
-		window = _gedit_app_get_window_in_viewport (app,
-							    screen,
-							    workspace,
-							    viewport_x,
-							    viewport_y);
-	}
-
-	if (file_list != NULL)
-	{
-		_gedit_cmd_load_files_from_prompt (window,
-						   file_list,
-						   encoding,
-						   line_position);
-
-		if (new_document_option)
-			gedit_window_create_tab (window, TRUE);
-	}
-	else
-	{
-		GeditDocument *doc;
-		doc = gedit_window_get_active_document (window);
-
-		if (doc == NULL ||
-		    !gedit_document_is_untouched (doc) ||
-		    new_document_option)
-			gedit_window_create_tab (window, TRUE);
-	}
-
-	/* set the proper interaction time on the window.
-	 * Fall back to roundtripping to the X server when we
-	 * don't have the timestamp, e.g. when launched from
-	 * terminal. We also need to make sure that the window
-	 * has been realized otherwise it will not work. lame.
-	 */
-	if (!GTK_WIDGET_REALIZED (window))
-		gtk_widget_realize (GTK_WIDGET (window));
-
-	if (startup_timestamp <= 0)
-		startup_timestamp = gdk_x11_get_server_time (GTK_WIDGET (window)->window);
-
-	gdk_x11_window_set_user_time (GTK_WIDGET (window)->window,
-				      startup_timestamp);
-
-	gtk_window_present (GTK_WINDOW (window));
-
-	/* free the file list and reset to default */
-	g_slist_foreach (file_list, (GFunc) g_free, NULL);
-	g_slist_free (file_list);
-	file_list = NULL;
-
- out:
-	g_strfreev (commands);
-
-	new_window_option = FALSE;
-	new_document_option = FALSE;
-	encoding = NULL;
-	line_position = 0;
-}
-
-/* clientside */
-static void
-send_bacon_message (void)
+static GeditMessage *
+make_message (GSList *files, gint line_position, guint32 startup_timestamp)
 {
+	GSList *file;
+	gchar **uris;
+	gint i = 0;
+	GeditMessage *message;
 	GdkScreen *screen;
 	GdkDisplay *display;
-	const gchar *display_name;
-	gint screen_number;
-	gint ws;
 	gint viewport_x;
 	gint viewport_y;
-	GString *command;
-
-	/* the messages have the following format:
-	 * <---                                  header                                     ---> <----            body             ----->
-	 * timestamp \t display_name \t screen_number \t workspace \t viewport_x \t viewport_y \v OP1 \t arg \t arg \v OP2 \t arg \t arg|...
-	 *
-	 * when the arg is a list of uri, they are separated by a space.
-	 * So the delimiters are \v for the commands, \t for the tokens in
-	 * a command and ' ' for the uris: note that such delimiters cannot
-	 * be part of an uri, this way parsing is easier.
-	 */
-
-	gedit_debug (DEBUG_APP);
+	
+	/* insert uris as G_TYPE_STRV list */
+	uris = g_new0(gchar *, g_slist_length (files) + 1);
+	
+	for (file = files; file; file = file->next)
+		uris[i++] = g_strdup ((gchar *)file->data);
 
+	/* initialize message with correct keys and types */
+	message = gedit_message_new ("core", "open",
+			   	     "uris", G_TYPE_STRV,
+			   	     "new_window", G_TYPE_BOOLEAN,
+			   	     "new_document", G_TYPE_BOOLEAN,
+			   	     "startup_timestamp", G_TYPE_UINT,
+			   	     "line_position", G_TYPE_INT,
+			   	     "encoding", G_TYPE_STRING,
+			   	     "screen_number", G_TYPE_INT,
+			   	     "workspace", G_TYPE_INT,
+			   	     "viewport_x", G_TYPE_INT,
+			   	     "viewport_y", G_TYPE_INT,
+			   	     "display_name", G_TYPE_STRING,
+			   	     NULL);
+	
 	screen = gdk_screen_get_default ();
 	display = gdk_screen_get_display (screen);
-
-	display_name = gdk_display_get_name (display);
-	screen_number = gdk_screen_get_number (screen);
-
-	gedit_debug_message (DEBUG_APP, "Display: %s", display_name);
-	gedit_debug_message (DEBUG_APP, "Screen: %d", screen_number);	
-
-	ws = gedit_utils_get_current_workspace (screen);
 	gedit_utils_get_current_viewport (screen, &viewport_x, &viewport_y);
+	
+	/* now set values for the message */
+	gedit_message_set (message,
+			   "uris", uris,
+			   "new_window", new_window_option,
+			   "new_document", new_document_option,
+			   "startup_timestamp", startup_timestamp,
+			   "line_position", line_position,
+			   "encoding", encoding_charset,
+			   "screen_number", gdk_screen_get_number (screen),
+			   "workspace", gedit_utils_get_current_workspace (screen),
+			   "viewport_x", viewport_x,
+			   "viewport_y", viewport_y,
+			   "display_name", gdk_display_get_name (display),
+			   NULL);
 
-	command = g_string_new (NULL);
-
-	/* header */
-	g_string_append_printf (command,
-				"%" G_GUINT32_FORMAT "\t%s\t%d\t%d\t%d\t%d",
-				startup_timestamp,
-				display_name,
-				screen_number,
-				ws,
-				viewport_x,
-				viewport_y);
+	return message;
+}
 
-	/* NEW-WINDOW command */
-	if (new_window_option)
+static gboolean
+dispatch_dbus (guint32 startup_timestamp)
+{
+	GSList *files;
+	gint line_position;
+	DBusGProxy *bus_proxy;
+	DBusGConnection *gbus;
+	GError *error = NULL;
+	GeditMessage *message;
+	GType gtype;
+	gboolean ret = TRUE;
+	
+	/* get files and line position */
+	gedit_get_command_line_data (&files, &line_position);
+	
+	gbus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	
+	if (!gbus)
 	{
-		command = g_string_append_c (command, '\v');
-		command = g_string_append (command, "NEW-WINDOW");
+		g_warning ("Could not dispatch to dbus: %s", error->message);
+		g_error_free (error);
+		return FALSE;
 	}
 
-	/* NEW-DOCUMENT command */
-	if (new_document_option)
+	/* Get the remote gedit message bus */
+	bus_proxy = dbus_g_proxy_new_for_name (gbus, 
+					       "org.gnome.gedit",
+					       "/org/gnome/gedit",
+					       "org.gnome.gedit.MessageBus");
+	
+	if (!bus_proxy)
 	{
-		command = g_string_append_c (command, '\v');
-		command = g_string_append (command, "NEW-DOCUMENT");
+		g_warning ("Could not get gedit dbus proxy object");
+		return FALSE;
 	}
 
-	/* OPEN_URIS command, optionally specify line_num and encoding */
-	if (file_list)
-	{
-		GSList *l;
+	message = make_message (files, line_position, startup_timestamp);
+	gtype = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
 
-		command = g_string_append_c (command, '\v');
-		command = g_string_append (command, "OPEN-URIS");
+	if (!dbus_g_proxy_call (bus_proxy, "Send", &error,
+			  	G_TYPE_STRING, "core",
+			  	G_TYPE_STRING, g_slist_length (files) != 0 ? "open" : "present",
+				gtype, gedit_message_get_hash (message),
+			  	G_TYPE_INVALID,
+			  	G_TYPE_INVALID))
+	{
+		g_warning ("Sending message over dbus failed: %s", error->message);
+		g_error_free (error);
 
-		g_string_append_printf (command,
-					"\t%d\t%s\t%u\t",
-					line_position,
-					encoding_charset ? encoding_charset : "",
-					g_slist_length (file_list));
+		ret = FALSE;
+	}
 
-		for (l = file_list; l != NULL; l = l->next)
+	if (new_document_option && g_slist_length (files) != 0)
+	{
+		/* send also a new_document message */
+		if (!dbus_g_proxy_call (bus_proxy, "Send", &error,
+			  		G_TYPE_STRING, "core",
+			  		G_TYPE_STRING, "new_document",
+					gtype, gedit_message_get_hash (message),
+			  		G_TYPE_INVALID,
+			  		G_TYPE_INVALID))
 		{
-			command = g_string_append (command, l->data);
-			if (l->next != NULL)
-				command = g_string_append_c (command, ' ');
+			g_warning ("Sending message over dbus failed: %s", error->message);
+			g_error_free (error);
+
+			ret = FALSE;
 		}
 	}
 
-	gedit_debug_message (DEBUG_APP, "Bacon Message: %s", command->str);
+	/* cleanup */
+	g_object_unref (message);
+	g_slist_foreach (files, (GFunc)g_free, NULL);
+	g_slist_free (files);
 	
-	bacon_message_connection_send (connection,
-				       command->str);
-
-	g_string_free (command, TRUE);
+	return ret;
 }
 
 int
@@ -453,7 +303,8 @@
 	GeditApp *app;
 	gboolean restored = FALSE;
 	GError *error = NULL;
-
+	guint32 startup_timestamp;
+	
 	/* Init glib threads asap */
 	g_thread_init (NULL);
 
@@ -485,49 +336,37 @@
 		return 1;
 	}
 
-	gedit_debug_message (DEBUG_APP, "Create bacon connection");
-
-	connection = bacon_message_connection_new ("gedit");
-
-	if (connection != NULL)
+#ifdef ENABLE_DBUS
+	if (!standalone_option)
 	{
-		if (!bacon_message_connection_get_is_server (connection)) 
+		gboolean ret;
+		
+		gedit_debug_message (DEBUG_APP, "Start dbus service");
+		ret = gedit_dbus_initialize (&error);
+		
+		if (error)
 		{
-			gedit_debug_message (DEBUG_APP, "I'm a client");
-
-			gedit_get_command_line_data ();
-
-			send_bacon_message ();
-
-			/* we never popup a window... tell startup-notification
-			 * that we are done.
-			 */
-			gdk_notify_startup_complete ();
-
-			bacon_message_connection_free (connection);
-
-			exit (0);
+			g_warning ("Could not initialize dbus service: %s", error->message);
+			g_error_free (error);
 		}
-		else 
+		
+		if (!ret)
 		{
-		  	gedit_debug_message (DEBUG_APP, "I'm a server");
+			/* this means there is already a master gedit process */
+			gedit_debug_message (DEBUG_APP, "I'm a client");
+			
+			if (dispatch_dbus (startup_timestamp))
+			{
+				/* dispatch complete, we can safely exit now */
+				gdk_notify_startup_complete ();
 
-			bacon_message_connection_set_callback (connection,
-							       on_message_received,
-							       NULL);
+				exit(0);
+			}
 		}
 	}
-	else
-	{
-		g_warning ("Cannot create the 'gedit' connection.");
-	}
-
+#endif
 	/* register command messages on the message bus */
 	_gedit_commands_messages_register ();
-	
-#ifdef ENABLE_DBUS
-	gedit_dbus_initialize ();
-#endif
 
 	gedit_debug_message (DEBUG_APP, "Set icon");
 	
@@ -556,8 +395,11 @@
 
 	if (!restored)
 	{
+		GSList *files;
+		gint line_position;
+
 		gedit_debug_message (DEBUG_APP, "Analyze command line data");
-		gedit_get_command_line_data ();
+		gedit_get_command_line_data (&files, &line_position);
 		
 		gedit_debug_message (DEBUG_APP, "Get default app");
 		app = gedit_app_get_default ();
@@ -565,11 +407,22 @@
 		gedit_debug_message (DEBUG_APP, "Create main window");
 		window = gedit_app_create_window (app, NULL);
 
-		if (file_list != NULL)
+		if (files != NULL)
 		{
+			const GeditEncoding *encoding = NULL;
+
+			if (encoding_charset)
+			{
+				encoding = gedit_encoding_get_from_charset (encoding_charset);
+
+				if (encoding == NULL)
+					g_print (_("%s: invalid encoding.\n"),
+						 encoding_charset);
+			}
+	
 			gedit_debug_message (DEBUG_APP, "Load files");
 			_gedit_cmd_load_files_from_prompt (window, 
-							   file_list, 
+							   files, 
 							   encoding, 
 							   line_position);
 		}
@@ -582,23 +435,13 @@
 		gedit_debug_message (DEBUG_APP, "Show window");
 		gtk_widget_show (GTK_WIDGET (window));
 
-		g_slist_foreach (file_list, (GFunc) g_free, NULL);
-		g_slist_free (file_list);
-		file_list = NULL;
-
-		g_free (encoding_charset);
-
-		new_window_option = FALSE;
-		new_document_option = FALSE;
-		encoding = NULL;
-		line_position = 0;
+		g_slist_foreach (files, (GFunc) g_free, NULL);
+		g_slist_free (files);
 	}
 
 	gedit_debug_message (DEBUG_APP, "Start gtk-main");		
 	gtk_main();
 
-	bacon_message_connection_free (connection);
-
 	/* We kept the original engine reference here. So let's unref it to
 	 * finalize it properly. 
 	 */



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