[gnome-terminal] Revert using org.gtk.Application interface



commit 742bc0296351e6a2792dd2f5f402ff6b2d7aca45
Author: Christian Persch <chpe gnome org>
Date:   Wed Aug 11 00:10:21 2010 +0200

    Revert using org.gtk.Application interface
    
    Regain interoperability with gnome-terminal 2.30.

 configure.ac   |    2 +-
 src/terminal.c |  261 ++++++++++++++++++++++++++------------------------------
 2 files changed, 121 insertions(+), 142 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 8df8a19..35a3773 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,7 +40,7 @@ GNOME_COMPILE_WARNINGS([maximum])
 AM_GLIB_GNU_GETTEXT
 
 GLIB_REQUIRED=2.25.0
-GIO_REQUIRED=2.25.11
+GIO_REQUIRED=2.25.12
 GTK_REQUIRED=2.14.0
 GCONF_REQUIRED=2.31.3
 VTE_REQUIRED=0.25.1
diff --git a/src/terminal.c b/src/terminal.c
index 5fbc59a..4bd8476 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -46,67 +46,77 @@
 
 #define TERMINAL_FACTORY_SERVICE_NAME_PREFIX  "org.gnome.Terminal.Display"
 #define TERMINAL_FACTORY_SERVICE_PATH         "/org/gnome/Terminal/Factory"
+#define TERMINAL_FACTORY_INTERFACE_NAME       "org.gnome.Terminal.Factory"
 
-#define GAPPLICATION_INTERFACE_NAME           "org.gtk.Application"
-
-/* The returned string is owned by @variant */
-static const char *
+static char *
 ay_to_string (GVariant *variant,
               GError **error)
 {
-  const char *string;
   gsize len;
+  const char *data;
 
-  len = g_variant_get_size (variant);
-  if (len == 0) {
-    g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
-                         "NUL strings not allowed");
+  data = g_variant_get_fixed_array (variant, &len, sizeof (char));
+  if (len == 0)
     return NULL;
-  }
 
-  string = g_variant_get_bytestring (variant);
-  if (strlen (string) != (len - 1)) {
-    g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
-                         "String is shorter than claimed (claimed %" G_GSIZE_FORMAT " actual %" G_GSIZE_FORMAT ")",
-                         len - 1, strlen (string));
+  /* 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 string;
+  return g_strndup (data, len);
 }
 
-/* The returned strings are owned by @variant. Free the array itself with g_free(). */
 static char **
-aay_to_strv (GVariant *variant,
-             int *argc,
-             GError **error)
+ay_to_strv (GVariant *variant,
+            int *argc)
 {
-  GVariant *item;
-  char **argv;
-  gsize i, n;
+  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) {
+    *argc = 0;
+    return NULL;
+  }
+
+  argv = g_ptr_array_new ();
+
+  len = data_len;
+  do {
+    gsize string_len;
+
+    nullbyte = memchr (data, '\0', len);
+
+    string_len = nullbyte ? (gsize) (nullbyte - data) : len;
+    g_ptr_array_add (argv, g_strndup (data, string_len));
+
+    len -= string_len + 1;
+    data += string_len + 1;
+  } while (len > 0);
 
-  n = g_variant_n_children (variant);
   if (argc)
-    *argc = n;
-  if (n == 0)
-    return NULL;
+    *argc = argv->len;
 
-  argv = g_new (char *, n + 1);
+  /* NULL terminate */
+  g_ptr_array_add (argv, NULL);
+  return (char **) g_ptr_array_free (argv, FALSE);
+}
 
-  for (i = 0; i < n; ++i) {
-    item = g_variant_get_child_value (variant, i);
-    argv[i] = (char *) ay_to_string (item, error);
-    g_variant_unref (item);
-    if (*error != NULL)
-      goto err;
-  }
+static GVariant *
+string_to_ay (const char *string)
+{
+  gsize len;
+  char *data;
 
-  argv[n] = NULL;
-  return argv;
+  len = strlen (string);
+  data = g_strndup (string, len);
 
-err:
-  g_free (argv);
-  return NULL;
+  return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, len, TRUE, g_free, data);
 }
 
 typedef struct {
@@ -127,49 +137,28 @@ method_call_cb (GDBusConnection *connection,
                 GDBusMethodInvocation *invocation,
                 gpointer user_data)
 {
-  _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
-                         "Remote method call sender '%s' object-path '%s' interface-name '%s' method-name '%s' parameters-type '%s'\n",
-                         sender, object_path, interface_name, method_name,
-                         g_variant_get_type_string (parameters));
-
-  if (g_strcmp0 (object_path, TERMINAL_FACTORY_SERVICE_PATH) != 0 ||
-      g_strcmp0 (interface_name, GAPPLICATION_INTERFACE_NAME) != 0)
-    return;
-
-  if (g_strcmp0 (method_name, "Activate") == 0) {
+  if (g_strcmp0 (method_name, "HandleArguments") == 0) {
     TerminalOptions *options = NULL;
-    GVariantIter *data_iter;
-    const char *key;
-    GVariant *data, *v_argv;
-    const char *working_directory = NULL, *display_name = NULL, *startup_id = 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, "(@aaya{sv})", &v_argv, &data_iter);
-
-    while (g_variant_iter_next (data_iter, "{&sv}", &key, &data)) {
-      if (strcmp (key, "startup-notication-id") == 0) {
-        working_directory = ay_to_string (data, &error);
-      } else if (strcmp (key, "display-name") == 0) {
-        display_name = ay_to_string (data, &error);
-      } else if (strcmp (key, "cwd") == 0) {
-        working_directory = ay_to_string (data, &error);
-      } else if (strcmp (key, "environment") == 0) {
-        envv = aay_to_strv (data, NULL, &error);
-      }
-
-      g_variant_unref (data);
-      if (error)
-        break;
-    }
-    g_variant_iter_free (data_iter);
+    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;
-
-    argv = aay_to_strv (v_argv, &argc, &error);
+    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",
@@ -191,11 +180,18 @@ method_call_cb (GDBusConnection *connection,
       terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
       terminal_options_free (options);
     }
-
+ 
   out:
-    g_free (envv);
-    g_free (argv);
+    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 ("()"));
@@ -203,23 +199,6 @@ method_call_cb (GDBusConnection *connection,
       g_dbus_method_invocation_return_gerror (invocation, error);
       g_error_free (error);
     }
-  } else if (g_strcmp0 (method_name, "ListActions") == 0) {
-    g_dbus_method_invocation_return_value (invocation,
-                                            g_variant_new ("(a{s(sb)})", NULL));
-    return;
-  } else if (g_strcmp0 (method_name, "InvokeAction") == 0) {
-    g_dbus_method_invocation_return_error (invocation,
-                                            G_DBUS_ERROR,
-                                            G_DBUS_ERROR_NOT_SUPPORTED,
-                                            "Not supported");
-    return;
-  } else if (g_strcmp0 (method_name, "Quit") == 0) {
-    /* Very funny. If you want to quit, use the session manager! */
-    g_dbus_method_invocation_return_error (invocation,
-                                            G_DBUS_ERROR,
-                                            G_DBUS_ERROR_NOT_SUPPORTED,
-                                            "Not supported");
-    return;
   }
 }
 
