[gnome-terminal] Split into server and remote
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-terminal] Split into server and remote
- Date: Thu, 3 May 2012 19:02:09 +0000 (UTC)
commit e1d641726cf0dec350b33e62d78eb6df9186443e
Author: Christian Persch <chpe gnome org>
Date: Wed Nov 16 19:14:38 2011 +0100
Split into server and remote
Make the''gnome-terminal' command simply invoke dbus.
configure.ac | 12 ++
src/Makefile.am | 106 ++++++++++---
src/server.c | 359 +++++++++++++++++++++++++++++++++++++++++++
src/terminal-options.c | 6 +
src/terminal-util.c | 1 +
src/terminal.c | 399 +++++++----------------------------------------
6 files changed, 522 insertions(+), 361 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 3d67d3f..7f141f5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -85,6 +85,17 @@ PKG_CHECK_MODULES([TERM],
gsettings-desktop-schemas >= $GSETTINGS_DESKTOP_SCHEMAS_REQUIRED
$PLATFORM_DEPS])
+# ****
+# DBus
+# ****
+
+AC_ARG_WITH([dbus-service-dir],
+ [AS_HELP_STRING([--with-dbus-service-dir=PATH],[dbus service file directory])],
+ [dbusservicedir="$withval"],
+ [dbusservicedir='${datadir}/dbus-1/services'])
+AC_SUBST([dbusservicedir])
+
+AC_ARG_WITH
# *********
# GSettings
# *********
@@ -205,6 +216,7 @@ echo "
gnome-terminal-$VERSION:
prefix: ${prefix}
+ DBus service dir: ${dbusservicedir}
source code location: ${srcdir}
compiler: ${CC}
diff --git a/src/Makefile.am b/src/Makefile.am
index 6d83a04..be22ec5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,11 @@
NULL =
bin_PROGRAMS = gnome-terminal
+libexec_PROGRAMS = gnome-terminal-server
+
+# Terminal server
+
+dbusservice_DATA = org.gnome.Terminal.Factory0.service
BUILT_SOURCES = \
terminal-marshal.c \
@@ -9,12 +14,12 @@ BUILT_SOURCES = \
terminal-type-builtins.h \
$(NULL)
-gnome_terminal_SOURCES= \
+gnome_terminal_server_SOURCES= \
eggshell.c \
eggshell.h \
profile-editor.c \
profile-editor.h \
- terminal.c \
+ server.c \
terminal-accels.c \
terminal-accels.h \
terminal-app.c \
@@ -48,10 +53,11 @@ gnome_terminal_SOURCES= \
terminal-window.h \
$(NULL)
-nodist_gnome_terminal_SOURCES= $(BUILT_SOURCES)
+nodist_gnome_terminal_server_SOURCES= $(BUILT_SOURCES)
-gnome_terminal_CPPFLAGS = \
+gnome_terminal_server_CPPFLAGS = \
-DTERMINAL_COMPILATION \
+ -DTERMINAL_SERVER \
-DEXECUTABLE_NAME=\"gnome-terminal\" \
-DTERM_DATADIR="\"$(datadir)\"" \
-DTERM_LOCALEDIR="\"$(datadir)/locale\"" \
@@ -59,47 +65,40 @@ gnome_terminal_CPPFLAGS = \
-DTERM_HELPDIR="\"$(HELP_DIR)\"" \
-DSN_API_NOT_YET_FROZEN \
-DGDK_MULTIHEAD_SAFE \
- -DG_DISABLE_SINGLE_INCLUDES \
- -DPANGO_DISABLE_SINGLE_INCLUDES \
- -DATK_DISABLE_SINGLE_INCLUDES \
- -DGDK_DISABLE_SINGLE_INCLUDES \
- -DGDK_PIXBUF_DISABLE_SINGLE_INCLUDES \
- -DGTK_DISABLE_SINGLE_INCLUDES \
- $(DISABLE_DEPRECATED) \
$(AM_CPPFLAGS)
-gnome_terminal_CFLAGS = \
+gnome_terminal_server_CFLAGS = \
$(TERM_CFLAGS) \
- $(WARN_CFLAGS) \
$(AM_CFLAGS)
-gnome_terminal_LDFLAGS =
+gnome_terminal_server_LDFLAGS = \
+ $(AM_LDFLAGS)
-gnome_terminal_LDADD = \
+gnome_terminal_server_LDADD = \
$(TERM_LIBS)
if WITH_SMCLIENT
-gnome_terminal_SOURCES += \
+gnome_terminal_server_SOURCES += \
eggsmclient.c \
eggsmclient.h \
eggsmclient-private.h \
$(NULL)
-gnome_terminal_CFLAGS += $(SMCLIENT_CFLAGS)
-gnome_terminal_LDADD += $(SMCLIENT_LIBS)
+gnome_terminal_server_CFLAGS += $(SMCLIENT_CFLAGS)
+gnome_terminal_server_LDADD += $(SMCLIENT_LIBS)
if WITH_SMCLIENT_XSMP
-gnome_terminal_SOURCES += \
+gnome_terminal_server_SOURCES += \
eggdesktopfile.c \
eggdesktopfile.h \
eggsmclient-xsmp.c \
$(NULL)
-gnome_terminal_CPPFLAGS += -DEGG_SM_CLIENT_BACKEND_XSMP
+gnome_terminal_server_CPPFLAGS += -DEGG_SM_CLIENT_BACKEND_XSMP
endif
if WITH_SMCLIENT_WIN32
-gnome_terminal_SOURCES += eggsmclient-win32.c
+gnome_terminal_server_SOURCES += eggsmclient-win32.c
endif
if WITH_SMCLIENT_QUARTZ
-gnome_terminal_SOURCES += eggsmclient-osx.c
+gnome_terminal_server_SOURCES += eggsmclient-osx.c
endif
endif
@@ -136,6 +135,69 @@ terminal-marshal.c: $(srcdir)/terminal-marshal.list
&& mv terminal-marshal.c.tmp terminal-marshal.c ) \
|| ( rm -f terminal-marshal.c.tmp && exit 1 )
+org.gnome.Terminal.Factory0.service: Makefile
+ $(AM_V_GEN) ( echo "[D-BUS Service]"; \
+ echo "Name=org.gnome.Terminal.Factory0"; \
+ echo "${libexecdir}/gnome-terminal-server") > $@
+
+# Terminal remote
+
+gnome_terminal_SOURCES= \
+ terminal.c \
+ terminal-debug.c \
+ terminal-debug.h \
+ terminal-intl.h \
+ terminal-options.c \
+ terminal-options.h \
+ $(NULL)
+
+gnome_terminal_CPPFLAGS = \
+ -DTERMINAL_COMPILATION \
+ -DTERMINAL_REMOTE \
+ -DTERM_DATADIR="\"$(datadir)\"" \
+ -DTERM_LOCALEDIR="\"$(datadir)/locale\"" \
+ -DTERM_PKGDATADIR="\"$(pkgdatadir)\"" \
+ -DSN_API_NOT_YET_FROZEN \
+ -DGDK_MULTIHEAD_SAFE \
+ $(AM_CPPFLAGS)
+
+gnome_terminal_CFLAGS = \
+ $(TERM_CFLAGS) \
+ $(AM_CFLAGS)
+
+gnome_terminal_LDFLAGS = \
+ $(AM_LDFLAGS)
+
+gnome_terminal_LDADD = \
+ $(TERM_LIBS)
+
+
+if WITH_SMCLIENT
+gnome_terminal_SOURCES += \
+ eggsmclient.c \
+ eggsmclient.h \
+ eggsmclient-private.h \
+ $(NULL)
+gnome_terminal_CFLAGS += $(SMCLIENT_CFLAGS)
+gnome_terminal_LDADD += $(SMCLIENT_LIBS)
+
+if WITH_SMCLIENT_XSMP
+gnome_terminal_SOURCES += \
+ eggdesktopfile.c \
+ eggdesktopfile.h \
+ eggsmclient-xsmp.c \
+ $(NULL)
+gnome_terminal_CPPFLAGS += -DEGG_SM_CLIENT_BACKEND_XSMP
+endif
+if WITH_SMCLIENT_WIN32
+gnome_terminal_SOURCES += eggsmclient-win32.c
+endif
+if WITH_SMCLIENT_QUARTZ
+gnome_terminal_SOURCES += eggsmclient-osx.c
+endif
+endif
+
+# Pref migrator
migrationdir = $(libexecdir)/GConf/gsettings
migration_PROGRAMS = gnome-terminal-migration
diff --git a/src/server.c b/src/server.c
new file mode 100644
index 0000000..ceb2a6f
--- /dev/null
+++ b/src/server.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright  2001, 2002 Havoc Pennington
+ * Copyright  2002 Red Hat, Inc.
+ * Copyright  2002 Sun Microsystems
+ * Copyright  2003 Mariano Suarez-Alvarez
+ * Copyright  2008, 2010, 2011 Christian Persch
+ *
+ * Gnome-terminal is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gnome-terminal 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 <config.h>
+
+#include <errno.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+
+#ifdef WITH_SMCLIENT
+#include "eggsmclient.h"
+#endif
+
+#include "terminal-accels.h"
+#include "terminal-app.h"
+#include "terminal-debug.h"
+#include "terminal-intl.h"
+#include "terminal-options.h"
+#include "terminal-util.h"
+
+#define TERMINAL_FACTORY_SERVICE_NAME_PREFIX "org.gnome.Terminal.Factory0.Display"
+#define TERMINAL_FACTORY_SERVICE_PATH "/org/gnome/Terminal/Factory"
+#define TERMINAL_FACTORY_INTERFACE_NAME "org.gnome.Terminal.Factory"
+
+static char *
+ay_to_string (GVariant *variant,
+ GError **error)
+{
+ gsize len;
+ const char *data;
+
+ data = g_variant_get_fixed_array (variant, &len, sizeof (char));
+ if (len == 0)
+ return NULL;
+
+ /* Make sure there are no embedded NULs */
+ if (memchr (data, '\0', len) != NULL) {
+ g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+ "String is shorter than claimed");
+ return NULL;
+ }
+
+ return g_strndup (data, len);
+}
+
+static char **
+ay_to_strv (GVariant *variant,
+ int *argc)
+{
+ GPtrArray *argv;
+ const char *data, *nullbyte;
+ gsize data_len;
+ gssize len;
+
+ data = g_variant_get_fixed_array (variant, &data_len, sizeof (char));
+ if (data_len == 0 || data_len > G_MAXSSIZE) {
+ if (argc)
+ *argc = 0;
+
+ return NULL;
+ }
+
+ argv = g_ptr_array_new ();
+
+ len = data_len;
+ do {
+ gssize string_len;
+
+ nullbyte = memchr (data, '\0', len);
+
+ string_len = nullbyte ? (gssize) (nullbyte - data) : len;
+ g_ptr_array_add (argv, g_strndup (data, string_len));
+
+ len -= string_len + 1;
+ data += string_len + 1;
+ } while (len > 0);
+
+ if (argc)
+ *argc = argv->len;
+
+ /* NULL terminate */
+ g_ptr_array_add (argv, NULL);
+ return (char **) g_ptr_array_free (argv, FALSE);
+}
+
+typedef struct {
+ char *factory_name;
+ int exit_code;
+} OwnData;
+
+static void
+method_call_cb (GDBusConnection *connection,
+ const char *sender,
+ const char *object_path,
+ const char *interface_name,
+ const char *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ if (g_strcmp0 (method_name, "HandleArguments") == 0) {
+ TerminalOptions *options = NULL;
+ GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv;
+ char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
+ char **envv = NULL, **argv = NULL;
+ int argc;
+ GError *error = NULL;
+
+ g_variant_get (parameters, "(@ay ay@ay ay@ay)",
+ &v_wd, &v_display, &v_sid, &v_envv, &v_argv);
+
+ working_directory = ay_to_string (v_wd, &error);
+ if (error)
+ goto out;
+ display_name = ay_to_string (v_display, &error);
+ if (error)
+ goto out;
+ startup_id = ay_to_string (v_sid, &error);
+ if (error)
+ goto out;
+ envv = ay_to_strv (v_envv, NULL);
+ argv = ay_to_strv (v_argv, &argc);
+
+ _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
+ "Factory invoked with working-dir='%s' display='%s' startup-id='%s'\n",
+ working_directory ? working_directory : "(null)",
+ display_name ? display_name : "(null)",
+ startup_id ? startup_id : "(null)");
+
+ options = terminal_options_parse (working_directory,
+ display_name,
+ startup_id,
+ envv,
+ TRUE,
+ TRUE,
+ &argc, &argv,
+ &error,
+ NULL);
+
+ if (options != NULL) {
+ terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
+ terminal_options_free (options);
+ }
+
+ out:
+ g_variant_unref (v_wd);
+ g_free (working_directory);
+ g_variant_unref (v_display);
+ g_free (display_name);
+ g_variant_unref (v_sid);
+ g_free (startup_id);
+ g_variant_unref (v_envv);
+ g_strfreev (envv);
+ g_variant_unref (v_argv);
+ g_strfreev (argv);
+
+ if (error == NULL) {
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
+ } else {
+ g_dbus_method_invocation_return_gerror (invocation, error);
+ g_error_free (error);
+ }
+ }
+}
+
+static void
+bus_acquired_cb (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ static const char dbus_introspection_xml[] =
+ "<node name='/org/gnome/Terminal'>"
+ "<interface name='org.gnome.Terminal.Factory'>"
+ "<method name='HandleArguments'>"
+ "<arg type='ay' name='working_directory' direction='in' />"
+ "<arg type='ay' name='display_name' direction='in' />"
+ "<arg type='ay' name='startup_id' direction='in' />"
+ "<arg type='ay' name='environment' direction='in' />"
+ "<arg type='ay' name='arguments' direction='in' />"
+ "</method>"
+ "</interface>"
+ "</node>";
+
+ static const GDBusInterfaceVTable interface_vtable = {
+ method_call_cb,
+ NULL,
+ NULL,
+ };
+
+ OwnData *data = (OwnData *) user_data;
+ GDBusNodeInfo *introspection_data;
+ guint registration_id;
+ GError *error = NULL;
+
+ _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
+ "Bus %s acquired\n", name);
+
+ introspection_data = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL);
+ g_assert (introspection_data != NULL);
+
+ registration_id = g_dbus_connection_register_object (connection,
+ TERMINAL_FACTORY_SERVICE_PATH,
+ introspection_data->interfaces[0],
+ &interface_vtable,
+ NULL, NULL,
+ &error);
+ g_dbus_node_info_unref (introspection_data);
+
+ if (registration_id == 0) {
+ _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
+ "Failed to register object: %s\n", error->message);
+ g_error_free (error);
+ data->exit_code = EXIT_FAILURE;
+ gtk_main_quit ();
+ }
+}
+
+static void
+name_acquired_cb (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
+ "Acquired the name %s on the starter bus\n", name);
+}
+
+static void
+name_lost_cb (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ OwnData *data = (OwnData *) user_data;
+
+ if (connection) {
+ _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
+ "Lost the name %s on the starter bus\n", name);
+ } else {
+ g_printerr ("Failed to connect to starter bus\n");
+ }
+
+ data->exit_code = EXIT_FAILURE;
+ gtk_main_quit ();
+}
+
+static char *
+get_factory_name_for_display (const char *display_name)
+{
+#if 0
+ GString *name;
+ const char *p;
+
+ name = g_string_sized_new (strlen (TERMINAL_FACTORY_SERVICE_NAME_PREFIX) + strlen (display_name) + 1 /* NUL */);
+ g_string_append (name, TERMINAL_FACTORY_SERVICE_NAME_PREFIX);
+
+ for (p = display_name; *p; ++p)
+ {
+ if (g_ascii_isalnum (*p))
+ g_string_append_c (name, *p);
+ else
+ g_string_append_c (name, '_');
+ }
+
+ _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
+ "Factory name is \"%s\"\n", name->str);
+
+ return g_string_free (name, FALSE);
+#endif
+ return g_strdup ("org.gnome.Terminal.Factory0");
+}
+
+int
+main (int argc, char **argv)
+{
+ OwnData data;
+ guint owner_id;
+ const char *home_dir;
+ GdkDisplay *display;
+ GError *error = NULL;
+
+ setlocale (LC_ALL, "");
+
+ bindtextdomain (GETTEXT_PACKAGE, TERM_LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ g_type_init ();
+
+ _terminal_debug_init ();
+
+ // FIXMEchpe: just use / here but make sure #565328 doesn't regress
+ /* Change directory to $HOME so we don't prevent unmounting, e.g. if the
+ * factory is started by nautilus-open-terminal. See bug #565328.
+ * On failure back to /.
+ */
+ home_dir = g_get_home_dir ();
+ if (home_dir == NULL || chdir (home_dir) < 0)
+ (void) chdir ("/");
+
+ g_set_application_name (_("Terminal"));
+
+ if (!gtk_init_with_args (&argc, &argv, "", NULL, NULL, &error)) {
+ g_printerr ("Failed to parse arguments: %s\n", error->message);
+ g_error_free (error);
+ exit (EXIT_FAILURE);
+ }
+
+ /* Unset the these env variables, so they doesn't end up
+ * in the factory's env and thus in the terminals' envs.
+ */
+// g_unsetenv ("DESKTOP_STARTUP_ID");
+// g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE_PID");
+// g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE");
+
+ display = gdk_display_get_default ();
+ data.factory_name = get_factory_name_for_display (gdk_display_get_name (display));
+ data.exit_code = EXIT_FAILURE;
+
+ owner_id = g_bus_own_name (G_BUS_TYPE_STARTER,
+ data.factory_name,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ bus_acquired_cb,
+ name_acquired_cb,
+ name_lost_cb,
+ &data, NULL);
+
+ gtk_main ();
+
+ g_bus_unown_name (owner_id);
+
+ g_free (data.factory_name);
+
+ terminal_app_shutdown ();
+
+ return data.exit_code;
+}
diff --git a/src/terminal-options.c b/src/terminal-options.c
index 55e5fdf..a4e179c 100644
--- a/src/terminal-options.c
+++ b/src/terminal-options.c
@@ -494,6 +494,7 @@ option_load_save_config_cb (const gchar *option_name,
gpointer data,
GError **error)
{
+#ifdef TERMINAL_SERVER
TerminalOptions *options = data;
if (options->config_file)
@@ -506,6 +507,7 @@ option_load_save_config_cb (const gchar *option_name,
options->config_file = terminal_util_resolve_relative_path (options->default_working_dir, value);
options->load_config = strcmp (option_name, "--load-config") == 0;
options->save_config = strcmp (option_name, "--save-config") == 0;
+#endif
return TRUE;
}
@@ -778,6 +780,8 @@ terminal_options_parse (const char *working_directory,
return NULL;
}
+#ifdef TERMINAL_SERVER
+
/**
* terminal_options_merge_config:
* @options:
@@ -897,6 +901,8 @@ terminal_options_merge_config (TerminalOptions *options,
return TRUE;
}
+#endif /* TERMINAL_SERVIER */
+
/**
* terminal_options_ensure_window:
* @options:
diff --git a/src/terminal-util.c b/src/terminal-util.c
index 135deb6..4e7d4a3 100644
--- a/src/terminal-util.c
+++ b/src/terminal-util.c
@@ -42,6 +42,7 @@
#include "terminal-accels.h"
#include "terminal-app.h"
#include "terminal-intl.h"
+#include "terminal-screen.h"
#include "terminal-util.h"
#include "terminal-window.h"
diff --git a/src/terminal.c b/src/terminal.c
index ff25cb9..1e107c7 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -31,84 +31,21 @@
#include <glib/gstdio.h>
#include <gio/gio.h>
+#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#ifdef WITH_SMCLIENT
#include "eggsmclient.h"
#endif
-#include "terminal-accels.h"
-#include "terminal-app.h"
#include "terminal-debug.h"
#include "terminal-intl.h"
#include "terminal-options.h"
-#include "terminal-util.h"
-#define TERMINAL_FACTORY_SERVICE_NAME_PREFIX "org.gnome.Terminal.Display"
+#define TERMINAL_FACTORY_SERVICE_NAME_PREFIX "org.gnome.Terminal.Factory0.Display"
#define TERMINAL_FACTORY_SERVICE_PATH "/org/gnome/Terminal/Factory"
#define TERMINAL_FACTORY_INTERFACE_NAME "org.gnome.Terminal.Factory"
-static char *
-ay_to_string (GVariant *variant,
- GError **error)
-{
- gsize len;
- const char *data;
-
- data = g_variant_get_fixed_array (variant, &len, sizeof (char));
- if (len == 0)
- return NULL;
-
- /* Make sure there are no embedded NULs */
- if (memchr (data, '\0', len) != NULL) {
- g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
- "String is shorter than claimed");
- return NULL;
- }
-
- return g_strndup (data, len);
-}
-
-static char **
-ay_to_strv (GVariant *variant,
- int *argc)
-{
- GPtrArray *argv;
- const char *data, *nullbyte;
- gsize data_len;
- gssize len;
-
- data = g_variant_get_fixed_array (variant, &data_len, sizeof (char));
- if (data_len == 0 || data_len > G_MAXSSIZE) {
- if (argc)
- *argc = 0;
-
- return NULL;
- }
-
- argv = g_ptr_array_new ();
-
- len = data_len;
- do {
- gssize string_len;
-
- nullbyte = memchr (data, '\0', len);
-
- string_len = nullbyte ? (gssize) (nullbyte - data) : len;
- g_ptr_array_add (argv, g_strndup (data, string_len));
-
- len -= string_len + 1;
- data += string_len + 1;
- } while (len > 0);
-
- if (argc)
- *argc = argv->len;
-
- /* NULL terminate */
- g_ptr_array_add (argv, NULL);
- return (char **) g_ptr_array_free (argv, FALSE);
-}
-
static GVariant *
string_to_ay (const char *string)
{
@@ -121,208 +58,28 @@ string_to_ay (const char *string)
return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, len, TRUE, g_free, data);
}
-typedef struct {
- char *factory_name;
- TerminalOptions *options;
- int exit_code;
- char **argv;
- int argc;
-} OwnData;
-
-static void
-method_call_cb (GDBusConnection *connection,
- const char *sender,
- const char *object_path,
- const char *interface_name,
- const char *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation,
- gpointer user_data)
-{
- if (g_strcmp0 (method_name, "HandleArguments") == 0) {
- TerminalOptions *options = NULL;
- GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv;
- char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
- char **envv = NULL, **argv = NULL;
- int argc;
- GError *error = NULL;
-
- g_variant_get (parameters, "(@ay ay@ay ay@ay)",
- &v_wd, &v_display, &v_sid, &v_envv, &v_argv);
-
- working_directory = ay_to_string (v_wd, &error);
- if (error)
- goto out;
- display_name = ay_to_string (v_display, &error);
- if (error)
- goto out;
- startup_id = ay_to_string (v_sid, &error);
- if (error)
- goto out;
- envv = ay_to_strv (v_envv, NULL);
- argv = ay_to_strv (v_argv, &argc);
-
- _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
- "Factory invoked with working-dir='%s' display='%s' startup-id='%s'\n",
- working_directory ? working_directory : "(null)",
- display_name ? display_name : "(null)",
- startup_id ? startup_id : "(null)");
-
- options = terminal_options_parse (working_directory,
- display_name,
- startup_id,
- envv,
- TRUE,
- TRUE,
- &argc, &argv,
- &error,
- NULL);
-
- if (options != NULL) {
- terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
- terminal_options_free (options);
- }
-
- out:
- g_variant_unref (v_wd);
- g_free (working_directory);
- g_variant_unref (v_display);
- g_free (display_name);
- g_variant_unref (v_sid);
- g_free (startup_id);
- g_variant_unref (v_envv);
- g_strfreev (envv);
- g_variant_unref (v_argv);
- g_strfreev (argv);
-
- if (error == NULL) {
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
- } else {
- g_dbus_method_invocation_return_gerror (invocation, error);
- g_error_free (error);
- }
- }
-}
-
-static void
-bus_acquired_cb (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
-{
- static const char dbus_introspection_xml[] =
- "<node name='/org/gnome/Terminal'>"
- "<interface name='org.gnome.Terminal.Factory'>"
- "<method name='HandleArguments'>"
- "<arg type='ay' name='working_directory' direction='in' />"
- "<arg type='ay' name='display_name' direction='in' />"
- "<arg type='ay' name='startup_id' direction='in' />"
- "<arg type='ay' name='environment' direction='in' />"
- "<arg type='ay' name='arguments' direction='in' />"
- "</method>"
- "</interface>"
- "</node>";
-
- static const GDBusInterfaceVTable interface_vtable = {
- method_call_cb,
- NULL,
- NULL,
- };
-
- OwnData *data = (OwnData *) user_data;
- GDBusNodeInfo *introspection_data;
- guint registration_id;
- GError *error = NULL;
-
- _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
- "Bus %s acquired\n", name);
-
- introspection_data = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL);
- g_assert (introspection_data != NULL);
-
- registration_id = g_dbus_connection_register_object (connection,
- TERMINAL_FACTORY_SERVICE_PATH,
- introspection_data->interfaces[0],
- &interface_vtable,
- NULL, NULL,
- &error);
- g_dbus_node_info_unref (introspection_data);
-
- if (registration_id == 0) {
- g_printerr ("Failed to register object: %s\n", error->message);
- g_error_free (error);
- data->exit_code = EXIT_FAILURE;
- gtk_main_quit ();
- }
-}
-
-static void
-name_acquired_cb (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
-{
- OwnData *data = (OwnData *) user_data;
- GError *error = NULL;
-
- _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
- "Acquired the name %s on the session bus\n", name);
-
- if (data->options == NULL) {
- /* Name re-acquired!? */
- g_assert_not_reached ();
- }
-
-
- if (!terminal_app_handle_options (terminal_app_get (), data->options, TRUE /* do resume */, &error)) {
- g_printerr ("Failed to handle options: %s\n", error->message);
- g_error_free (error);
- data->exit_code = EXIT_FAILURE;
- gtk_main_quit ();
- }
-
- terminal_options_free (data->options);
- data->options = NULL;
-}
-
-static void
-name_lost_cb (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
+/**
+ * options_to_variant:
+ *
+ * Returns: a new floating #GVariant
+ */
+static GVariant *
+options_to_variant (TerminalOptions *options,
+ char **argv,
+ int argc)
{
- OwnData *data = (OwnData *) user_data;
- GError *error = NULL;
char **envv;
- int envc, i;
+ int i;
GVariantBuilder builder;
- GVariant *value;
GString *string;
char *s;
gsize len;
- _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
- "Lost the name %s on the session bus\n", name);
-
- /* Couldn't get the connection? No way to continue! */
- if (connection == NULL) {
- data->exit_code = EXIT_FAILURE;
- gtk_main_quit ();
- return;
- }
-
- if (data->options == NULL) {
- /* Already handled */
- data->exit_code = EXIT_SUCCESS;
- gtk_main_quit ();
- return;
- }
-
- _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
- "Forwarding arguments to existing instance\n");
-
g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ayayayayay)"));
- g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->default_working_dir));
- g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->display_name));
- g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->startup_id));
+ g_variant_builder_add (&builder, "@ay", string_to_ay (options->default_working_dir));
+ g_variant_builder_add (&builder, "@ay", string_to_ay (options->display_name));
+ g_variant_builder_add (&builder, "@ay", string_to_ay (options->startup_id));
string = g_string_new (NULL);
envv = g_get_environ ();
@@ -342,11 +99,11 @@ name_lost_cb (GDBusConnection *connection,
string = g_string_new (NULL);
- for (i = 0; i < data->argc; ++i)
+ for (i = 0; i < argc; ++i)
{
if (i > 0)
g_string_append_c (string, '\0');
- g_string_append (string, data->argv[i]);
+ g_string_append (string, argv[i]);
}
len = string->len;
@@ -354,31 +111,7 @@ name_lost_cb (GDBusConnection *connection,
g_variant_builder_add (&builder, "@ay",
g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
- value = g_dbus_connection_call_sync (connection,
- data->factory_name,
- TERMINAL_FACTORY_SERVICE_PATH,
- TERMINAL_FACTORY_INTERFACE_NAME,
- "HandleArguments",
- g_variant_builder_end (&builder),
- G_VARIANT_TYPE ("()"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- if (value == NULL) {
- g_printerr ("Failed to forward arguments: %s\n", error->message);
- g_error_free (error);
- data->exit_code = EXIT_FAILURE;
- gtk_main_quit ();
- } else {
- g_variant_unref (value);
- data->exit_code = EXIT_SUCCESS;
- }
-
- terminal_options_free (data->options);
- data->options = NULL;
-
- gtk_main_quit ();
+ return g_variant_builder_end (&builder);
}
/* Copied from libnautilus/nautilus-program-choosing.c; Needed in case
@@ -432,9 +165,11 @@ slowly_and_stupidly_obtain_timestamp (Display *xdisplay)
return event.xproperty.time;
}
+
static char *
get_factory_name_for_display (const char *display_name)
{
+#if 0
GString *name;
const char *p;
@@ -453,6 +188,8 @@ get_factory_name_for_display (const char *display_name)
"Factory name is \"%s\"\n", name->str);
return g_string_free (name, FALSE);
+#endif
+ return g_strdup ("org.gnome.Terminal.Factory0");
}
int
@@ -461,12 +198,15 @@ main (int argc, char **argv)
int i;
char **argv_copy;
int argc_copy;
- const char *startup_id, *display_name, *home_dir;
+ const char *startup_id, *display_name;
+ char *factory_name = NULL;
GdkDisplay *display;
TerminalOptions *options;
+ GDBusConnection *connection;
GError *error = NULL;
char *working_directory;
- int ret = EXIT_SUCCESS;
+ GVariant *server_retval;
+ int exit_code = EXIT_FAILURE;
setlocale (LC_ALL, "");
@@ -474,8 +214,7 @@ main (int argc, char **argv)
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
- /* GConf uses ORBit2 which need GThread. See bug #565516 */
- g_thread_init (NULL);
+ g_type_init ();
_terminal_debug_init ();
@@ -487,17 +226,8 @@ main (int argc, char **argv)
argc_copy = argc;
startup_id = g_getenv ("DESKTOP_STARTUP_ID");
-
working_directory = g_get_current_dir ();
- /* Now change directory to $HOME so we don't prevent unmounting, e.g. if the
- * factory is started by nautilus-open-terminal. See bug #565328.
- * On failure back to /.
- */
- home_dir = g_get_home_dir ();
- if (home_dir == NULL || chdir (home_dir) < 0)
- (void) chdir ("/");
-
options = terminal_options_parse (working_directory,
NULL,
startup_id,
@@ -517,11 +247,12 @@ main (int argc, char **argv)
if (options == NULL) {
g_printerr (_("Failed to parse arguments: %s\n"), error->message);
g_error_free (error);
+ g_free (argv_copy);
exit (EXIT_FAILURE);
}
g_set_application_name (_("Terminal"));
-
+
/* Unset the these env variables, so they doesn't end up
* in the factory's env and thus in the terminals' envs.
*/
@@ -543,51 +274,41 @@ main (int argc, char **argv)
display = gdk_display_get_default ();
display_name = gdk_display_get_name (display);
options->display_name = g_strdup (display_name);
-
- if (options->use_factory) {
- OwnData *data;
- guint owner_id;
-
- data = g_new (OwnData, 1);
- data->factory_name = get_factory_name_for_display (display_name);
- data->options = options;
- data->exit_code = -1;
- data->argv = argv_copy;
- data->argc = argc_copy;
-
- owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
- data->factory_name,
- G_BUS_NAME_OWNER_FLAGS_NONE,
- bus_acquired_cb,
- name_acquired_cb,
- name_lost_cb,
- data, NULL);
-
- gtk_main ();
-
- ret = data->exit_code;
- g_bus_unown_name (owner_id);
-
- g_free (data->factory_name);
- g_free (data);
-
- } else {
- terminal_app_handle_options (terminal_app_get (), options, TRUE /* allow resume */, &error);
- terminal_options_free (options);
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+ if (connection == NULL) {
+ g_printerr ("Error connecting to bus: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
- if (error == NULL) {
- gtk_main ();
- } else {
- g_printerr ("Error handling options: %s\n", error->message);
- g_error_free (error);
- ret = EXIT_FAILURE;
- }
+ factory_name = get_factory_name_for_display (options->display_name);
+ server_retval = g_dbus_connection_call_sync (connection,
+ factory_name,
+ TERMINAL_FACTORY_SERVICE_PATH,
+ TERMINAL_FACTORY_INTERFACE_NAME,
+ "HandleArguments",
+ options_to_variant (options, argv_copy, argc_copy),
+ G_VARIANT_TYPE ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ if (server_retval == NULL) {
+ g_printerr ("Error opening terminal: %s\n", error->message);
+ g_error_free (error);
+ } else {
+ g_variant_unref (server_retval);
+ exit_code = EXIT_SUCCESS;
}
- terminal_app_shutdown ();
+ g_free (factory_name);
+ g_object_unref (connection);
+
+out:
+ terminal_options_free (options);
g_free (argv_copy);
- return ret;
+ return exit_code;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]