@@ -230,22 +209,14 @@ bus_acquired_cb (GDBusConnection *connection,
 {
   static const char dbus_introspection_xml[] =
     "<node name='/org/gnome/Terminal'>"
-      "<interface name='org.gtk.Application'>"
-        "<method name='Quit'>"
-          "<arg type='u' name='timestamp' direction='in'/>"
+      "<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>"
-        "<method name='ListActions'>"
-          "<arg type='a{s(sb)}' name='actions' direction='out'/>"
-        "</method>"
-        "<method name='InvokeAction'>"
-          "<arg type='s' name='action' direction='in'/>"
-          "<arg type='u' name='timestamp' direction='in'/>"
-        "</method>"
-        "<method name='Activate'>"
-          "<arg type='aay' name='arguments' direction='in'/>"
-          "<arg type='a{sv}' name='data' direction='in'/>"
-        "</method>"
-        "<signal name='ActionsChanged'/>"
       "</interface>"
     "</node>";
 
@@ -321,10 +292,20 @@ name_lost_cb (GDBusConnection *connection,
   int envc, 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;
@@ -335,55 +316,53 @@ name_lost_cb (GDBusConnection *connection,
   _terminal_debug_print (TERMINAL_DEBUG_FACTORY,
                           "Forwarding arguments to existing instance\n");
 
-  g_variant_builder_init (&builder, G_VARIANT_TYPE ("(aaya{sv})"));
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ayayayayay)"));
 
-  g_variant_builder_open (&builder, G_VARIANT_TYPE ("aay"));
-  for (i = 0; i < data->argc; ++i)
-    g_variant_builder_add (&builder, "^ay", data->argv[i]);
-  g_variant_builder_close (&builder); /* aay */
-
-  g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
-
-  g_variant_builder_add (&builder, "{sv}",
-                         "startup-notication-id",
-                         g_variant_new_bytestring (data->options->startup_id ? data->options->startup_id : ""));
-  g_variant_builder_add (&builder, "{sv}",
-                         "display-name",
-                         g_variant_new_bytestring (data->options->display_name ? data->options->display_name : ""));
-  g_variant_builder_add (&builder, "{sv}",
-                         "cwd",
-                         g_variant_new_bytestring (data->options->default_working_dir ? data->options->default_working_dir : ""));
-
-  g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sv}"));
-  g_variant_builder_add (&builder, "s", "environment");
-  g_variant_builder_open (&builder, G_VARIANT_TYPE ("v"));
-  g_variant_builder_open (&builder, G_VARIANT_TYPE ("aay"));
+  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));
+
+  string = g_string_new (NULL);
   envv = g_listenv ();
   envc = g_strv_length (envv);
   for (i = 0; i < envc; ++i)
     {
       const char *value;
-      char *str;
 
       value = g_getenv (envv[i]);
       if (value == NULL)
         continue;
 
-      str = g_strdup_printf ("%s=%s", envv[i], value);
-      g_variant_builder_add (&builder, "^ay", str);
-      g_free (str);
+      if (i > 0)
+        g_string_append_c (string, '\0');
+
+      g_string_append_printf (string, "%s=%s", envv[i], value);
+    }
+
+  len = string->len;
+  s = g_string_free (string, FALSE);
+  g_variant_builder_add (&builder, "@ay",
+                         g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s));
+
+  string = g_string_new (NULL);
+
+  for (i = 0; i < data->argc; ++i)
+    {
+      if (i > 0)
+        g_string_append_c (string, '\0');
+      g_string_append (string, data->argv[i]);
     }
-  g_variant_builder_close (&builder); /* aay */
-  g_variant_builder_close (&builder); /* v */
-  g_variant_builder_close (&builder); /* {sv} */
 
-  g_variant_builder_close (&builder); /* a{sv} */
+  len = string->len;
+  s = g_string_free (string, FALSE);
+  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,
-                                       GAPPLICATION_INTERFACE_NAME,
-                                       "Activate",
+                                       TERMINAL_FACTORY_INTERFACE_NAME,
+                                       "HandleArguments",
                                        g_variant_builder_end (&builder),
                                        G_VARIANT_TYPE ("()"),
                                        G_DBUS_CALL_FLAGS_NONE,



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